001/**
002 * Copyright 2005-2016 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.doctype.dao.impl;
017
018import java.util.ArrayList;
019import java.util.Collection;
020import java.util.Iterator;
021import java.util.List;
022
023import javax.persistence.EntityManager;
024import javax.persistence.PersistenceContext;
025import javax.persistence.Query;
026
027import org.apache.log4j.Logger;
028import org.kuali.rice.core.framework.persistence.jpa.OrmUtils;
029import org.kuali.rice.core.framework.persistence.jpa.criteria.Criteria;
030import org.kuali.rice.core.framework.persistence.jpa.criteria.QueryByCriteria;
031import org.kuali.rice.kew.doctype.DocumentTypeAttributeBo;
032import org.kuali.rice.kew.doctype.bo.DocumentType;
033import org.kuali.rice.kew.doctype.dao.DocumentTypeDAO;
034import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
035import org.kuali.rice.kew.rule.bo.RuleAttribute;
036
037
038public class DocumentTypeDAOJpaImpl implements DocumentTypeDAO {
039
040        public static final Logger LOG = Logger.getLogger(DocumentTypeDAOJpaImpl.class);
041
042        @PersistenceContext(unitName="kew-unit")
043        private EntityManager entityManager;
044
045
046        /**
047         * @return the entityManager
048         */
049        public EntityManager getEntityManager() {
050                return this.entityManager;
051        }
052
053        /**
054         * @param entityManager the entityManager to set
055         */
056        public void setEntityManager(EntityManager entityManager) {
057                this.entityManager = entityManager;
058        }
059
060        public void delete(DocumentType documentType) {
061                DocumentType docType = findById(documentType.getDocumentTypeId());
062                entityManager.remove(documentType);
063        }
064
065        public DocumentType findById(String docTypeId) {
066                Criteria crit = new Criteria(DocumentType.class.getName());
067                crit.eq("documentTypeId", docTypeId);
068                        return (DocumentType) new QueryByCriteria(entityManager, crit).toQuery().getSingleResult();
069        }
070
071        public DocumentType findByName(String name){
072                return findByName(name, true); // by default find by name is case sensitive
073        }
074
075        public DocumentType findByName(String name, boolean caseSensitive) {
076                Criteria crit = new Criteria(DocumentType.class.getName());
077                if(!caseSensitive){
078                        crit.like("UPPER(__JPA_ALIAS[[0]]__.name)", ("%" + name.trim() + "%").toUpperCase());
079
080                }else{
081                        crit.eq("name", name);
082                }
083                crit.eq("currentInd", Boolean.TRUE);
084                DocumentType docType = (DocumentType) new QueryByCriteria(entityManager, crit).toQuery().getSingleResult();
085                return docType;
086        }
087
088        public Integer getMaxVersionNumber(String docTypeName) {
089                return getMostRecentDocType(docTypeName).getVersion();
090        }
091
092        public List<String> getChildDocumentTypeIds(String parentDocumentTypeId) {
093                List<String> childrenIds = new ArrayList<String>();
094                try {
095                        String sql = "select DOC_TYP_ID from KREW_DOC_TYP_T where CUR_IND = 1 and PARNT_ID = " + parentDocumentTypeId;
096                        Query query = entityManager.createNativeQuery(sql);
097                        List resultIds = query.getResultList();
098                        for (Object id : resultIds){
099                                childrenIds.add(id.toString());
100                        }
101
102                } catch (Exception e) {
103                        LOG.error("Error occured fetching children document type ids for document type " + parentDocumentTypeId, e);
104                        throw new RuntimeException(e);
105                }
106
107                return childrenIds;
108        }
109
110        protected DocumentType getMostRecentDocType(String docTypeName) {
111                Criteria crit = new Criteria(DocumentType.class.getName());
112                crit.eq("name", docTypeName);
113                crit.orderBy("version", false);
114
115                Iterator docTypes = new QueryByCriteria(entityManager, crit).toQuery().getResultList().iterator();
116                while (docTypes.hasNext()) {
117                        return (DocumentType) docTypes.next();
118                }
119                return null;
120        }
121
122        public void save(DocumentType documentType) {
123                if (documentType.getDocumentTypeId() == null){
124                        entityManager.persist(documentType);
125                } else {
126                        OrmUtils.merge(entityManager, documentType);
127                }
128        }
129
130        public List findByDocumentId(String documentId) {
131                Criteria crit = new Criteria(DocumentType.class.getName());
132                crit.eq("documentId", documentId);
133                return (List) new QueryByCriteria(entityManager, crit).toQuery().getResultList();
134        }
135
136        public Collection<DocumentType> find(DocumentType documentType, DocumentType docTypeParent, boolean climbHierarchy) {
137                LOG.debug("documentType: "+ documentType);
138                LOG.debug("docTypeParent: "+ docTypeParent);
139                LOG.debug("climbHierarchy: " + climbHierarchy);
140
141                Criteria crit = new Criteria(DocumentType.class.getName());
142                if (documentType != null && !org.apache.commons.lang.StringUtils.isEmpty(documentType.getLabel())) {
143                        crit.like("UPPER(__JPA_ALIAS[[0]]__.label)", documentType.getLabel().trim().toUpperCase());
144                }
145                if (documentType != null && !org.apache.commons.lang.StringUtils.isEmpty(documentType.getName())) {
146                        String docTypeName = documentType.getName();
147                        crit.like("UPPER(__JPA_ALIAS[[0]]__.name)", ("%" + docTypeName.trim() + "%").toUpperCase());
148                }
149                if (documentType != null && documentType.getActive() != null) {
150                        crit.eq("active", documentType.getActive());
151                }
152                if (documentType != null && documentType.getDocumentTypeId() != null) {
153                        crit.eq("documentTypeId", documentType.getDocumentTypeId());
154                }
155                if (documentType != null && documentType.getActualApplicationId() != null){
156                        crit.eq("applicationId", documentType.getActualApplicationId());
157                }
158                if (docTypeParent != null) {
159                        if (!"".equals(docTypeParent.getName()) && docTypeParent.getName() != null) {
160                                Criteria parentCrit = new Criteria(DocumentType.class.getName());
161                                //addParentNameOrCriteria(docTypeParent.getName(), parentCrit);
162                                addParentIdOrCriteria(docTypeParent.getDocumentTypeId(), parentCrit);
163                                if (climbHierarchy) {
164                                        assembleChildrenCriteria(docTypeParent.getChildrenDocTypes(), parentCrit);
165                                }
166                                parentCrit.eq("currentInd", Boolean.TRUE);
167                                crit.and(parentCrit);
168                        }
169                } else {
170                        if (documentType != null && !org.apache.commons.lang.StringUtils.isEmpty(documentType.getName())) {
171                                DocumentType searchDocumentType = findByName(documentType.getName());
172                                if ((searchDocumentType != null) && climbHierarchy) {
173                                        LOG.debug("searchDocumentType: "+ searchDocumentType);
174                                        Criteria criteria = new Criteria(DocumentType.class.getName());
175                                        //addParentNameOrCriteria(searchDocumentType.getName(), criteria);
176                    addParentIdOrCriteria(searchDocumentType.getDocumentTypeId(), criteria);
177                    assembleChildrenCriteria(searchDocumentType.getChildrenDocTypes(), criteria);
178                                        criteria.eq("currentInd", Boolean.TRUE);
179                                        crit.or(criteria);
180                                }
181                        }
182                }
183                crit.eq("currentInd", Boolean.TRUE);
184                return new QueryByCriteria(entityManager, crit).toQuery().getResultList();
185        }
186
187    private void addParentIdOrCriteria(String parentId, Criteria mainCriteria) {
188        Criteria parentCriteria = new Criteria(DocumentType.class.getName());
189        parentCriteria.eq("docTypeParentId", parentId);
190        mainCriteria.or(parentCriteria);
191    }
192
193        private void assembleChildrenCriteria(Collection childrenDocTypes, Criteria crit) {
194                if (childrenDocTypes != null) {
195                        Iterator childrenDocTypesIter = childrenDocTypes.iterator();
196                        while (childrenDocTypesIter.hasNext()) {
197                                DocumentType child = (DocumentType) childrenDocTypesIter.next();
198                                addParentIdOrCriteria(child.getDocumentTypeId(), crit);
199                                assembleChildrenCriteria(child.getChildrenDocTypes(), crit);
200                        }
201                }
202        }
203
204        
205
206        public List findAllCurrentRootDocuments() {
207                Criteria crit = new Criteria(DocumentType.class.getName());
208                crit.isNull("docTypeParentId");
209                return findAllCurrent(crit);
210        }
211
212    public List findAllCurrent() {
213        return findAllCurrent(new Criteria(DocumentType.class.getName()));
214    }
215
216    public List findAllCurrentByName(String name) {
217                Criteria crit = new Criteria(DocumentType.class.getName());
218                crit.eq("name", name);
219                return findAllCurrent(crit);
220    }
221
222    public List<DocumentType> findPreviousInstances(String name) {
223        Criteria crit = new Criteria(DocumentType.class.getName());
224        crit.eq("name", name);
225        crit.eq("currentInd", Boolean.FALSE);
226        return findAll(crit);
227    }
228
229    private List findAllCurrent(Criteria crit) {
230        crit.eq("currentInd", Boolean.TRUE);
231        return findAll(crit);
232    }
233
234    private List findAll(Criteria crit) {
235        return (List) new QueryByCriteria(entityManager, crit).toQuery().getResultList();
236    }
237
238    public List findDocumentTypeAttributes(RuleAttribute ruleAttribute) {
239        Criteria crit = new Criteria(DocumentTypeAttributeBo.class.getName());
240        if (ruleAttribute.getId() != null) {
241                crit.eq("ruleAttributeId", ruleAttribute.getId());
242        }
243        return (List) new QueryByCriteria(entityManager, crit).toQuery().getResultList();
244    }
245
246    public String findDocumentTypeIdByDocumentId(String documentId) {
247        Criteria crit = new Criteria(DocumentRouteHeaderValue.class.getName());
248        crit.eq("documentId", documentId);
249
250        final DocumentRouteHeaderValue docHeader = (DocumentRouteHeaderValue)new QueryByCriteria(entityManager, crit).toQuery().getSingleResult();
251        return (docHeader != null) ? docHeader.getDocumentTypeId() : null;
252    }
253    
254    public String findDocumentTypeIdByName(String documentTypeName) {
255        Criteria crit = new Criteria(DocumentType.class.getName());
256        crit.eq("name", documentTypeName);
257        crit.eq("currentInd", Boolean.TRUE);
258
259        final DocumentType documentType = (DocumentType)new QueryByCriteria(entityManager, crit).toQuery().getSingleResult();
260        return (documentType != null) ? documentType.getDocumentTypeId() : null;
261    }
262    
263    public String findDocumentTypeNameById(String documentTypeId) {
264        Criteria crit = new Criteria(DocumentType.class.getName());
265        crit.eq("documentTypeId", documentTypeId);
266
267        final DocumentType documentType = (DocumentType)new QueryByCriteria(entityManager, crit).toQuery().getSingleResult();
268        return (documentType != null) ? documentType.getName() : null;
269    }
270
271}