View Javadoc
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 }