001/**
002 * Copyright 2005-2017 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.kew.quicklinks.dao.impl;
017
018import org.kuali.rice.core.api.delegation.DelegationType;
019import org.kuali.rice.core.api.util.KeyValue;
020import org.kuali.rice.coreservice.framework.CoreFrameworkServiceLocator;
021import org.kuali.rice.kew.api.KewApiConstants;
022import org.kuali.rice.kew.api.WorkflowRuntimeException;
023import org.kuali.rice.kew.docsearch.service.DocumentSearchService;
024import org.kuali.rice.kew.doctype.DocumentTypePolicy;
025import org.kuali.rice.kew.doctype.bo.DocumentType;
026import org.kuali.rice.kew.doctype.service.DocumentTypeService;
027import org.kuali.rice.kew.quicklinks.ActionListStats;
028import org.kuali.rice.kew.quicklinks.InitiatedDocumentType;
029import org.kuali.rice.kew.quicklinks.WatchedDocument;
030import org.kuali.rice.kew.quicklinks.dao.QuickLinksDAO;
031import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
032import org.kuali.rice.kew.service.KEWServiceLocator;
033import org.kuali.rice.krad.util.KRADConstants;
034
035import javax.persistence.EntityManager;
036import java.util.ArrayList;
037import java.util.Collections;
038import java.util.List;
039import java.util.StringTokenizer;
040
041public class QuickLinksDAOJpa implements QuickLinksDAO {
042
043    private EntityManager entityManager;
044
045    public static final String FIND_WATCHED_DOCUMENTS_BY_INITIATOR_WORKFLOW_ID_NAME =
046            "DocumentRouteHeaderValue.QuickLinks.FindWatchedDocumentsByInitiatorWorkflowId";
047    public static final String FIND_WATCHED_DOCUMENTS_BY_INITIATOR_WORKFLOW_ID_QUERY = "SELECT d FROM "
048            + "DocumentRouteHeaderValue d WHERE d.initiatorWorkflowId = :initiatorWorkflowId AND "
049            + "d.docRouteStatus IN ('"+ KewApiConstants.ROUTE_HEADER_ENROUTE_CD +"','"
050            + KewApiConstants.ROUTE_HEADER_EXCEPTION_CD +"') ORDER BY d.createDate DESC";
051
052    @Override
053        @SuppressWarnings("unchecked")
054    public List<ActionListStats> getActionListStats(final String principalId) {
055        try {
056            final List<Object[]> stats = getEntityManager().createNamedQuery("ActionItem.GetQuickLinksDocumentTypeNameAndCount").
057                    setParameter("principalId", principalId).setParameter("delegationType", DelegationType
058                    .SECONDARY.getCode()).getResultList();
059            final List<ActionListStats> docTypes = new ArrayList<ActionListStats>(stats.size());
060            for (Object[] res : stats) {
061                final String docTypeName = (String) res[0];
062                final Long count = (Long) res[1];
063
064                final DocumentType docType = getDocumentTypeService().findByName(docTypeName);
065                if(docType != null){
066                    docTypes.add(new ActionListStats(docTypeName, docType.getLabel(), count.intValue()));
067                }
068            }
069            Collections.sort(docTypes);
070            return docTypes;
071        } catch (Exception e) {
072            throw new WorkflowRuntimeException("Error getting action list stats for user: " + principalId, e);
073        }
074    }
075
076    @Override
077        @SuppressWarnings("unchecked")
078    public List<InitiatedDocumentType> getInitiatedDocumentTypesList(final String principalId) {
079        String documentNames = CoreFrameworkServiceLocator.getParameterService().getParameterValueAsString(KewApiConstants.KEW_NAMESPACE, KRADConstants.DetailTypes.QUICK_LINK_DETAIL_TYPE, KewApiConstants.QUICK_LINKS_RESTRICT_DOCUMENT_TYPES);
080        if (documentNames != null) {
081            documentNames = documentNames.trim();
082        }
083        if (documentNames == null || "none".equals(documentNames)) {
084            documentNames = "";
085        }
086
087        final StringTokenizer st = new StringTokenizer(documentNames, ",");
088        final List<String> docTypesToRestrict = new ArrayList<String>();
089        while (st.hasMoreTokens()) {
090            docTypesToRestrict.add(st.nextToken());
091        }
092
093        try {
094            final List<Object[]> list = getEntityManager().createNamedQuery(
095                    "DocumentType.QuickLinks.FindInitiatedDocumentTypesListByInitiatorWorkflowId").
096                    setParameter("initiatorWorkflowId", principalId).getResultList();
097            final List<InitiatedDocumentType> documentTypesByName = new ArrayList<InitiatedDocumentType>(list.size());
098            for (Object[] doc : list) {
099                final String docTypeName = (String) doc[0];
100                final String label = (String) doc[1];
101
102                final String docTypeTopParent;
103                final int firstPeriod = docTypeName.indexOf(".");
104                if (firstPeriod == -1) {
105                    docTypeTopParent = docTypeName.substring(0);
106                } else {
107                    docTypeTopParent = docTypeName.substring(0, firstPeriod);
108                }
109                if (!docTypesToRestrict.contains(docTypeTopParent)) {
110                    // the document types should be cached so this should be pretty quick
111                    final DocumentType docType = KEWServiceLocator.getDocumentTypeService().findByName(docTypeName);
112                    final DocumentTypePolicy quickInitiatePolicy = docType.getSupportsQuickInitiatePolicy();
113                    if (quickInitiatePolicy.getPolicyValue().booleanValue()) {
114                        documentTypesByName.add(new InitiatedDocumentType(docTypeName, label));
115                    }
116                }
117            }
118            return documentTypesByName;
119        } catch (Exception e) {
120            throw new WorkflowRuntimeException("Error getting initiated document types for user: " + principalId, e);
121        }
122    }
123
124    @Override
125        public List<KeyValue> getNamedSearches(String principalId) {
126        return getDocumentSearchService().getNamedSearches(principalId);
127    }
128
129    @Override
130        public List<KeyValue> getRecentSearches(String principalId) {
131        return getDocumentSearchService().getMostRecentSearches(principalId);
132    }
133
134    @Override
135        @SuppressWarnings("unchecked")
136    public List<WatchedDocument> getWatchedDocuments(final String principalId) {
137        try {
138            List<DocumentRouteHeaderValue> documentRouteHeaderValues =  getEntityManager().createNamedQuery(
139                    QuickLinksDAOJpa.FIND_WATCHED_DOCUMENTS_BY_INITIATOR_WORKFLOW_ID_NAME).
140                    setParameter("initiatorWorkflowId", principalId).getResultList();
141            List<WatchedDocument> watchedDocuments = new ArrayList<WatchedDocument>();
142            for(DocumentRouteHeaderValue documentRouteHeader : documentRouteHeaderValues){
143                WatchedDocument watchedDocument = new WatchedDocument(documentRouteHeader.getDocumentId(),
144                        documentRouteHeader.getDocRouteStatusLabel(),documentRouteHeader.getDocTitle());
145                watchedDocuments.add(watchedDocument);
146            }
147            return watchedDocuments;
148        } catch (Exception e) {
149            throw new WorkflowRuntimeException("Error getting watched documents for user: " + principalId, e);
150        }
151    }
152
153    public DocumentTypeService getDocumentTypeService() {
154        return ((DocumentTypeService) KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_TYPE_SERVICE));
155    }
156
157    public DocumentSearchService getDocumentSearchService() {
158        return ((DocumentSearchService) KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_SEARCH_SERVICE));
159    }
160
161    public EntityManager getEntityManager() {
162        return this.entityManager;
163    }
164
165    public void setEntityManager(EntityManager entityManager) {
166        this.entityManager = entityManager;
167    }
168}