View Javadoc

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