1 package org.kuali.coeus.dc.access.kim; 2 3 4 import org.kuali.coeus.dc.common.db.ConnectionDaoService; 5 import org.kuali.coeus.dc.common.db.SequenceDaoService; 6 7 import java.sql.*; 8 import java.util.*; 9 import java.util.logging.Logger; 10 11 import static org.kuali.coeus.dc.common.db.PreparedStatementUtils.*; 12 13 public class RoleDaoImpl implements RoleDao { 14 15 private static final Logger LOG = Logger.getLogger(RoleDaoImpl.class.getName()); 16 17 private ConnectionDaoService connectionDaoService; 18 private KimTypeDao kimTypeDao; 19 private SequenceDaoService sequenceDaoService; 20 21 @Override 22 public void copyRoleMembersToDocAccessType(Collection<String> roleIds, KimAttributeDocumentValueHandler handler) { 23 24 final String kimTypeId = kimTypeDao.getDocAccessKimTypeId(); 25 26 if (kimTypeId == null || kimTypeId.trim().equals("")) { 27 throw new IllegalStateException("Doc Access Kim Type is not found"); 28 } 29 30 for (String roleId : roleIds) { 31 Role existingRole = getRole(roleId); 32 33 if (!existingRole.getKimTypeId().equals(kimTypeId) && copyExists(createNewRoleName(existingRole.getName()), existingRole.getNamespaceCode())) { 34 copyRoleMembers(existingRole, handler); 35 } 36 } 37 38 handler.cleanup(); 39 } 40 41 protected boolean copyExists(String name, String namespace) { 42 Connection connection = connectionDaoService.getRiceConnection(); 43 44 try (PreparedStatement stmt = setString(2, namespace, setString(1, name, connection.prepareStatement("SELECT count(*) from KRIM_ROLE_T WHERE ROLE_NM = ? AND NMSPC_CD = ?"))); 45 ResultSet result = stmt.executeQuery()) { 46 result.next(); 47 final boolean exists = result.getInt(1) > 0; 48 if (exists) { 49 return true; 50 } else { 51 LOG.warning("Copy Role does not exist for name: " + name + " and namespace: " + namespace); 52 return false; 53 } 54 55 } catch (SQLException e) { 56 throw new RuntimeException(e); 57 } 58 } 59 60 private String createNewRoleName(String name) { 61 return name + " Document Level"; 62 } 63 64 protected void copyRoleMembers(Role existingRole, KimAttributeDocumentValueHandler handler) { 65 66 Collection<DocumentAccess> accessesToSave = new ArrayList<>(); 67 Collection<String> attrsToDelete = new ArrayList<>(); 68 69 for (RoleMember member : getRoleMembers(existingRole.getId())) { 70 if ("P".equals(member.getTypeCode())) { 71 Collection<RoleMemberAttributeData> attrs = getRoleMemberAttributeData(member.getId()); 72 for (RoleMemberAttributeData attr : attrs) { 73 if (handler.isDocumentValueType(attr.getKimAttributeId())) { 74 String documentNumber = handler.transform(attr.getAttributeValue()); 75 if (documentNumber != null) { 76 DocumentAccess access = new DocumentAccess(); 77 access.setId(sequenceDaoService.getNextCoeusSequence("SEQ_DOCUMENT_ACCESS_ID", "")); 78 access.setDocumentNumber(documentNumber); 79 access.setPrincipalId(member.getMemberId()); 80 access.setRoleName(createNewRoleName(existingRole.getName())); 81 access.setNamespaceCode(existingRole.getNamespaceCode()); 82 access.setUpdateUser("kc-doc-access-conv"); 83 access.setUpdateTimestamp(new Timestamp(new java.util.Date().getTime())); 84 access.setVersionNumber(1L); 85 access.setObjectId(UUID.randomUUID().toString()); 86 87 accessesToSave.add(access); 88 } 89 90 attrsToDelete.add(attr.getId()); 91 } 92 } 93 } 94 } 95 96 final Set<DocumentAccess> filtered = new TreeSet<>(new Comparator<DocumentAccess>(){ 97 @Override 98 public int compare(DocumentAccess o1, DocumentAccess o2) { 99 if (o1.getPrincipalId().equals(o2.getPrincipalId()) 100 && o1.getDocumentNumber().equals(o2.getDocumentNumber()) 101 && o1.getRoleName().equals(o2.getRoleName()) 102 && o1.getNamespaceCode().equals(o2.getNamespaceCode())) { 103 return 0; 104 } else { 105 return o1.getDocumentNumber().compareTo(o2.getDocumentNumber()); 106 } 107 } 108 }); 109 filtered.addAll(accessesToSave); 110 111 if (filtered.size() != accessesToSave.size()) { 112 LOG.warning("Duplicate role member document qualifiers detected"); 113 } 114 115 saveDocumentAccess(filtered); 116 deleteAttributeData(attrsToDelete); 117 } 118 119 private void deleteAttributeData(Collection<String> attrsToDelete) { 120 for (String attr: attrsToDelete) { 121 Connection connection = connectionDaoService.getRiceConnection(); 122 try (PreparedStatement stmt = setString(1, attr, connection.prepareStatement("DELETE FROM KRIM_ROLE_MBR_ATTR_DATA_T WHERE ATTR_DATA_ID = ?"))) { 123 stmt.executeUpdate(); 124 } catch (SQLException e) { 125 throw new RuntimeException(e); 126 } 127 } 128 } 129 130 private void saveDocumentAccess(Collection<DocumentAccess> accesses) { 131 for (DocumentAccess access : accesses) { 132 Connection connection = connectionDaoService.getCoeusConnection(); 133 try (PreparedStatement stmt = setString(9, access.getObjectId(), 134 setLong(8, access.getVersionNumber(), 135 setString(7, access.getUpdateUser(), 136 setTimestamp(6, access.getUpdateTimestamp(), 137 setString(5, access.getNamespaceCode(), 138 setString(4, access.getRoleName(), 139 setString(3, access.getPrincipalId(), 140 setString(2, access.getDocumentNumber(), 141 setString(1, access.getId(), connection.prepareStatement("INSERT INTO DOCUMENT_ACCESS (DOC_ACCESS_ID, DOC_HDR_ID, PRNCPL_ID, ROLE_NM, NMSPC_CD, UPDATE_TIMESTAMP, UPDATE_USER, VER_NBR, OBJ_ID) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"))))))))))) { 142 stmt.executeUpdate(); 143 } catch (SQLException e) { 144 throw new RuntimeException(e); 145 } 146 } 147 } 148 149 protected Collection<RoleMember> getRoleMembers(String roleId) { 150 Connection connection = connectionDaoService.getRiceConnection(); 151 try (PreparedStatement stmt = setString(1, roleId, 152 connection.prepareStatement("SELECT ROLE_MBR_ID, VER_NBR, OBJ_ID, ROLE_ID, MBR_ID, MBR_TYP_CD, ACTV_FRM_DT, ACTV_TO_DT, LAST_UPDT_DT FROM KRIM_ROLE_MBR_T WHERE ROLE_ID = ?")); 153 ResultSet result = stmt.executeQuery()) { 154 155 final Collection<RoleMember> members = new ArrayList<RoleMember>(); 156 while(result.next()) { 157 RoleMember member = new RoleMember(); 158 member.setId(result.getString(1)); 159 member.setVersionNumber(result.getLong(2)); 160 member.setObjectId(result.getString(3)); 161 member.setRoleId(result.getString(4)); 162 member.setMemberId(result.getString(5)); 163 member.setTypeCode(result.getString(6)); 164 member.setActiveFromDateValue(result.getTimestamp(7)); 165 member.setActiveToDateValue(result.getTimestamp(8)); 166 member.setLastUpdatedDate(result.getTimestamp(9)); 167 168 members.add(member); 169 } 170 return members; 171 172 } catch (SQLException e) { 173 throw new RuntimeException(e); 174 } 175 176 } 177 178 179 180 protected Collection<RoleMemberAttributeData> getRoleMemberAttributeData(String roleMemberId) { 181 Connection connection = connectionDaoService.getRiceConnection(); 182 try (PreparedStatement stmt = setString(1, roleMemberId, connection.prepareStatement("SELECT ATTR_DATA_ID, OBJ_ID, VER_NBR, ROLE_MBR_ID, KIM_TYP_ID, KIM_ATTR_DEFN_ID, ATTR_VAL FROM KRIM_ROLE_MBR_ATTR_DATA_T WHERE ROLE_MBR_ID = ?")); 183 ResultSet result = stmt.executeQuery()) { 184 185 final Collection<RoleMemberAttributeData> attrs = new ArrayList<RoleMemberAttributeData>(); 186 while(result.next()) { 187 RoleMemberAttributeData attr = new RoleMemberAttributeData(); 188 attr.setId(result.getString(1)); 189 attr.setObjectId(result.getString(2)); 190 attr.setVersionNumber(result.getLong(3)); 191 attr.setRoleMemberId(result.getString(4)); 192 attr.setKimTypeId(result.getString(5)); 193 attr.setKimAttributeId(result.getString(6)); 194 attr.setAttributeValue(result.getString(7)); 195 196 attrs.add(attr); 197 } 198 return attrs; 199 } catch (SQLException e) { 200 throw new RuntimeException(e); 201 } 202 } 203 204 public Role getRole(String roleId) { 205 Connection connection = connectionDaoService.getRiceConnection(); 206 try (PreparedStatement stmt = setString(1, roleId, connection.prepareStatement("SELECT ROLE_ID, ROLE_NM, NMSPC_CD, DESC_TXT, KIM_TYP_ID, ACTV_IND, OBJ_ID, VER_NBR, LAST_UPDT_DT FROM KRIM_ROLE_T WHERE ROLE_ID = ?")); 207 ResultSet result = stmt.executeQuery()) { 208 if (result.next()) { 209 final Role role = new Role(); 210 role.setId(result.getString(1)); 211 role.setName(result.getString(2)); 212 role.setNamespaceCode(result.getString(3)); 213 role.setDescription(result.getString(4)); 214 role.setKimTypeId(result.getString(5)); 215 role.setActive(result.getString(6)); 216 role.setObjectId(result.getString(7)); 217 role.setVersionNumber(result.getLong(8)); 218 role.setLastUpdatedDate(result.getTimestamp(9)); 219 return role; 220 } else { 221 throw new IllegalStateException("role not found"); 222 } 223 } catch (SQLException e) { 224 throw new RuntimeException(e); 225 } 226 } 227 228 public ConnectionDaoService getConnectionDaoService() { 229 return connectionDaoService; 230 } 231 232 public void setConnectionDaoService(ConnectionDaoService connectionDaoService) { 233 this.connectionDaoService = connectionDaoService; 234 } 235 236 public KimTypeDao getKimTypeDao() { 237 return kimTypeDao; 238 } 239 240 public void setKimTypeDao(KimTypeDao kimTypeDao) { 241 this.kimTypeDao = kimTypeDao; 242 } 243 244 public SequenceDaoService getSequenceDaoService() { 245 return sequenceDaoService; 246 } 247 248 public void setSequenceDaoService(SequenceDaoService sequenceDaoService) { 249 this.sequenceDaoService = sequenceDaoService; 250 } 251 252 253 }