View Javadoc

1   /**
2    * Copyright 2005-2013 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.engine.node.dao.impl;
17  
18  import java.sql.Connection;
19  import java.sql.PreparedStatement;
20  import java.sql.ResultSet;
21  import java.sql.SQLException;
22  import java.util.ArrayList;
23  import java.util.Iterator;
24  import java.util.List;
25  
26  import javax.persistence.EntityManager;
27  import javax.persistence.PersistenceContext;
28  import javax.persistence.Query;
29  import javax.sql.DataSource;
30  
31  import org.kuali.rice.core.framework.persistence.jpa.OrmUtils;
32  import org.kuali.rice.kew.api.KEWPropertyConstants;
33  import org.kuali.rice.kew.engine.node.Branch;
34  import org.kuali.rice.kew.engine.node.NodeState;
35  import org.kuali.rice.kew.engine.node.RouteNode;
36  import org.kuali.rice.kew.engine.node.RouteNodeInstance;
37  import org.kuali.rice.kew.engine.node.dao.RouteNodeDAO;
38  import org.kuali.rice.kew.service.KEWServiceLocator;
39  import org.kuali.rice.krad.data.DataObjectService;
40  import org.springframework.beans.factory.annotation.Required;
41  import org.springframework.dao.DataAccessException;
42  import org.springframework.jdbc.core.JdbcTemplate;
43  import org.springframework.jdbc.core.PreparedStatementCallback;
44  import org.springframework.jdbc.core.PreparedStatementCreator;
45  
46  public class RouteNodeDAOJpa implements RouteNodeDAO {
47  
48  	@PersistenceContext(unitName="kew")
49  	private EntityManager entityManager;
50      private DataObjectService dataObjectService;
51  	
52      /**
53  	 * @return the entityManager
54  	 */
55  	public EntityManager getEntityManager() {
56  		return this.entityManager;
57  	}
58  
59  	/**
60  	 * @param entityManager the entityManager to set
61  	 */
62  	public void setEntityManager(EntityManager entityManager) {
63  		this.entityManager = entityManager;
64  	}
65  
66      public RouteNodeInstance findRouteNodeInstanceById(String nodeInstanceId) {
67      	Query query = entityManager.createNamedQuery("RouteNodeInstance.FindByRouteNodeInstanceId");
68      	query.setParameter(KEWPropertyConstants.ROUTE_NODE_INSTANCE_ID, nodeInstanceId);
69  
70     	 	return (RouteNodeInstance) query.getSingleResult(); 		
71      }
72  
73      @SuppressWarnings("unchecked")
74      public List<RouteNodeInstance> getActiveNodeInstances(String documentId) {
75      	Query query = entityManager.createNamedQuery("RouteNodeInstance.FindActiveNodeInstances");
76      	query.setParameter(KEWPropertyConstants.DOCUMENT_ID, documentId);
77      	return (List<RouteNodeInstance>)query.getResultList();
78      }
79  
80      private static final String CURRENT_ROUTE_NODE_NAMES_SQL = "SELECT rn.nm" +
81                  " FROM krew_rte_node_t rn," +
82                  "      krew_rte_node_instn_t rni" +
83                  " LEFT JOIN krew_rte_node_instn_lnk_t rnl" +
84                  "   ON rnl.from_rte_node_instn_id = rni.rte_node_instn_id" +
85                  " WHERE rn.rte_node_id = rni.rte_node_id AND" +
86                  "       rni.doc_hdr_id = ? AND" +
87                  "       rnl.from_rte_node_instn_id IS NULL";
88  
89          @Override
90          public List<String> getCurrentRouteNodeNames(final String documentId) {
91              final DataSource dataSource = KEWServiceLocator.getDataSource();
92              JdbcTemplate template = new JdbcTemplate(dataSource);
93              List<String> names = template.execute(new PreparedStatementCreator() {
94                          public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
95                              return connection.prepareStatement(CURRENT_ROUTE_NODE_NAMES_SQL);
96                          }
97                      }, new PreparedStatementCallback<List<String>>() {
98                          public List<String> doInPreparedStatement(
99                                  PreparedStatement statement) throws SQLException, DataAccessException {
100                             List<String> routeNodeNames = new ArrayList<String>();
101                             statement.setString(1, documentId);
102                             ResultSet rs = statement.executeQuery();
103                             try {
104                                 while (rs.next()) {
105                                     String name = rs.getString("nm");
106                                     routeNodeNames.add(name);
107                                 }
108                             } finally {
109                                 if (rs != null) {
110                                     rs.close();
111                                 }
112                             }
113                             return routeNodeNames;
114                         }
115                     }
116             );
117             return names;
118         }
119     
120     @Override
121 	public List<String> getActiveRouteNodeNames(final String documentId) {
122     	final DataSource dataSource = KEWServiceLocator.getDataSource();
123     	JdbcTemplate template = new JdbcTemplate(dataSource);
124     	List<String> names = template.execute(
125 				new PreparedStatementCreator() {
126 					public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
127 						PreparedStatement statement = connection.prepareStatement(
128 								"SELECT rn.nm FROM krew_rte_node_t rn, krew_rte_node_instn_t rni WHERE rn.rte_node_id "
129                                         + "= rni.rte_node_id AND rni.doc_hdr_id = ? AND rni.actv_ind = ?");
130 						return statement;
131 					}
132 				},
133 				new PreparedStatementCallback<List<String>>() {
134 					public List<String> doInPreparedStatement(PreparedStatement statement) throws SQLException, DataAccessException {
135 						List<String> routeNodeNames = new ArrayList<String>();
136 						statement.setString(1, documentId);
137 						statement.setBoolean(2, Boolean.TRUE);
138 						ResultSet rs = statement.executeQuery();
139 						try {
140 							while(rs.next()) {
141 								String name = rs.getString("nm");
142 								routeNodeNames.add(name);
143 							}
144 						} finally {
145 							if(rs != null) {
146 								rs.close();
147 							}
148 						}
149 						return routeNodeNames;
150 					}
151 				});
152     	return names;
153 	}
154 
155     @SuppressWarnings("unchecked")
156     public List<RouteNodeInstance> getTerminalNodeInstances(String documentId) {
157     	Query query = entityManager.createNamedQuery("RouteNodeInstance.FindTerminalNodeInstances");
158     	query.setParameter(KEWPropertyConstants.DOCUMENT_ID, documentId);
159 		
160 		//FIXME: Can we do this better using just the JPQL query?  
161 		List<RouteNodeInstance> terminalNodes = new ArrayList<RouteNodeInstance>();
162 		List<RouteNodeInstance> routeNodeInstances = (List<RouteNodeInstance>) query.getResultList();
163 		for (RouteNodeInstance routeNodeInstance : routeNodeInstances) {
164 		    if (routeNodeInstance.getNextNodeInstances().isEmpty()) {
165 		    	terminalNodes.add(routeNodeInstance);
166 		    }
167 		}
168 		return terminalNodes;
169     }
170 
171     @Override
172     public List<String> getTerminalRouteNodeNames(final String documentId) {
173         final DataSource dataSource = KEWServiceLocator.getDataSource();
174         JdbcTemplate template = new JdbcTemplate(dataSource);
175         List<String> names = template.execute(new PreparedStatementCreator() {
176                     public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
177                         PreparedStatement statement = connection.prepareStatement("SELECT rn.nm" +
178                                 "  FROM krew_rte_node_t rn," +
179                                 "       krew_rte_node_instn_t rni" +
180                                 "  LEFT JOIN krew_rte_node_instn_lnk_t rnl" +
181                                 "    ON rnl.from_rte_node_instn_id = rni.rte_node_instn_id" +
182                                 "  WHERE rn.rte_node_id = rni.rte_node_id AND" +
183                                 "        rni.doc_hdr_id = ? AND" +
184                                 "        rni.actv_ind = ? AND" +
185                                 "        rni.cmplt_ind = ? AND" +
186                                 "        rnl.from_rte_node_instn_id IS NULL");
187                         return statement;
188                     }
189                 }, new PreparedStatementCallback<List<String>>() {
190                     public List<String> doInPreparedStatement(
191                             PreparedStatement statement) throws SQLException, DataAccessException {
192                         List<String> routeNodeNames = new ArrayList<String>();
193                         statement.setString(1, documentId);
194                         statement.setBoolean(2, Boolean.FALSE);
195                         statement.setBoolean(3, Boolean.TRUE);
196                         ResultSet rs = statement.executeQuery();
197                         try {
198                             while (rs.next()) {
199                                 String name = rs.getString("nm");
200                                 routeNodeNames.add(name);
201                             }
202                         } finally {
203                             if (rs != null) {
204                                 rs.close();
205                             }
206                         }
207                         return routeNodeNames;
208                     }
209                 }
210         );
211         return names;
212     }
213 
214     public List getInitialNodeInstances(String documentId) {
215     	//FIXME: Not sure this query is returning what it needs to     	                                              
216     	Query query = entityManager.createNamedQuery("RouteNodeInstance.FindInitialNodeInstances");
217     	query.setParameter(KEWPropertyConstants.DOCUMENT_ID, documentId);
218 		return (List)query.getResultList();
219     }
220 
221     public NodeState findNodeState(Long nodeInstanceId, String key) {
222     	Query query = entityManager.createNamedQuery("NodeState.FindNodeState");
223     	query.setParameter(KEWPropertyConstants.ROUTE_NODE_INSTANCE_ID, nodeInstanceId.toString());
224     	query.setParameter(KEWPropertyConstants.KEY, key);
225 		return (NodeState) query.getSingleResult();
226     }
227 
228     public RouteNode findRouteNodeByName(String documentTypeId, String name) {
229     	Query query = entityManager.createNamedQuery("RouteNode.FindRouteNodeByName");
230     	query.setParameter(KEWPropertyConstants.DOCUMENT_TYPE_ID, documentTypeId);
231     	query.setParameter(KEWPropertyConstants.ROUTE_NODE_NAME, name);
232 		return (RouteNode)query.getSingleResult();    	
233     }
234 
235     public List<RouteNode> findFinalApprovalRouteNodes(String documentTypeId) {
236     	Query query = entityManager.createNamedQuery("RouteNode.FindApprovalRouteNodes");
237     	query.setParameter(KEWPropertyConstants.DOCUMENT_TYPE_ID, documentTypeId);
238     	query.setParameter(KEWPropertyConstants.FINAL_APPROVAL, Boolean.TRUE);
239     	return new ArrayList<RouteNode>(query.getResultList());
240     }
241 
242     public List findProcessNodeInstances(RouteNodeInstance process) {
243     	Query query = entityManager.createNamedQuery("RouteNodeInstance.FindProcessNodeInstances");
244     	query.setParameter(KEWPropertyConstants.PROCESS_ID, process.getRouteNodeInstanceId());
245     	return (List) query.getResultList();
246     }
247 
248     public List findRouteNodeInstances(String documentId) {
249     	Query query = entityManager.createNamedQuery("RouteNodeInstance.FindRouteNodeInstances");
250     	query.setParameter(KEWPropertyConstants.DOCUMENT_ID, documentId);
251     	return (List) query.getResultList();
252     }
253 
254     public void deleteLinksToPreNodeInstances(RouteNodeInstance routeNodeInstance) {
255 		List<RouteNodeInstance> preNodeInstances = routeNodeInstance.getPreviousNodeInstances();
256 		for (Iterator<RouteNodeInstance> preNodeInstanceIter = preNodeInstances.iterator(); preNodeInstanceIter.hasNext();) {
257 		    RouteNodeInstance preNodeInstance = (RouteNodeInstance) preNodeInstanceIter.next();
258 		    List<RouteNodeInstance> nextInstances = preNodeInstance.getNextNodeInstances();
259 		    nextInstances.remove(routeNodeInstance);
260 		    entityManager.merge(preNodeInstance);
261 		}
262     }
263 
264     public void deleteRouteNodeInstancesHereAfter(RouteNodeInstance routeNodeInstance) {
265     	RouteNodeInstance rnInstance = findRouteNodeInstanceById(routeNodeInstance.getRouteNodeInstanceId());
266     	entityManager.remove(rnInstance);
267     }
268 
269     public void deleteNodeStateById(Long nodeStateId) {
270     	Query query = entityManager.createNamedQuery("RouteNode.FindNodeStateById");
271     	query.setParameter(KEWPropertyConstants.ROUTE_NODE_STATE_ID, nodeStateId);
272     	NodeState nodeState = (NodeState) query.getSingleResult();
273     	entityManager.remove(nodeState);
274     }
275 
276     public void deleteNodeStates(List statesToBeDeleted) {
277 		for (Iterator stateToBeDeletedIter = statesToBeDeleted.iterator(); stateToBeDeletedIter.hasNext();) {
278 		    Long stateId = (Long) stateToBeDeletedIter.next();
279 		    deleteNodeStateById(stateId);
280 		}
281     }
282 
283 
284     public DataObjectService getDataObjectService() {
285         return dataObjectService;
286     }
287 
288     @Required
289     public void setDataObjectService(DataObjectService dataObjectService) {
290         this.dataObjectService = dataObjectService;
291     }
292 
293 
294 }