001/**
002 * Copyright 2005-2018 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.krad.service.impl;
017
018import org.apache.commons.lang.StringUtils;
019import org.kuali.rice.core.api.CoreApiServiceLocator;
020import org.kuali.rice.core.api.encryption.EncryptionService;
021import org.kuali.rice.kew.api.WorkflowDocument;
022import org.kuali.rice.krad.UserSession;
023import org.kuali.rice.krad.UserSessionUtils;
024import org.kuali.rice.krad.bo.SessionDocument;
025import org.kuali.rice.krad.dao.SessionDocumentDao;
026import org.kuali.rice.krad.datadictionary.DocumentEntry;
027import org.kuali.rice.krad.service.DataDictionaryService;
028import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
029import org.kuali.rice.krad.service.LegacyDataAdapter;
030import org.kuali.rice.krad.service.SessionDocumentService;
031import org.kuali.rice.krad.web.form.DocumentFormBase;
032import org.springframework.beans.factory.annotation.Required;
033import org.springframework.transaction.annotation.Transactional;
034
035import java.io.ByteArrayInputStream;
036import java.io.ByteArrayOutputStream;
037import java.io.ObjectInputStream;
038import java.io.ObjectOutputStream;
039import java.sql.Timestamp;
040import java.util.HashMap;
041
042/**
043 * Implementation of <code>SessionDocumentService</code> that persists the document form
044 * contents to the underlying database
045 *
046 * @deprecated (Deprecated and removed from use in KRAD  (KULRICE-9149)
047 *
048 * @author Kuali Rice Team (rice.collab@kuali.org)
049 */
050@Transactional
051@Deprecated
052public class SessionDocumentServiceImpl implements SessionDocumentService {
053    private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(SessionDocumentServiceImpl.class);
054
055    protected static final String IP_ADDRESS = "ipAddress";
056    protected static final String PRINCIPAL_ID = "principalId";
057    protected static final String DOCUMENT_NUMBER = "documentNumber";
058    protected static final String SESSION_ID = "sessionId";
059
060    private EncryptionService encryptionService;
061
062    private LegacyDataAdapter legacyDataAdapter;
063    private DataDictionaryService dataDictionaryService;
064    private SessionDocumentDao sessionDocumentDao;
065
066    /**
067     * @deprecated (Deprecated and removed from use in KRAD  (KULRICE-9149)
068     *
069     */
070    @Override
071    @Deprecated
072    public DocumentFormBase getDocumentForm(String documentNumber, String docFormKey, UserSession userSession,
073            String ipAddress) {
074        DocumentFormBase documentForm = null;
075
076        LOG.debug("getDocumentForm DocumentFormBase from db");
077        try {
078            // re-create the DocumentFormBase object
079            documentForm = (DocumentFormBase) retrieveDocumentForm(userSession, docFormKey, documentNumber, ipAddress);
080
081            //re-store workFlowDocument into session
082            WorkflowDocument workflowDocument =
083                    documentForm.getDocument().getDocumentHeader().getWorkflowDocument();
084            UserSessionUtils.addWorkflowDocument(userSession, workflowDocument);
085        } catch (Exception e) {
086            LOG.error("getDocumentForm failed for SessId/DocNum/PrinId/IP:" + userSession.getKualiSessionId() + "/" +
087                    documentNumber + "/" + userSession.getPrincipalId() + "/" + ipAddress, e);
088        }
089
090        return documentForm;
091    }
092
093    @Deprecated
094    protected Object retrieveDocumentForm(UserSession userSession, String sessionId, String documentNumber,
095            String ipAddress) throws Exception {
096        HashMap<String, String> primaryKeys = new HashMap<String, String>(4);
097        primaryKeys.put(SESSION_ID, sessionId);
098        if (documentNumber != null) {
099            primaryKeys.put(DOCUMENT_NUMBER, documentNumber);
100        }
101        primaryKeys.put(PRINCIPAL_ID, userSession.getPrincipalId());
102        primaryKeys.put(IP_ADDRESS, ipAddress);
103
104        SessionDocument sessionDoc = legacyDataAdapter.findByPrimaryKey(SessionDocument.class, primaryKeys);
105        if (sessionDoc != null) {
106            byte[] formAsBytes = sessionDoc.getSerializedDocumentForm();
107            if (sessionDoc.isEncrypted()) {
108                formAsBytes = getEncryptionService().decryptBytes(formAsBytes);
109            }
110            ByteArrayInputStream baip = new ByteArrayInputStream(formAsBytes);
111            ObjectInputStream ois = new ObjectInputStream(baip);
112
113            return ois.readObject();
114        }
115
116        return null;
117    }
118
119    /**
120     * @deprecated (Deprecated and removed from use in KRAD  (KULRICE-9149)
121     *
122     */
123    @Override
124    @Deprecated
125    public WorkflowDocument getDocumentFromSession(UserSession userSession, String docId) {
126        return UserSessionUtils.getWorkflowDocument(userSession, docId);
127    }
128
129    /**
130     * @see org.kuali.rice.krad.service.SessionDocumentService#addDocumentToUserSession(org.kuali.rice.krad.UserSession,
131     *      org.kuali.rice.kew.api.WorkflowDocument)
132     *
133     * @deprecated (Deprecated and removed from use in KRAD  (KULRICE-9149)     *
134     */
135    @Override
136    @Deprecated
137    public void addDocumentToUserSession(UserSession userSession, WorkflowDocument document) {
138        UserSessionUtils.addWorkflowDocument(userSession, document);
139    }
140
141    /**
142     * @see org.kuali.rice.krad.service.SessionDocumentService#purgeDocumentForm(String, String,
143     *      org.kuali.rice.krad.UserSession, String)
144     *
145     * @deprecated (Deprecated and removed from use in KRAD  (KULRICE-9149)
146     */
147    @Override
148    @Deprecated
149    public void purgeDocumentForm(String documentNumber, String docFormKey, UserSession userSession, String ipAddress) {
150        synchronized (userSession) {
151            LOG.debug("purge document form from session");
152            userSession.removeObject(docFormKey);
153            try {
154                LOG.debug("purge document form from database");
155                HashMap<String, String> primaryKeys = new HashMap<String, String>(4);
156                primaryKeys.put(SESSION_ID, userSession.getKualiSessionId());
157                primaryKeys.put(DOCUMENT_NUMBER, documentNumber);
158                primaryKeys.put(PRINCIPAL_ID, userSession.getPrincipalId());
159                primaryKeys.put(IP_ADDRESS, ipAddress);
160                legacyDataAdapter.deleteMatching(SessionDocument.class, primaryKeys);
161            } catch (Exception e) {
162                LOG.error("purgeDocumentForm failed for SessId/DocNum/PrinId/IP:" + userSession.getKualiSessionId() +
163                        "/" + documentNumber + "/" + userSession.getPrincipalId() + "/" + ipAddress, e);
164            }
165        }
166    }
167
168    /**
169     * @deprecated (Deprecated and removed from use in KRAD  (KULRICE-9149)
170     *
171     */
172    @Override
173    @Deprecated
174    public void setDocumentForm(DocumentFormBase form, UserSession userSession, String ipAddress) {
175        synchronized (userSession) {
176            //formKey was set in KualiDocumentActionBase execute method
177            String formKey = form.getFormKey();
178            String key = userSession.getKualiSessionId() + "-" + formKey;
179
180            String documentNumber = form.getDocument().getDocumentNumber();
181            if (StringUtils.isNotBlank(formKey)) {
182                //FIXME: Currently using formKey for sessionId
183                persistDocumentForm(form, userSession, ipAddress, formKey, documentNumber);
184            } else {
185                LOG.warn("documentNumber is null on form's document: " + form);
186            }
187        }
188    }
189
190    @Deprecated
191    protected void persistDocumentForm(DocumentFormBase form, UserSession userSession, String ipAddress,
192            String sessionId, String documentNumber) {
193        try {
194            LOG.debug("set Document Form into database");
195
196            Timestamp currentTime = new Timestamp(System.currentTimeMillis());
197            ByteArrayOutputStream baos = new ByteArrayOutputStream();
198            ObjectOutputStream oos = new ObjectOutputStream(baos);
199            oos.writeObject(form);
200
201            // serialize the DocumentFormBase object into a byte array
202            byte[] formAsBytes = baos.toByteArray();
203            boolean encryptContent = false;
204            DocumentEntry documentEntry =
205                    getDataDictionaryService().getDataDictionary().getDocumentEntry(form.getDocTypeName());
206            if (documentEntry != null) {
207                encryptContent = documentEntry.isEncryptDocumentDataInPersistentSessionStorage();
208            }
209
210            EncryptionService encryptionService = getEncryptionService();
211            if (encryptContent && encryptionService.isEnabled()) {
212                formAsBytes = encryptionService.encryptBytes(formAsBytes);
213            }
214
215            // check if a record is already there in the database
216            // this may only happen under jMeter testing, but there is no way to be sure
217            HashMap<String, String> primaryKeys = new HashMap<String, String>(4);
218            primaryKeys.put(SESSION_ID, sessionId);
219            primaryKeys.put(DOCUMENT_NUMBER, documentNumber);
220            primaryKeys.put(PRINCIPAL_ID, userSession.getPrincipalId());
221            primaryKeys.put(IP_ADDRESS, ipAddress);
222
223            SessionDocument sessionDocument =
224                    legacyDataAdapter.findByPrimaryKey(SessionDocument.class, primaryKeys);
225            if (sessionDocument == null) {
226                sessionDocument = new SessionDocument();
227                sessionDocument.setSessionId(sessionId);
228                sessionDocument.setDocumentNumber(documentNumber);
229                sessionDocument.setPrincipalId(userSession.getPrincipalId());
230                sessionDocument.setIpAddress(ipAddress);
231            }
232            sessionDocument.setSerializedDocumentForm(formAsBytes);
233            sessionDocument.setEncrypted(encryptContent);
234            sessionDocument.setLastUpdatedDate(currentTime);
235
236            legacyDataAdapter.save(sessionDocument);
237        } catch (Exception e) {
238            final String className = form != null ? form.getClass().getName() : "null";
239            LOG.error("setDocumentForm failed for SessId/DocNum/PrinId/IP/class:" + userSession.getKualiSessionId() +
240                    "/" + documentNumber + "/" + userSession.getPrincipalId() + "/" + ipAddress + "/" + className, e);
241        }
242    }
243
244    /**
245     * @see org.kuali.rice.krad.service.SessionDocumentService#purgeAllSessionDocuments(java.sql.Timestamp)
246     *
247     * @deprecated (Deprecated and removed from use in KRAD  (KULRICE-9149)
248     */
249    @Override
250    @Deprecated
251    public void purgeAllSessionDocuments(Timestamp expirationDate) {
252        sessionDocumentDao.purgeAllSessionDocuments(expirationDate);
253    }
254
255    @Deprecated
256    protected SessionDocumentDao getSessionDocumentDao() {
257        return this.sessionDocumentDao;
258    }
259
260    /**
261     * @deprecated (Deprecated and removed from use in KRAD  (KULRICE-9149)
262     *
263     */
264    @Deprecated
265    public void setSessionDocumentDao(SessionDocumentDao sessionDocumentDao) {
266        this.sessionDocumentDao = sessionDocumentDao;
267    }
268    
269    @Required
270    public void setLegacyDataAdapter(LegacyDataAdapter legacyDataAdapter) {
271        this.legacyDataAdapter = legacyDataAdapter;
272    }
273
274    @Deprecated
275    protected EncryptionService getEncryptionService() {
276        if (encryptionService == null) {
277            encryptionService = CoreApiServiceLocator.getEncryptionService();
278        }
279        return encryptionService;
280    }
281
282
283    @Deprecated
284    protected DataDictionaryService getDataDictionaryService() {
285        if (dataDictionaryService == null) {
286            dataDictionaryService = KRADServiceLocatorWeb.getDataDictionaryService();
287        }
288        return dataDictionaryService;
289    }
290}