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.actionrequest.dao.impl;
017
018import java.io.Serializable;
019import java.sql.Timestamp;
020import java.util.Collection;
021import java.util.Collections;
022import java.util.List;
023
024import javax.persistence.EntityManager;
025import javax.persistence.PersistenceContext;
026import javax.persistence.Query;
027
028import org.apache.commons.lang.StringUtils;
029import org.kuali.rice.core.framework.persistence.jpa.OrmUtils;
030import org.kuali.rice.kew.actionrequest.ActionRequestValue;
031import org.kuali.rice.kew.actionrequest.dao.ActionRequestDAO;
032import org.kuali.rice.kew.api.action.ActionRequestStatus;
033import org.kuali.rice.kew.api.action.RecipientType;
034import org.kuali.rice.kew.api.KewApiConstants;
035import org.kuali.rice.kim.api.group.Group;
036
037/**
038 * This is a description of what this class does - sgibson don't forget to fill this in.
039 * 
040 * @author Kuali Rice Team (rice.collab@kuali.org)
041 */
042public class ActionRequestDAOJpaImpl implements ActionRequestDAO {
043    
044    @PersistenceContext(name = "kew-unit")
045    private EntityManager entityManager;
046
047    /**
048         * @return the entityManager
049         */
050        public EntityManager getEntityManager() {
051                return this.entityManager;
052        }
053
054        /**
055         * @param entityManager the entityManager to set
056         */
057        public void setEntityManager(EntityManager entityManager) {
058                this.entityManager = entityManager;
059        }
060
061        public void delete(String actionRequestId) {
062        ActionRequestValue actionRequestValue = (ActionRequestValue) entityManager.find(ActionRequestValue.class, actionRequestId);
063        entityManager.remove(actionRequestValue);
064    }
065
066    public void deleteByDocumentId(String documentId) {
067        // FIXME should be jpa bulk update?
068        Query query = entityManager.createNamedQuery("ActionRequestValue.FindByDocumentId");
069        query.setParameter("documentId", documentId);
070        List<ActionRequestValue> actionRequestValues = (List<ActionRequestValue>) query.getSingleResult();
071        for(ActionRequestValue arv : actionRequestValues) {
072            entityManager.remove(arv);
073        }
074    }
075
076    public boolean doesDocumentHaveUserRequest(String principalId, String documentId) {
077        Query query = entityManager.createNamedQuery("ActionRequestValue.GetUserRequestCount");
078        query.setParameter("principalId", principalId);
079        query.setParameter("documentId", documentId);
080        query.setParameter("recipientTypeCd", RecipientType.PRINCIPAL.getCode());
081        query.setParameter("currentIndicator", Boolean.TRUE);
082        
083        return ((Long)query.getSingleResult()) > 0;
084    }
085
086    public List<?> findActivatedByGroup(Group group) {
087        
088        Query query = entityManager.createNamedQuery("ActionRequestValue.FindActivatedByGroup");
089        query.setParameter("groupId", group.getId());
090        query.setParameter("currentIndicator", Boolean.TRUE);
091        query.setParameter("status", ActionRequestStatus.ACTIVATED.getCode());
092        
093        return query.getResultList();
094    }
095
096    public List<ActionRequestValue> findAllByDocId(String documentId) {
097        Query query = entityManager.createNamedQuery("ActionRequestValue.FindAllByDocId");
098        query.setParameter("documentId", documentId);
099        query.setParameter("currentIndicator", Boolean.TRUE);
100        
101        return query.getResultList();
102    }
103
104    public List<ActionRequestValue> findAllPendingByDocId(String documentId) {
105        Query query = entityManager.createNamedQuery("ActionRequestValue.FindAllPendingByDocId");
106        query.setParameter("documentId", documentId);
107        query.setParameter("currentIndicator", Boolean.TRUE);
108        query.setParameter("actionRequestStatus1", ActionRequestStatus.INITIALIZED.getCode());
109        query.setParameter("actionRequestStatus2", ActionRequestStatus.ACTIVATED.getCode());
110        
111        return query.getResultList();
112    }
113
114    @SuppressWarnings("unchecked")
115    public List<ActionRequestValue> findAllRootByDocId(String documentId) {
116        Query query = entityManager.createNamedQuery("ActionRequestValue.FindAllRootByDocId");
117        query.setParameter("documentId", documentId);
118        query.setParameter("currentIndicator", Boolean.TRUE);
119        
120        return (List<ActionRequestValue>) query.getResultList();
121    }
122
123    public List<ActionRequestValue> findByDocumentIdIgnoreCurrentInd(String documentId) {
124        Query query = entityManager.createNamedQuery("ActionRequestValue.FindByDocumentId");
125        query.setParameter("documentId", documentId);
126        
127        return query.getResultList();
128    }
129
130    @SuppressWarnings("unchecked")
131    public List<ActionRequestValue> findByStatusAndDocId(String statusCd, String documentId) {
132        Query query = entityManager.createNamedQuery("ActionRequestValue.FindByStatusAndDocId");
133        query.setParameter("documentId", documentId);
134        query.setParameter("status", statusCd);
135        query.setParameter("currentIndicator", Boolean.TRUE);
136        
137        return (List<ActionRequestValue>)query.getResultList();
138    }
139
140    public List<ActionRequestValue> findPendingByActionRequestedAndDocId(String actionRequestedCd, String documentId) {
141        Query query = entityManager.createNamedQuery("ActionRequestValue.FindPendingByActionRequestedAndDocId");
142        query.setParameter("documentId", documentId);
143        query.setParameter("currentIndicator", Boolean.TRUE);
144        query.setParameter("actionRequested", actionRequestedCd);
145        query.setParameter("actionRequestStatus1", ActionRequestStatus.INITIALIZED.getCode());
146        query.setParameter("actionRequestStatus2", ActionRequestStatus.ACTIVATED.getCode());
147        
148        return query.getResultList();
149    }
150
151    public List<ActionRequestValue> findPendingByDocIdAtOrBelowRouteLevel(String documentId, Integer routeLevel) {
152        Query query = entityManager.createNamedQuery("ActionRequestValue.FindPendingByDocIdAtOrBelowRouteLevel");
153        query.setParameter("documentId", documentId);
154        query.setParameter("currentIndicator", Boolean.TRUE);
155        query.setParameter("routeLevel", routeLevel);
156        query.setParameter("status", ActionRequestStatus.DONE.getCode());
157        
158        return query.getResultList();
159    }
160
161    public List<ActionRequestValue> findPendingByResponsibilityIds(Collection responsibilityIds) {
162        if (responsibilityIds == null || responsibilityIds.size() == 0)
163            return Collections.emptyList();
164
165        Query query = entityManager.createNamedQuery("ActionRequestValue.FindPendingByDocIdAtOrBelowRouteLevel");
166        query.setParameter("responsibilityIds", responsibilityIds);
167        
168        return query.getResultList();
169    }
170
171    public List<ActionRequestValue> findPendingRootRequestsByDocIdAtOrBelowRouteLevel(String documentId, Integer routeLevel) {
172        Query query = entityManager.createNamedQuery("ActionRequestValue.FindPendingRootRequestsByDocIdAtOrBelowRouteLevel");
173        query.setParameter("documentId", documentId);
174        query.setParameter("currentIndicator", Boolean.TRUE);
175        query.setParameter("status", ActionRequestStatus.DONE.getCode());
176        query.setParameter("routeLevel", routeLevel);
177        
178        return query.getResultList();
179    }
180
181    public List<ActionRequestValue> findPendingRootRequestsByDocIdAtRouteLevel(String documentId, Integer routeLevel) {
182        Query query = entityManager.createNamedQuery("ActionRequestValue.FindPendingRootRequestsByDocIdAtRouteLevel");
183        query.setParameter("documentId", documentId);
184        query.setParameter("currentIndicator", Boolean.TRUE);
185        query.setParameter("status", ActionRequestStatus.DONE.getCode());
186        query.setParameter("routeLevel", routeLevel);
187        
188        return query.getResultList();
189    }
190
191    public List<ActionRequestValue> findPendingRootRequestsByDocIdAtRouteNode(String documentId, String nodeInstanceId) {
192        Query query = entityManager.createNamedQuery("ActionRequestValue.FindPendingRootRequestsByDocIdAtRouteNode");
193        query.setParameter("documentId", documentId);
194        query.setParameter("currentIndicator", Boolean.TRUE);
195        query.setParameter("routeNodeInstanceId", nodeInstanceId);
196        query.setParameter("actionRequestStatus1", ActionRequestStatus.INITIALIZED.getCode());
197        query.setParameter("actionRequestStatus2", ActionRequestStatus.ACTIVATED.getCode());
198        
199        return query.getResultList();
200    }
201
202    public List<ActionRequestValue> findPendingRootRequestsByDocumentType(String documentTypeId) {
203        Query query = entityManager.createNamedQuery("ActionRequestValue.FindPendingRootRequestsByDocumentType");
204        query.setParameter("documentTypeId", documentTypeId);
205        query.setParameter("currentIndicator", Boolean.TRUE);
206        query.setParameter("actionRequestStatus1", ActionRequestStatus.INITIALIZED.getCode());
207        query.setParameter("actionRequestStatus2", ActionRequestStatus.ACTIVATED.getCode());
208        
209        return query.getResultList();
210    }
211
212    public List<ActionRequestValue> findRootRequestsByDocIdAtRouteNode(String documentId, String nodeInstanceId) {
213        Query query = entityManager.createNamedQuery("ActionRequestValue.FindRootRequestsByDocIdAtRouteNode");
214        query.setParameter("documentId", documentId);
215        query.setParameter("currentIndicator", Boolean.TRUE);
216        query.setParameter("routeNodeInstanceId", nodeInstanceId);
217        
218        return query.getResultList();
219    }
220
221    public ActionRequestValue getActionRequestByActionRequestId(String actionRequestId) {
222        return entityManager.find(ActionRequestValue.class, actionRequestId);
223    }
224
225    @SuppressWarnings("unchecked")
226    public List<String> getRequestGroupIds(String documentId) {
227        Query query = entityManager.createNamedQuery("ActionRequestValue.GetRequestGroupIds");
228        query.setParameter("documentId", documentId);
229        query.setParameter("currentIndicator", Boolean.TRUE);
230        query.setParameter("recipientTypeCd", RecipientType.GROUP.getCode());
231        
232        return query.getResultList();
233    }
234
235    public void saveActionRequest(ActionRequestValue actionRequest) {
236        if ( actionRequest.getAnnotation() != null && actionRequest.getAnnotation().length() > 2000 ) {
237                actionRequest.setAnnotation( StringUtils.abbreviate(actionRequest.getAnnotation(), 2000) );
238        }
239        if(actionRequest.getActionRequestId() == null) {
240                loadDefaultValues(actionRequest);
241                entityManager.persist(actionRequest);
242        }else{
243            OrmUtils.merge(entityManager, actionRequest);
244        }
245    }
246    private void loadDefaultValues(ActionRequestValue actionRequest) {
247        checkNull(actionRequest.getActionRequested(), "action requested");
248        checkNull(actionRequest.getResponsibilityId(), "responsibility ID");
249        checkNull(actionRequest.getRouteLevel(), "route level");
250        checkNull(actionRequest.getDocVersion(), "doc version");
251        if (actionRequest.getForceAction() == null) {
252            actionRequest.setForceAction(Boolean.FALSE);
253        }
254        if (actionRequest.getStatus() == null) {
255            actionRequest.setStatus(ActionRequestStatus.INITIALIZED.getCode());
256        }
257        if (actionRequest.getPriority() == null) {
258            actionRequest.setPriority(KewApiConstants.ACTION_REQUEST_DEFAULT_PRIORITY);
259        }
260        if (actionRequest.getCurrentIndicator() == null) {
261            actionRequest.setCurrentIndicator(true);
262        }
263        actionRequest.setCreateDate(new Timestamp(System.currentTimeMillis()));
264    }
265    //TODO Runtime might not be the right thing to do here...
266    private void checkNull(Serializable value, String valueName) throws RuntimeException {
267        if (value == null) {
268            throw new RuntimeException("Null value for " + valueName);
269        }
270    }
271    
272        public List<ActionRequestValue> findActivatedByGroup(String groupId) {
273                Query query = entityManager.createNamedQuery("ActionRequestValue.FindByStatusAndGroupId");
274        query.setParameter("status", ActionRequestStatus.ACTIVATED.getCode());
275        query.setParameter("currentIndicator", Boolean.TRUE);
276        query.setParameter("groupId", groupId);
277        
278        return query.getResultList();
279        }
280
281    @Override
282    public ActionRequestValue getRoleActionRequestByActionTakenId(String actionTakenId) {
283        throw new UnsupportedOperationException("not yet implemented");
284    }
285}