View Javadoc

1   /*
2    * Copyright 2005-2007 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.engine.node;
18  
19  import java.io.Serializable;
20  import java.util.ArrayList;
21  import java.util.Iterator;
22  import java.util.List;
23  
24  import javax.persistence.CascadeType;
25  import javax.persistence.Column;
26  import javax.persistence.Entity;
27  import javax.persistence.FetchType;
28  import javax.persistence.GeneratedValue;
29  import javax.persistence.Id;
30  import javax.persistence.JoinColumn;
31  import javax.persistence.JoinTable;
32  import javax.persistence.ManyToMany;
33  import javax.persistence.ManyToOne;
34  import javax.persistence.NamedQueries;
35  import javax.persistence.NamedQuery;
36  import javax.persistence.OneToMany;
37  import javax.persistence.OneToOne;
38  import javax.persistence.Table;
39  import javax.persistence.Version;
40  
41  import org.apache.commons.lang.builder.ToStringBuilder;
42  import org.hibernate.annotations.Fetch;
43  import org.hibernate.annotations.FetchMode;
44  import org.hibernate.annotations.GenericGenerator;
45  import org.hibernate.annotations.Parameter;
46  import org.kuali.rice.core.framework.persistence.jpa.OrmUtils;
47  import org.kuali.rice.kew.api.document.node.RouteNodeInstanceState;
48  import org.kuali.rice.kew.doctype.bo.DocumentType;
49  import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
50  import org.kuali.rice.kew.service.KEWServiceLocator;
51  
52  
53  /**
54   * Represents a materialized instance of a {@link RouteNode} definition on a {@link DocumentRouteHeaderValue}.  Node instances
55   * are generated by the engine using the {@link RouteNode} as a prototype and connected as a 
56   * Directed Acyclic Graph.
57   *
58   * @author Kuali Rice Team (rice.collab@kuali.org)
59   */
60  @Entity
61  @Table(name="KREW_RTE_NODE_INSTN_T")
62  //@Sequence(name="KREW_RTE_NODE_S",property="routeNodeInstanceId")
63  @NamedQueries({
64  	@NamedQuery(name="RouteNodeInstance.FindByRouteNodeInstanceId",query="select r from RouteNodeInstance r where r.routeNodeInstanceId = :routeNodeInstanceId"),
65  	@NamedQuery(name="RouteNodeInstance.FindActiveNodeInstances",query="select r from RouteNodeInstance r where r.documentId = :documentId and r.active = true"),
66  	@NamedQuery(name="RouteNodeInstance.FindTerminalNodeInstances",query="select r from RouteNodeInstance r where r.documentId = :documentId and r.active = false and r.complete = true"),
67  	@NamedQuery(name="RouteNodeInstance.FindInitialNodeInstances",query="select d.initialRouteNodeInstances from DocumentRouteHeaderValue d where d.documentId = :documentId"),
68  	@NamedQuery(name="RouteNodeInstance.FindProcessNodeInstances", query="select r from RouteNodeInstance r where r.process.routeNodeInstanceId = :processId"),
69  	@NamedQuery(name="RouteNodeInstance.FindRouteNodeInstances", query="select r from RouteNodeInstance r where r.documentId = :documentId")
70  })
71  public class RouteNodeInstance implements Serializable {
72      
73  	private static final long serialVersionUID = 7183670062805580420L;
74  	
75  	@Id
76  	@GeneratedValue(generator="KREW_RTE_NODE_S")
77  	@GenericGenerator(name="KREW_RTE_NODE_S",strategy="org.hibernate.id.enhanced.SequenceStyleGenerator",parameters={
78  			@Parameter(name="sequence_name",value="KREW_RTE_NODE_S"),
79  			@Parameter(name="value_column",value="id")
80  	})
81  	@Column(name="RTE_NODE_INSTN_ID")
82  	private String routeNodeInstanceId;
83      @Column(name="DOC_HDR_ID")
84  	private String documentId;
85      @ManyToOne(cascade={CascadeType.PERSIST, CascadeType.MERGE})
86  	@JoinColumn(name="BRCH_ID")
87  	private Branch branch;
88      @OneToOne(fetch=FetchType.EAGER)
89  	@JoinColumn(name="RTE_NODE_ID")
90      private RouteNode routeNode;
91      @Column(name="ACTV_IND")
92      private boolean active = false;
93      @Column(name="CMPLT_IND")
94      private boolean complete = false;
95      @Column(name="INIT_IND")
96      private boolean initial = true;
97      @OneToOne(fetch=FetchType.EAGER,cascade={CascadeType.PERSIST, CascadeType.MERGE})
98  	@JoinColumn(name="PROC_RTE_NODE_INSTN_ID")
99  	private RouteNodeInstance process;
100     
101     @ManyToMany(fetch=FetchType.EAGER,cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})
102     @JoinTable(name = "KREW_RTE_NODE_INSTN_LNK_T", joinColumns = @JoinColumn(name = "FROM_RTE_NODE_INSTN_ID"), inverseJoinColumns = @JoinColumn(name = "TO_RTE_NODE_INSTN_ID"))
103     @Fetch(value = FetchMode.SELECT)
104     private List<RouteNodeInstance> nextNodeInstances = new ArrayList<RouteNodeInstance>();
105     
106     @ManyToMany(fetch=FetchType.EAGER, mappedBy="nextNodeInstances")
107     @Fetch(value = FetchMode.SELECT)
108     //@JoinTable(name = "KREW_RTE_NODE_INSTN_LNK_T", joinColumns = @JoinColumn(name = "TO_RTE_NODE_INSTN_ID"), inverseJoinColumns = @JoinColumn(name = "FROM_RTE_NODE_INSTN_ID"))
109     private List<RouteNodeInstance> previousNodeInstances = new ArrayList<RouteNodeInstance>();
110 
111     @OneToMany(fetch=FetchType.EAGER,cascade={CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.MERGE}, mappedBy="nodeInstance", orphanRemoval=true)    
112     @Fetch(value = FetchMode.SELECT)
113     private List<NodeState> state = new ArrayList<NodeState>();
114     	
115     @Version
116 	@Column(name="VER_NBR")
117 	private Integer lockVerNbr;
118     
119     public boolean isActive() {
120         return active;
121     }
122     public void setActive(boolean active) {
123         this.active = active;
124     }
125     
126     public boolean isComplete() {
127         return complete;
128     }
129     public void setComplete(boolean complete) {
130         this.complete = complete;
131     }
132     public Branch getBranch() {
133         return branch;
134     }
135     public void setBranch(Branch branch) {
136         this.branch = branch;
137     }
138     public RouteNode getRouteNode() {
139         return routeNode;
140     }
141     public void setRouteNode(RouteNode node) {
142         this.routeNode = node;
143     }
144     public String getRouteNodeInstanceId() {
145         return routeNodeInstanceId;
146     }
147     public void setRouteNodeInstanceId(String routeNodeInstanceId) {
148         this.routeNodeInstanceId = routeNodeInstanceId;
149     }
150     public String getDocumentId() {
151         return documentId;
152     }
153     public void setDocumentId(String documentId) {
154         this.documentId = documentId;
155     }
156     public List<RouteNodeInstance> getNextNodeInstances() {
157         return nextNodeInstances;
158     }
159     public RouteNodeInstance getNextNodeInstance(int index) {
160     	while (getNextNodeInstances().size() <= index) {
161     		nextNodeInstances.add(new RouteNodeInstance());
162     	}
163     	return (RouteNodeInstance) getNextNodeInstances().get(index);
164     }
165     public void setNextNodeInstances(List<RouteNodeInstance> nextNodeInstances) {
166         this.nextNodeInstances = nextNodeInstances;
167     }
168     public List<RouteNodeInstance> getPreviousNodeInstances() {
169         return previousNodeInstances;
170     }
171     public RouteNodeInstance getPreviousNodeInstance(int index) {
172     	while (previousNodeInstances.size() <= index) {
173     		previousNodeInstances.add(new RouteNodeInstance());
174     	}
175     	return (RouteNodeInstance) getPreviousNodeInstances().get(index);
176     }
177     public void setPreviousNodeInstances(List<RouteNodeInstance> previousNodeInstances) {
178         this.previousNodeInstances = previousNodeInstances;
179     }
180     public boolean isInitial() {
181         return initial;
182     }
183     public void setInitial(boolean initial) {
184         this.initial = initial;
185     }
186     public List<NodeState> getState() {
187         return state;
188     }
189     public void setState(List<NodeState> state) {
190         this.state.clear();
191     	this.state.addAll(state);
192         //this.state = state;
193     }
194     public RouteNodeInstance getProcess() {
195 		return process;
196 	}
197 	public void setProcess(RouteNodeInstance process) {
198 		this.process = process;
199 	}
200 	public Integer getLockVerNbr() {
201         return lockVerNbr;
202     }
203     public void setLockVerNbr(Integer lockVerNbr) {
204         this.lockVerNbr = lockVerNbr;
205     }
206     
207     public NodeState getNodeState(String key) {
208         for (Iterator iter = getState().iterator(); iter.hasNext();) {
209             NodeState nodeState = (NodeState) iter.next();
210             if (nodeState.getKey().equals(key)) {
211                 return nodeState;
212             }
213         }
214         return null;
215     }
216     
217     public void addNodeState(NodeState state) {
218         this.state.add(state);
219         state.setNodeInstance(this);
220     }
221     
222     public void removeNodeState(String key) {
223         for (Iterator iter = getState().iterator(); iter.hasNext();) {
224             NodeState nodeState = (NodeState) iter.next();
225             if (nodeState.getKey().equals(key)) {
226                 iter.remove();
227                 break;
228             }
229         }
230     }
231     
232     public void addNextNodeInstance(RouteNodeInstance nextNodeInstance) {
233         nextNodeInstances.add(nextNodeInstance);
234         nextNodeInstance.getPreviousNodeInstances().add(this);
235     }
236     
237     public void removeNextNodeInstance(RouteNodeInstance nextNodeInstance) {
238         nextNodeInstances.remove(nextNodeInstance);
239         nextNodeInstance.getPreviousNodeInstances().remove(this);
240     }
241     
242     public void clearNextNodeInstances() {
243         for (Iterator iterator = nextNodeInstances.iterator(); iterator.hasNext();) {
244             RouteNodeInstance nextNodeInstance = (RouteNodeInstance) iterator.next();
245             iterator.remove();
246             nextNodeInstance.getPreviousNodeInstances().remove(this);
247         }
248     }
249     
250     public String getName() {
251         return (getRouteNode() == null ? null : getRouteNode().getRouteNodeName());
252     }
253     
254     public boolean isInProcess() {
255         return getProcess() != null;
256     }
257     
258     public DocumentType getDocumentType() {
259         return KEWServiceLocator.getDocumentTypeService().findByDocumentId(getDocumentId());
260     }
261     
262     /*
263      * methods used to display route node instances' data on documentoperation.jsp
264      */
265     
266     public NodeState getNodeStateByIndex(int index){
267     	while (state.size() <= index) {
268             state.add(new NodeState());
269         }
270         return (NodeState) getState().get(index);
271     }   
272 
273     public void populateState(List<NodeState> state) {
274         this.state.addAll(state);
275      }
276 
277     public String toString() {
278         return new ToStringBuilder(this)
279             .append("routeNodeInstanceId", routeNodeInstanceId)
280             .append("documentId", documentId)
281             .append("branch", branch == null ? null : branch.getBranchId())
282             .append("routeNode", routeNode == null ? null : routeNode.getRouteNodeName())
283             .append("active", active)
284             .append("complete", complete)
285             .append("initial", initial)
286             .append("process", process)
287             .append("nextNodeInstances", nextNodeInstances == null ? null : nextNodeInstances.size())
288             .append("previousNodeInstances", previousNodeInstances == null ? null : previousNodeInstances.size())
289             .append("state", state == null ? null : state.size())
290             .toString();
291     }
292     
293 	//@PrePersist
294 	public void beforeInsert(){
295 		OrmUtils.populateAutoIncValue(this, KEWServiceLocator.getEntityManagerFactory().createEntityManager());
296 	}
297 
298 
299 	public static org.kuali.rice.kew.api.document.node.RouteNodeInstance to(RouteNodeInstance routeNodeInstance) {
300 		if (routeNodeInstance == null) {
301 			return null;
302 		}
303 		org.kuali.rice.kew.api.document.node.RouteNodeInstance.Builder builder = org.kuali.rice.kew.api.document.node
304                 .RouteNodeInstance.Builder.create();
305 		builder.setActive(routeNodeInstance.isActive());
306 		builder.setBranchId(routeNodeInstance.getBranch().getBranchId());
307 		builder.setComplete(routeNodeInstance.isComplete());
308 		builder.setDocumentId(routeNodeInstance.getDocumentId());
309 		builder.setId(routeNodeInstance.getRouteNodeInstanceId());
310 		builder.setInitial(routeNodeInstance.isInitial());
311 		builder.setName(routeNodeInstance.getName());
312 		if (routeNodeInstance.getProcess() != null) {
313 			builder.setProcessId(routeNodeInstance.getProcess().getRouteNodeInstanceId());
314 		}
315 		builder.setRouteNodeId(routeNodeInstance.getRouteNode().getRouteNodeId());
316 		List<RouteNodeInstanceState.Builder> states = new ArrayList<RouteNodeInstanceState.Builder>();
317 		for (NodeState stateBo : routeNodeInstance.getState()) {
318 			RouteNodeInstanceState.Builder stateBuilder = RouteNodeInstanceState.Builder.create();
319 			stateBuilder.setId(stateBo.getStateId());
320 			stateBuilder.setKey(stateBo.getKey());
321 			stateBuilder.setValue(stateBo.getValue());
322 			states.add(stateBuilder);
323 		}
324 		builder.setState(states);
325 
326         List<org.kuali.rice.kew.api.document.node.RouteNodeInstance.Builder> nextNodes = new ArrayList<org.kuali.rice.kew.api.document.node.RouteNodeInstance.Builder>();
327         if (routeNodeInstance.getNextNodeInstances() != null) {
328             for (RouteNodeInstance next : routeNodeInstance.getNextNodeInstances()) {
329                 // will this make things blow up?
330                 nextNodes.add(org.kuali.rice.kew.api.document.node.RouteNodeInstance.Builder.create(RouteNodeInstance.to(next)));
331             }
332         }
333         builder.setNextNodeInstances(nextNodes);
334 
335 		return builder.build();
336 
337 
338 
339 	}
340     
341 }
342