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