View Javadoc

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