View Javadoc

1   /**
2    * Copyright 2005-2011 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     	List<SearchableAttributeValue> searchableAttributeValues = findSearchableAttributeValues(documentId);
104     	for (SearchableAttributeValue searchableAttributeValue:searchableAttributeValues){
105     		entityManager.remove(searchableAttributeValue);
106     	}
107     }
108    
109     private List<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     	// need to clear action list cache for users who have this item in their action list
179     	ActionListService actionListSrv = KEWServiceLocator.getActionListService();
180     	Collection actionItems = actionListSrv.findByDocumentId(routeHeader.getDocumentId());
181     	for (Iterator iter = actionItems.iterator(); iter.hasNext();) {
182     		ActionItem actionItem = (ActionItem) iter.next();
183     		try {
184     			KEWServiceLocator.getUserOptionsService().saveRefreshUserOption(actionItem.getPrincipalId());
185     		} catch (Exception e) {
186     			LOG.error("error saving refreshUserOption", e);
187     		}
188     	}
189     	
190     	DocumentRouteHeaderValue attachedRouteHeader = findRouteHeader(routeHeader.getDocumentId());
191     	entityManager.remove(attachedRouteHeader);
192     }
193 
194     public String getNextDocumentId() {
195     	Long nextDocumentId = getPlatform().getNextValSQL("KREW_DOC_HDR_S", entityManager);
196         return nextDocumentId.toString();
197     }
198     
199     protected DatabasePlatform getPlatform() {
200     	return (DatabasePlatform) GlobalResourceLoader.getService(RiceConstants.DB_PLATFORM);
201     }
202 
203     @Override
204     public Collection<String> findPendingByResponsibilityIds(Set<String> responsibilityIds) {
205 
206         if (responsibilityIds.isEmpty()) {
207             return new ArrayList();
208         }
209 
210         String respIds = "(";
211         int index = 0;
212         for (String responsibilityId : responsibilityIds) {
213             respIds += responsibilityId + (index == responsibilityIds.size()-1 ? "" : ",");
214         }
215         respIds += ")";
216 
217         String query = "SELECT DISTINCT(doc_hdr_id) FROM KREW_ACTN_RQST_T "+
218         	"WHERE (STAT_CD='" +
219         	ActionRequestStatus.INITIALIZED.getCode()+
220         	"' OR STAT_CD='"+
221         	ActionRequestStatus.ACTIVATED.getCode()+
222         	"') AND RSP_ID IN "+respIds;
223 
224         LOG.debug("Query to find pending documents for requeue: " + query);
225         
226         List<String> idList = new ArrayList<String>();
227         for (Object tempId : entityManager.createNativeQuery(query).getResultList()) {
228         	idList.add(((String) tempId));
229         }
230 
231         return idList; //(List<Long>)entityManager.createNativeQuery(query).getResultList();
232     }
233 
234     public boolean hasSearchableAttributeValue(String documentId, String searchableAttributeKey, String searchableAttributeValue) {
235     	return hasSearchableAttributeValue(documentId, searchableAttributeKey, searchableAttributeValue, "SearchableAttributeDateTimeValue.FindByKey")
236     		|| hasSearchableAttributeValue(documentId, searchableAttributeKey, searchableAttributeValue, "SearchableAttributeStringValue.FindByKey")
237     		|| hasSearchableAttributeValue(documentId, searchableAttributeKey, searchableAttributeValue, "SearchableAttributeLongValue.FindByKey")
238     		|| hasSearchableAttributeValue(documentId, searchableAttributeKey, searchableAttributeValue, "SearchableAttributeFloatValue.FindByKey");
239     }
240     
241     private boolean hasSearchableAttributeValue(String documentId, String searchableAttributeKey, String searchableAttributeValue, String namedQuery) {
242     	Query query = entityManager.createNamedQuery(namedQuery);
243         query.setParameter("documentId", documentId);
244         query.setParameter("searchableAttributeKey", searchableAttributeKey);
245         Collection results = query.getResultList();
246         if (!results.isEmpty()) {
247             for (Iterator iterator = results.iterator(); iterator.hasNext();) {
248                 SearchableAttributeValue attribute = (SearchableAttributeValue) iterator.next();
249                 if (StringUtils.equals(attribute.getSearchableAttributeDisplayValue(), searchableAttributeValue)) {
250                     return true;
251                 }
252             }
253         }
254         return false;    	
255     }
256 
257     public String getApplicationIdByDocumentId(String documentId) {
258     	if (documentId == null) {
259     		throw new IllegalArgumentException("Encountered a null document ID.");
260     	}
261     	
262     	String applicationId = null;
263     	
264     	try {
265             String sql = "SELECT DT.APPL_ID FROM KREW_DOC_TYP_T DT, KREW_DOC_HDR_T DH "+
266             	"WHERE DH.DOC_TYP_ID=DT.DOC_TYP_ID AND "+
267             	"DH.DOC_HDR_ID=?";
268         	
269             Query query = entityManager.createNativeQuery(sql);
270             query.setParameter(1, documentId);
271             
272             applicationId = (String)query.getSingleResult();
273     	} catch (EntityNotFoundException enfe) {
274     		throw new WorkflowRuntimeException(enfe.getMessage());
275 		}
276     	
277     	return applicationId;
278     }
279 
280     public String getDocumentStatus(String documentId) {
281     	DocumentRouteHeaderValue document = findRouteHeader(documentId);
282 
283 		return document.getDocRouteStatus();
284     }
285     
286     public String getAppDocId(String documentId) {
287     	Query query = entityManager.createNamedQuery("DocumentRouteHeaderValue.GetAppDocId");
288         query.setParameter("documentId", documentId);
289         return (String) query.getSingleResult(); 
290  	 }
291     
292     public void save(SearchableAttributeValue searchableAttributeValue) {   	
293     	if (searchableAttributeValue.getSearchableAttributeValueId() == null){
294     		entityManager.persist(searchableAttributeValue);
295     	} else {
296     		entityManager.merge(searchableAttributeValue);
297     	}
298     }
299 
300 	public Collection findByDocTypeAndAppId(String documentTypeName,
301 			String appId) {
302     	try {
303             String sql = 
304         	 	"SELECT DISTINCT " +
305         		"    (docHdr.doc_hdr_id) " +
306         		"FROM " +
307         		"    KREW_DOC_HDR_T docHdr, " +
308         		"    KREW_DOC_TYP_T docTyp " +
309         		"WHERE " +
310         		"    docHdr.APP_DOC_ID     = ? " +
311         		"    AND docHdr.DOC_TYP_ID = docTyp.DOC_TYP_ID " +
312         		"    AND docTyp.DOC_TYP_NM = ?";
313         	
314             Query query = entityManager.createNativeQuery(sql);
315             query.setParameter(1, appId);
316             query.setParameter(2, documentTypeName);
317             Collection<Long> idCollection = new ArrayList<Long>();
318             for (Object tempId : query.getResultList()) {
319             	idCollection.add(((BigDecimal)tempId).longValueExact());
320             }
321             return idCollection;
322     	} catch (EntityNotFoundException enfe) {
323     		throw new WorkflowRuntimeException(enfe.getMessage());
324 		}
325 	}
326 
327 
328 }