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