1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.service.impl;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.kuali.rice.core.api.CoreApiServiceLocator;
20 import org.kuali.rice.core.api.encryption.EncryptionService;
21 import org.kuali.rice.kew.api.WorkflowDocument;
22 import org.kuali.rice.kew.api.KewApiConstants;
23 import org.kuali.rice.krad.UserSession;
24 import org.kuali.rice.krad.bo.SessionDocument;
25 import org.kuali.rice.krad.dao.SessionDocumentDao;
26 import org.kuali.rice.krad.datadictionary.DocumentEntry;
27 import org.kuali.rice.krad.service.BusinessObjectService;
28 import org.kuali.rice.krad.service.DataDictionaryService;
29 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
30 import org.kuali.rice.krad.service.SessionDocumentService;
31 import org.kuali.rice.krad.web.form.DocumentFormBase;
32 import org.springframework.transaction.annotation.Transactional;
33
34 import java.io.ByteArrayInputStream;
35 import java.io.ByteArrayOutputStream;
36 import java.io.ObjectInputStream;
37 import java.io.ObjectOutputStream;
38 import java.sql.Timestamp;
39 import java.util.HashMap;
40 import java.util.Map;
41
42
43
44
45
46
47
48 @Transactional
49 public class SessionDocumentServiceImpl implements SessionDocumentService {
50 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(SessionDocumentServiceImpl.class);
51
52 protected static final String IP_ADDRESS = "ipAddress";
53 protected static final String PRINCIPAL_ID = "principalId";
54 protected static final String DOCUMENT_NUMBER = "documentNumber";
55 protected static final String SESSION_ID = "sessionId";
56
57 private EncryptionService encryptionService;
58
59 private BusinessObjectService businessObjectService;
60 private DataDictionaryService dataDictionaryService;
61 private SessionDocumentDao sessionDocumentDao;
62
63 @Override
64 public DocumentFormBase getDocumentForm(String documentNumber, String docFormKey, UserSession userSession,
65 String ipAddress) {
66 DocumentFormBase documentForm = null;
67
68 LOG.debug("getDocumentForm DocumentFormBase from db");
69 try {
70
71 documentForm = (DocumentFormBase) retrieveDocumentForm(userSession, docFormKey, documentNumber, ipAddress);
72
73
74 WorkflowDocument workflowDocument =
75 documentForm.getDocument().getDocumentHeader().getWorkflowDocument();
76 addDocumentToUserSession(userSession, workflowDocument);
77 } catch (Exception e) {
78 LOG.error("getDocumentForm failed for SessId/DocNum/PrinId/IP:" + userSession.getKualiSessionId() + "/" +
79 documentNumber + "/" + userSession.getPrincipalId() + "/" + ipAddress, e);
80 }
81
82 return documentForm;
83 }
84
85 protected Object retrieveDocumentForm(UserSession userSession, String sessionId, String documentNumber,
86 String ipAddress) throws Exception {
87 HashMap<String, String> primaryKeys = new HashMap<String, String>(4);
88 primaryKeys.put(SESSION_ID, sessionId);
89 if (documentNumber != null) {
90 primaryKeys.put(DOCUMENT_NUMBER, documentNumber);
91 }
92 primaryKeys.put(PRINCIPAL_ID, userSession.getPrincipalId());
93 primaryKeys.put(IP_ADDRESS, ipAddress);
94
95 SessionDocument sessionDoc = getBusinessObjectService().findByPrimaryKey(SessionDocument.class, primaryKeys);
96 if (sessionDoc != null) {
97 byte[] formAsBytes = sessionDoc.getSerializedDocumentForm();
98 if (sessionDoc.isEncrypted()) {
99 formAsBytes = getEncryptionService().decryptBytes(formAsBytes);
100 }
101 ByteArrayInputStream baip = new ByteArrayInputStream(formAsBytes);
102 ObjectInputStream ois = new ObjectInputStream(baip);
103
104 return ois.readObject();
105 }
106
107 return null;
108 }
109
110 @Override
111 public WorkflowDocument getDocumentFromSession(UserSession userSession, String docId) {
112 @SuppressWarnings("unchecked") Map<String, WorkflowDocument> workflowDocMap =
113 (Map<String, WorkflowDocument>) userSession
114 .retrieveObject(KewApiConstants.WORKFLOW_DOCUMENT_MAP_ATTR_NAME);
115
116 if (workflowDocMap == null) {
117 workflowDocMap = new HashMap<String, WorkflowDocument>();
118 userSession.addObject(KewApiConstants.WORKFLOW_DOCUMENT_MAP_ATTR_NAME, workflowDocMap);
119 return null;
120 }
121 return workflowDocMap.get(docId);
122 }
123
124
125
126
127
128 @Override
129 public void addDocumentToUserSession(UserSession userSession, WorkflowDocument document) {
130 @SuppressWarnings("unchecked") Map<String, WorkflowDocument> workflowDocMap =
131 (Map<String, WorkflowDocument>) userSession
132 .retrieveObject(KewApiConstants.WORKFLOW_DOCUMENT_MAP_ATTR_NAME);
133 if (workflowDocMap == null) {
134 workflowDocMap = new HashMap<String, WorkflowDocument>();
135 }
136 workflowDocMap.put(document.getDocumentId(), document);
137 userSession.addObject(KewApiConstants.WORKFLOW_DOCUMENT_MAP_ATTR_NAME, workflowDocMap);
138 }
139
140
141
142
143
144 @Override
145 public void purgeDocumentForm(String documentNumber, String docFormKey, UserSession userSession, String ipAddress) {
146 synchronized (userSession) {
147
148 LOG.debug("purge document form from session");
149 userSession.removeObject(docFormKey);
150 try {
151 LOG.debug("purge document form from database");
152 HashMap<String, String> primaryKeys = new HashMap<String, String>(4);
153 primaryKeys.put(SESSION_ID, userSession.getKualiSessionId());
154 primaryKeys.put(DOCUMENT_NUMBER, documentNumber);
155 primaryKeys.put(PRINCIPAL_ID, userSession.getPrincipalId());
156 primaryKeys.put(IP_ADDRESS, ipAddress);
157 getBusinessObjectService().deleteMatching(SessionDocument.class, primaryKeys);
158 } catch (Exception e) {
159 LOG.error("purgeDocumentForm failed for SessId/DocNum/PrinId/IP:" + userSession.getKualiSessionId() +
160 "/" + documentNumber + "/" + userSession.getPrincipalId() + "/" + ipAddress, e);
161 }
162 }
163 }
164
165 @Override
166 public void setDocumentForm(DocumentFormBase form, UserSession userSession, String ipAddress) {
167 synchronized (userSession) {
168
169 String formKey = form.getFormKey();
170 String key = userSession.getKualiSessionId() + "-" + formKey;
171
172 String documentNumber = form.getDocument().getDocumentNumber();
173 if (StringUtils.isNotBlank(formKey)) {
174
175 persistDocumentForm(form, userSession, ipAddress, formKey, documentNumber);
176 } else {
177 LOG.warn("documentNumber is null on form's document: " + form);
178 }
179 }
180 }
181
182 protected void persistDocumentForm(DocumentFormBase form, UserSession userSession, String ipAddress,
183 String sessionId, String documentNumber) {
184 try {
185 LOG.debug("set Document Form into database");
186
187 Timestamp currentTime = new Timestamp(System.currentTimeMillis());
188 ByteArrayOutputStream baos = new ByteArrayOutputStream();
189 ObjectOutputStream oos = new ObjectOutputStream(baos);
190 oos.writeObject(form);
191
192
193 byte[] formAsBytes = baos.toByteArray();
194 boolean encryptContent = false;
195 DocumentEntry documentEntry =
196 getDataDictionaryService().getDataDictionary().getDocumentEntry(form.getDocTypeName());
197 if (documentEntry != null) {
198 encryptContent = documentEntry.isEncryptDocumentDataInPersistentSessionStorage();
199 }
200
201 if (encryptContent) {
202 formAsBytes = getEncryptionService().encryptBytes(formAsBytes);
203 }
204
205
206
207 HashMap<String, String> primaryKeys = new HashMap<String, String>(4);
208 primaryKeys.put(SESSION_ID, sessionId);
209 primaryKeys.put(DOCUMENT_NUMBER, documentNumber);
210 primaryKeys.put(PRINCIPAL_ID, userSession.getPrincipalId());
211 primaryKeys.put(IP_ADDRESS, ipAddress);
212
213 SessionDocument sessionDocument =
214 getBusinessObjectService().findByPrimaryKey(SessionDocument.class, primaryKeys);
215 if (sessionDocument == null) {
216 sessionDocument = new SessionDocument();
217 sessionDocument.setSessionId(sessionId);
218 sessionDocument.setDocumentNumber(documentNumber);
219 sessionDocument.setPrincipalId(userSession.getPrincipalId());
220 sessionDocument.setIpAddress(ipAddress);
221 }
222 sessionDocument.setSerializedDocumentForm(formAsBytes);
223 sessionDocument.setEncrypted(encryptContent);
224 sessionDocument.setLastUpdatedDate(currentTime);
225
226 businessObjectService.save(sessionDocument);
227 } catch (Exception e) {
228 final String className = form != null ? form.getClass().getName() : "null";
229 LOG.error("setDocumentForm failed for SessId/DocNum/PrinId/IP/class:" + userSession.getKualiSessionId() +
230 "/" + documentNumber + "/" + userSession.getPrincipalId() + "/" + ipAddress + "/" + className, e);
231 }
232 }
233
234
235
236
237 @Override
238 public void purgeAllSessionDocuments(Timestamp expirationDate) {
239 sessionDocumentDao.purgeAllSessionDocuments(expirationDate);
240 }
241
242 protected SessionDocumentDao getSessionDocumentDao() {
243 return this.sessionDocumentDao;
244 }
245
246 public void setSessionDocumentDao(SessionDocumentDao sessionDocumentDao) {
247 this.sessionDocumentDao = sessionDocumentDao;
248 }
249
250 protected BusinessObjectService getBusinessObjectService() {
251 return this.businessObjectService;
252 }
253
254 public void setBusinessObjectService(BusinessObjectService businessObjectService) {
255 this.businessObjectService = businessObjectService;
256 }
257
258 protected EncryptionService getEncryptionService() {
259 if (encryptionService == null) {
260 encryptionService = CoreApiServiceLocator.getEncryptionService();
261 }
262 return encryptionService;
263 }
264
265 protected DataDictionaryService getDataDictionaryService() {
266 if (dataDictionaryService == null) {
267 dataDictionaryService = KRADServiceLocatorWeb.getDataDictionaryService();
268 }
269 return dataDictionaryService;
270 }
271 }