View Javadoc
1   /**
2    * Copyright 2005-2015 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.kew.routeheader.dao.impl;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
20  import org.kuali.rice.core.api.util.RiceConstants;
21  import org.kuali.rice.core.framework.persistence.jpa.OrmUtils;
22  import org.kuali.rice.core.framework.persistence.jpa.criteria.Criteria;
23  import org.kuali.rice.core.framework.persistence.jpa.criteria.QueryByCriteria;
24  import org.kuali.rice.core.framework.persistence.platform.DatabasePlatform;
25  import org.kuali.rice.kew.actionitem.ActionItem;
26  import org.kuali.rice.kew.actionlist.service.ActionListService;
27  import org.kuali.rice.kew.api.WorkflowRuntimeException;
28  import org.kuali.rice.kew.api.action.ActionRequestStatus;
29  import org.kuali.rice.kew.docsearch.SearchableAttributeValue;
30  import org.kuali.rice.kew.api.exception.LockingException;
31  import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
32  import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValueContent;
33  import org.kuali.rice.kew.routeheader.dao.DocumentRouteHeaderDAO;
34  import org.kuali.rice.kew.service.KEWServiceLocator;
35  
36  import javax.persistence.EntityManager;
37  import javax.persistence.EntityNotFoundException;
38  import javax.persistence.PersistenceContext;
39  import javax.persistence.Query;
40  import java.math.BigDecimal;
41  import java.util.ArrayList;
42  import java.util.Collection;
43  import java.util.Iterator;
44  import java.util.List;
45  import java.util.Set;
46  
47  
48  public class DocumentRouteHeaderDAOJpaImpl implements DocumentRouteHeaderDAO {
49  
50  	@PersistenceContext(unitName="kew-unit")
51  	private EntityManager entityManager;
52      private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DocumentRouteHeaderDAOJpaImpl.class);
53  
54      
55      /**
56  	 * @return the entityManager
57  	 */
58  	public EntityManager getEntityManager() {
59  		return this.entityManager;
60  	}
61  
62  	/**
63  	 * @param entityManager the entityManager to set
64  	 */
65  	public void setEntityManager(EntityManager entityManager) {
66  		this.entityManager = entityManager;
67  	}
68  
69  	public void saveRouteHeader(DocumentRouteHeaderValue routeHeader) {   	
70      	DocumentRouteHeaderValueContent documentContent = routeHeader.getDocumentContent();    	
71  //    	List<SearchableAttributeValue> searchableAttributes = routeHeader.getSearchableAttributeValues();
72      	
73      	if (routeHeader.getDocumentId() == null){
74      		entityManager.persist(routeHeader);
75      	} else {
76      		OrmUtils.merge(entityManager, routeHeader);
77      	}
78          
79          //Save document content (document content retrieved via a service call)
80          documentContent.setDocumentId(routeHeader.getDocumentId());
81          entityManager.merge(documentContent);
82          
83          /*
84          //Save searchable attributes
85          for (SearchableAttributeValue searchableAttributeValue:searchableAttributes){
86          	searchableAttributeValue.setDocumentId(routeHeader.getDocumentId());
87          	if (searchableAttributeValue.getSearchableAttributeValueId() == null){
88          		entityManager.persist(searchableAttributeValue);
89          	} else {
90          		entityManager.merge(searchableAttributeValue);
91          	}
92          }
93          */
94      }
95  
96      public DocumentRouteHeaderValueContent getContent(String documentId) {
97      	Query query = entityManager.createNamedQuery("DocumentRouteHeaderValueContent.FindByDocumentId");
98      	query.setParameter("documentId", documentId);
99          return (DocumentRouteHeaderValueContent)query.getSingleResult();
100     }
101 
102     public void clearRouteHeaderSearchValues(String documentId) {
103     	Collection<SearchableAttributeValue> searchableAttributeValues = findSearchableAttributeValues(documentId);
104     	for (SearchableAttributeValue searchableAttributeValue:searchableAttributeValues){
105     		entityManager.remove(searchableAttributeValue);
106     	}
107     }
108    
109     public Collection<SearchableAttributeValue> findSearchableAttributeValues(String documentId){
110     	List<SearchableAttributeValue> searchableAttributeValues = new ArrayList<SearchableAttributeValue>();
111     	
112     	for (int i=1;i<=4; i++){
113     		String namedQuery = "";
114     		switch (i) {
115 				case 1: namedQuery = "SearchableAttributeFloatValue.FindByDocumentId"; break;
116 				case 2: namedQuery = "SearchableAttributeDateTimeValue.FindByDocumentId"; break;
117 				case 3: namedQuery = "SearchableAttributeLongValue.FindByDocumentId";break;
118 				case 4: namedQuery = "SearchableAttributeStringValue.FindByDocumentId"; break;
119     		}
120 	    	Query query = entityManager.createNamedQuery(namedQuery);
121 	    	query.setParameter("documentId", documentId);   	
122 	    	searchableAttributeValues.addAll(query.getResultList());
123     	}    	
124 
125     	return searchableAttributeValues;
126     }
127 
128     public void lockRouteHeader(final String documentId, final boolean wait) {
129     	String sql = getPlatform().getLockRouteHeaderQuerySQL(documentId, wait);
130     	try{
131 	    	Query query = entityManager.createNativeQuery(sql);
132 	    	query.setParameter(1, documentId);
133 	    	query.getSingleResult();
134     	} catch (Exception e){
135     		//FIXME: Should this check for hibernate LockAcquisitionException
136     		throw new LockingException("Could not aquire lock on document, documentId=" + documentId, e);
137     	}
138     }
139 
140     public DocumentRouteHeaderValue findRouteHeader(String documentId) {
141     	return findRouteHeader(documentId, false);
142     }
143 
144     public DocumentRouteHeaderValue findRouteHeader(String documentId, boolean clearCache) {
145         Query query = entityManager.createNamedQuery("DocumentRouteHeaderValue.FindByDocumentId");
146         query.setParameter("documentId", documentId);
147 
148         //TODO: What cache do we clear when using JPA
149         if (clearCache) {
150         	//this.getPersistenceBrokerTemplate().clearCache();
151         }
152         
153 	    DocumentRouteHeaderValue routeHeader = (DocumentRouteHeaderValue) query.getSingleResult(); 
154 //	    routeHeader.setSearchableAttributeValues(findSearchableAttributeValues(documentId));
155 	    return routeHeader;
156     }
157 
158     public Collection<DocumentRouteHeaderValue> findRouteHeaders(Collection<String> documentIds) {
159     	return findRouteHeaders(documentIds, false);
160     }
161     
162     public Collection<DocumentRouteHeaderValue> findRouteHeaders(Collection<String> documentIds, boolean clearCache) {
163     	if (documentIds == null || documentIds.isEmpty()) {
164     		return null;
165     	}
166     	Criteria crit = new Criteria(DocumentRouteHeaderValue.class.getName());
167     	crit.in("documentId", documentIds);
168     	
169     	//TODO: What cache do we clear when using JPA
170         if (clearCache) {
171         	//this.getPersistenceBrokerTemplate().clearCache();
172         }
173     	
174     	return new QueryByCriteria(entityManager, crit).toQuery().getResultList();
175     }
176     
177     public void deleteRouteHeader(DocumentRouteHeaderValue routeHeader) {
178     	DocumentRouteHeaderValue attachedRouteHeader = findRouteHeader(routeHeader.getDocumentId());
179     	entityManager.remove(attachedRouteHeader);
180     }
181 
182     public String getNextDocumentId() {
183     	Long nextDocumentId = getPlatform().getNextValSQL("KREW_DOC_HDR_S", entityManager);
184         return nextDocumentId.toString();
185     }
186     
187     protected DatabasePlatform getPlatform() {
188     	return (DatabasePlatform) GlobalResourceLoader.getService(RiceConstants.DB_PLATFORM);
189     }
190 
191     @Override
192     public Collection<String> findPendingByResponsibilityIds(Set<String> responsibilityIds) {
193 
194         if (responsibilityIds.isEmpty()) {
195             return new ArrayList();
196         }
197 
198         String respIds = "('";
199         int index = 0;
200         for (String responsibilityId : responsibilityIds) {
201             respIds += responsibilityId + (index == responsibilityIds.size()-1 ? "" : "','");
202         }
203         respIds += "')";
204 
205         String query = "SELECT DISTINCT(doc_hdr_id) FROM KREW_ACTN_RQST_T "+
206         	"WHERE (STAT_CD='" +
207         	ActionRequestStatus.INITIALIZED.getCode()+
208         	"' OR STAT_CD='"+
209         	ActionRequestStatus.ACTIVATED.getCode()+
210         	"') AND RSP_ID IN "+respIds;
211 
212         LOG.debug("Query to find pending documents for requeue: " + query);
213         
214         List<String> idList = new ArrayList<String>();
215         for (Object tempId : entityManager.createNativeQuery(query).getResultList()) {
216         	idList.add(((String) tempId));
217         }
218 
219         return idList; //(List<Long>)entityManager.createNativeQuery(query).getResultList();
220     }
221 
222     public boolean hasSearchableAttributeValue(String documentId, String searchableAttributeKey, String searchableAttributeValue) {
223     	return hasSearchableAttributeValue(documentId, searchableAttributeKey, searchableAttributeValue, "SearchableAttributeDateTimeValue.FindByKey")
224     		|| hasSearchableAttributeValue(documentId, searchableAttributeKey, searchableAttributeValue, "SearchableAttributeStringValue.FindByKey")
225     		|| hasSearchableAttributeValue(documentId, searchableAttributeKey, searchableAttributeValue, "SearchableAttributeLongValue.FindByKey")
226     		|| hasSearchableAttributeValue(documentId, searchableAttributeKey, searchableAttributeValue, "SearchableAttributeFloatValue.FindByKey");
227     }
228     
229     private boolean hasSearchableAttributeValue(String documentId, String searchableAttributeKey, String searchableAttributeValue, String namedQuery) {
230     	Query query = entityManager.createNamedQuery(namedQuery);
231         query.setParameter("documentId", documentId);
232         query.setParameter("searchableAttributeKey", searchableAttributeKey);
233         Collection results = query.getResultList();
234         if (!results.isEmpty()) {
235             for (Iterator iterator = results.iterator(); iterator.hasNext();) {
236                 SearchableAttributeValue attribute = (SearchableAttributeValue) iterator.next();
237                 if (StringUtils.equals(attribute.getSearchableAttributeDisplayValue(), searchableAttributeValue)) {
238                     return true;
239                 }
240             }
241         }
242         return false;    	
243     }
244 
245     public String getApplicationIdByDocumentId(String documentId) {
246     	if (documentId == null) {
247     		throw new IllegalArgumentException("Encountered a null document ID.");
248     	}
249     	
250     	String applicationId = null;
251     	
252     	try {
253             String sql = "SELECT DT.APPL_ID FROM KREW_DOC_TYP_T DT, KREW_DOC_HDR_T DH "+
254             	"WHERE DH.DOC_TYP_ID=DT.DOC_TYP_ID AND "+
255             	"DH.DOC_HDR_ID=?";
256         	
257             Query query = entityManager.createNativeQuery(sql);
258             query.setParameter(1, documentId);
259             
260             applicationId = (String)query.getSingleResult();
261     	} catch (EntityNotFoundException enfe) {
262     		throw new WorkflowRuntimeException(enfe.getMessage());
263 		}
264     	
265     	return applicationId;
266     }
267 
268     public String getDocumentStatus(String documentId) {
269     	DocumentRouteHeaderValue document = findRouteHeader(documentId);
270 
271 		return document.getDocRouteStatus();
272     }
273     
274     public String getAppDocId(String documentId) {
275     	Query query = entityManager.createNamedQuery("DocumentRouteHeaderValue.GetAppDocId");
276         query.setParameter("documentId", documentId);
277         return (String) query.getSingleResult(); 
278  	 }
279 
280     public String getAppDocStatus(String documentId) {
281         Query query = entityManager.createNamedQuery("DocumentRouteHeaderValue.GetAppDocStatus");
282         query.setParameter("documentId", documentId);
283         return (String) query.getSingleResult();
284     }
285 
286     public void save(SearchableAttributeValue searchableAttributeValue) {   	
287     	if (searchableAttributeValue.getSearchableAttributeValueId() == null){
288     		entityManager.persist(searchableAttributeValue);
289     	} else {
290     		entityManager.merge(searchableAttributeValue);
291     	}
292     }
293 
294 	public Collection findByDocTypeAndAppId(String documentTypeName,
295 			String appId) {
296     	try {
297             String sql = 
298         	 	"SELECT DISTINCT " +
299         		"    (docHdr.doc_hdr_id) " +
300         		"FROM " +
301         		"    KREW_DOC_HDR_T docHdr, " +
302         		"    KREW_DOC_TYP_T docTyp " +
303         		"WHERE " +
304         		"    docHdr.APP_DOC_ID     = ? " +
305         		"    AND docHdr.DOC_TYP_ID = docTyp.DOC_TYP_ID " +
306         		"    AND docTyp.DOC_TYP_NM = ?";
307         	
308             Query query = entityManager.createNativeQuery(sql);
309             query.setParameter(1, appId);
310             query.setParameter(2, documentTypeName);
311             Collection<Long> idCollection = new ArrayList<Long>();
312             for (Object tempId : query.getResultList()) {
313             	idCollection.add(((BigDecimal)tempId).longValueExact());
314             }
315             return idCollection;
316     	} catch (EntityNotFoundException enfe) {
317     		throw new WorkflowRuntimeException(enfe.getMessage());
318 		}
319 	}
320 
321 
322 }