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 }