1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kew.engine.node;
17
18 import java.io.Serializable;
19 import java.util.ArrayList;
20 import java.util.List;
21 import java.util.Map;
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.Transient;
39 import javax.persistence.Version;
40
41 import org.apache.commons.lang.StringUtils;
42 import org.apache.log4j.Logger;
43 import org.hibernate.annotations.Fetch;
44 import org.hibernate.annotations.FetchMode;
45 import org.hibernate.annotations.GenericGenerator;
46 import org.hibernate.annotations.Parameter;
47 import org.kuali.rice.core.framework.persistence.jpa.OrmUtils;
48 import org.kuali.rice.kew.api.doctype.RouteNodeConfigurationParameterContract;
49 import org.kuali.rice.kew.api.doctype.RouteNodeContract;
50 import org.kuali.rice.kew.api.exception.ResourceUnavailableException;
51 import org.kuali.rice.kew.doctype.bo.DocumentType;
52 import org.kuali.rice.kew.rule.bo.RuleTemplateBo;
53 import org.kuali.rice.kew.rule.service.RuleTemplateService;
54 import org.kuali.rice.kew.service.KEWServiceLocator;
55 import org.kuali.rice.kew.api.KewApiConstants;
56 import org.kuali.rice.kew.util.Utilities;
57 import org.kuali.rice.kim.api.group.Group;
58 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
59
60
61
62
63
64
65 @Entity
66 @Table(name="KREW_RTE_NODE_T")
67
68 @NamedQueries({
69 @NamedQuery(name="RouteNode.FindByRouteNodeId",query="select r from RouteNode as r where r.routeNodeId = :routeNodeId"),
70 @NamedQuery(name="RouteNode.FindRouteNodeByName", query="select r from RouteNode as r where r.routeNodeName = :routeNodeName and r.documentTypeId = :documentTypeId"),
71 @NamedQuery(name="RouteNode.FindApprovalRouteNodes", query="select r from RouteNode as r where r.documentTypeId = :documentTypeId and r.finalApprovalInd = :finalApprovalInd")
72 })
73 public class RouteNode implements Serializable, RouteNodeContract {
74
75 private static final long serialVersionUID = 4891233177051752726L;
76
77 public static final String CONTENT_FRAGMENT_CFG_KEY = "contentFragment";
78 public static final String RULE_SELECTOR_CFG_KEY = "ruleSelector";
79
80 @Id
81 @GeneratedValue(generator="KREW_RTE_NODE_S")
82 @GenericGenerator(name="KREW_RTE_NODE_S",strategy="org.hibernate.id.enhanced.SequenceStyleGenerator",parameters={
83 @Parameter(name="sequence_name",value="KREW_RTE_NODE_S"),
84 @Parameter(name="value_column",value="id")
85 })
86 @Column(name="RTE_NODE_ID")
87 private String routeNodeId;
88 @Column(name="DOC_TYP_ID",insertable=false, updatable=false)
89 private String documentTypeId;
90 @Column(name="NM")
91 private String routeNodeName;
92 @Column(name="RTE_MTHD_NM")
93 private String routeMethodName;
94 @Column(name="FNL_APRVR_IND")
95 private Boolean finalApprovalInd;
96 @Column(name="MNDTRY_RTE_IND")
97 private Boolean mandatoryRouteInd;
98 @Column(name="GRP_ID")
99 private String exceptionWorkgroupId;
100 @Column(name="RTE_MTHD_CD")
101 private String routeMethodCode;
102 @Column(name="ACTVN_TYP")
103 private String activationType = ActivationTypeEnum.PARALLEL.getCode();
104
105
106
107
108
109 @Column(name="NEXT_DOC_STAT")
110 private String nextDocStatus;
111
112 @Version
113 @Column(name="VER_NBR")
114 private Integer lockVerNbr;
115 @ManyToOne(fetch=FetchType.EAGER)
116 @JoinColumn(name="DOC_TYP_ID")
117 private DocumentType documentType;
118 @Transient
119 private String exceptionWorkgroupName;
120
121 @Transient
122 private RuleTemplateBo ruleTemplate;
123 @Column(name="TYP")
124 private String nodeType = RequestsNode.class.getName();
125
126
127 @ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST}, mappedBy="nextNodes")
128 @Fetch(value = FetchMode.SELECT)
129
130 private List<RouteNode> previousNodes = new ArrayList<RouteNode>();
131
132 @ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST})
133 @Fetch(value = FetchMode.SELECT)
134 @JoinTable(name = "KREW_RTE_NODE_LNK_T", joinColumns = @JoinColumn(name = "FROM_RTE_NODE_ID"), inverseJoinColumns = @JoinColumn(name = "TO_RTE_NODE_ID"))
135 private List<RouteNode> nextNodes = new ArrayList<RouteNode>();
136 @OneToOne(fetch=FetchType.EAGER, cascade={CascadeType.PERSIST, CascadeType.MERGE})
137 @JoinColumn(name="BRCH_PROTO_ID")
138 private BranchPrototype branch;
139 @OneToMany(fetch=FetchType.EAGER,mappedBy="routeNode",cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})
140 @Fetch(value = FetchMode.SELECT)
141 private List<RouteNodeConfigParam> configParams = new ArrayList<RouteNodeConfigParam>(0);
142
143
144
145
146
147
148 protected RouteNodeConfigParam getConfigParam(String key) {
149 Map<String, RouteNodeConfigParam> configParamMap = Utilities.getKeyValueCollectionAsLookupTable(configParams);
150 return configParamMap.get(key);
151 }
152
153
154
155
156
157
158
159 protected void setConfigParam(String key, String value) {
160 Map<String, RouteNodeConfigParam> configParamMap = Utilities.getKeyValueCollectionAsLookupTable(configParams);
161 RouteNodeConfigParam cfCfgParam = configParamMap.get(key);
162 if (cfCfgParam == null) {
163 cfCfgParam = new RouteNodeConfigParam(this, key, value);
164 configParams.add(cfCfgParam);
165 } else {
166 cfCfgParam.setValue(value);
167 }
168 }
169
170 public List<RouteNodeConfigParam> getConfigParams() {
171 return configParams;
172 }
173
174 public void setConfigParams(List<RouteNodeConfigParam> configParams) {
175 this.configParams = configParams;
176 }
177
178
179
180
181 public String getContentFragment() {
182 RouteNodeConfigParam cfCfgParam = getConfigParam(CONTENT_FRAGMENT_CFG_KEY);
183 if (cfCfgParam == null) return null;
184 return cfCfgParam.getValue();
185 }
186
187
188
189
190 public void setContentFragment(String contentFragment) {
191 setConfigParam(CONTENT_FRAGMENT_CFG_KEY, contentFragment);
192 }
193
194 public String getActivationType() {
195 return activationType;
196 }
197
198 public void setActivationType(String activationType) {
199
200
201
202
203
204
205
206
207 ActivationTypeEnum at = ActivationTypeEnum.lookupCode(activationType);
208 this.activationType = at.getCode();
209 }
210
211 public Group getExceptionWorkgroup() {
212 if (!StringUtils.isBlank(exceptionWorkgroupId)) {
213 return KimApiServiceLocator.getGroupService().getGroup(exceptionWorkgroupId);
214 }
215 return null;
216 }
217
218 public boolean isExceptionGroupDefined() {
219 return getExceptionWorkgroupId() != null;
220 }
221
222 public String getExceptionWorkgroupId() {
223 return exceptionWorkgroupId;
224 }
225
226 public void setExceptionWorkgroupId(String workgroupId) {
227 this.exceptionWorkgroupId = workgroupId;
228 }
229
230 public void setFinalApprovalInd(Boolean finalApprovalInd) {
231 this.finalApprovalInd = finalApprovalInd;
232 }
233
234 public void setMandatoryRouteInd(Boolean mandatoryRouteInd) {
235 this.mandatoryRouteInd = mandatoryRouteInd;
236 }
237
238 public String getRouteMethodName() {
239 return routeMethodName;
240 }
241
242 public void setRouteMethodName(String routeMethodName) {
243 this.routeMethodName = routeMethodName;
244 }
245
246 public String getDocumentTypeId() {
247 return documentTypeId;
248 }
249
250 public void setDocumentTypeId(String documentTypeId) {
251 this.documentTypeId = documentTypeId;
252 }
253
254 public String getRouteNodeId() {
255 return routeNodeId;
256 }
257
258 public void setRouteNodeId(String routeNodeId) {
259 this.routeNodeId = routeNodeId;
260 }
261
262 public String getRouteNodeName() {
263 return routeNodeName;
264 }
265
266 public void setRouteNodeName(String routeLevelName) {
267 this.routeNodeName = routeLevelName;
268 }
269
270 public DocumentType getDocumentType() {
271 return documentType;
272 }
273
274 public void setDocumentType(DocumentType documentType) {
275 this.documentType = documentType;
276 }
277
278 public String getRouteMethodCode() {
279 return routeMethodCode;
280 }
281
282 public void setRouteMethodCode(String routeMethodCode) {
283 this.routeMethodCode = routeMethodCode;
284 }
285
286
287
288
289 public void setNextDocStatus(String nextDocStatus) {
290 this.nextDocStatus = nextDocStatus;
291 }
292
293
294
295
296 public String getNextDocStatus() {
297 return nextDocStatus;
298 }
299
300 public String getExceptionWorkgroupName() {
301 Group exceptionGroup = getExceptionWorkgroup();
302 if (exceptionWorkgroupName == null || exceptionWorkgroupName.equals("")) {
303 if (exceptionGroup != null) {
304 return exceptionGroup.getName();
305 }
306 }
307 return exceptionWorkgroupName;
308 }
309
310 public void setExceptionWorkgroupName(String exceptionWorkgroupName) {
311 this.exceptionWorkgroupName = exceptionWorkgroupName;
312 }
313
314 public Integer getLockVerNbr() {
315 return lockVerNbr;
316 }
317
318 public void setLockVerNbr(Integer lockVerNbr) {
319 this.lockVerNbr = lockVerNbr;
320 }
321
322 public boolean isFlexRM() {
323 return routeMethodCode != null && routeMethodCode.equals(KewApiConstants.ROUTE_LEVEL_FLEX_RM);
324 }
325
326 public boolean isRulesEngineNode() {
327 return StringUtils.equals(routeMethodCode, KewApiConstants.ROUTE_LEVEL_RULES_ENGINE);
328 }
329
330 public boolean isPeopleFlowNode() {
331 return StringUtils.equals(routeMethodCode, KewApiConstants.ROUTE_LEVEL_PEOPLE_FLOW);
332 }
333
334 public boolean isRoleNode() {
335 try {
336 return nodeType != null && NodeType.fromNode(this).isTypeOf(NodeType.ROLE);
337 } catch( ResourceUnavailableException ex ) {
338 Logger.getLogger( RouteNode.class ).info( "isRoleNode(): Unable to determine node type: " + ex.getMessage() );
339 return false;
340 }
341 }
342
343 public Boolean getFinalApprovalInd() {
344 return finalApprovalInd;
345 }
346
347 public Boolean getMandatoryRouteInd() {
348 return mandatoryRouteInd;
349 }
350
351 public void addNextNode(RouteNode nextNode) {
352 getNextNodes().add(nextNode);
353 nextNode.getPreviousNodes().add(this);
354 }
355
356 public List<RouteNode> getNextNodes() {
357 return nextNodes;
358 }
359
360 public void setNextNodes(List<RouteNode> nextNodes) {
361 this.nextNodes = nextNodes;
362 }
363
364 public List<RouteNode> getPreviousNodes() {
365 return previousNodes;
366 }
367
368 public void setPreviousNodes(List<RouteNode> parentNodes) {
369 this.previousNodes = parentNodes;
370 }
371
372 public RuleTemplateBo getRuleTemplate() {
373 if (ruleTemplate == null) {
374 RuleTemplateService ruleTemplateService = (RuleTemplateService) KEWServiceLocator.getService(KEWServiceLocator.RULE_TEMPLATE_SERVICE);
375 ruleTemplate = ruleTemplateService.findByRuleTemplateName(getRouteMethodName());
376 }
377 return ruleTemplate;
378 }
379
380 public String getNodeType() {
381 return nodeType;
382 }
383
384 public void setNodeType(String nodeType) {
385 this.nodeType = nodeType;
386 }
387
388 public BranchPrototype getBranch() {
389 return branch;
390 }
391
392 public void setBranch(BranchPrototype branch) {
393 this.branch = branch;
394 }
395
396
397 public void beforeInsert(){
398 OrmUtils.populateAutoIncValue(this, KEWServiceLocator.getEntityManagerFactory().createEntityManager());
399 }
400
401
402
403
404
405
406 @Override
407 public String toString() {
408 return "RouteNode[routeNodeName="+routeNodeName+", nodeType="+nodeType+", activationType="+activationType+"]";
409 }
410
411 @Override
412 public Long getVersionNumber() {
413 if (lockVerNbr == null) {
414 return null;
415 }
416 return Long.valueOf(lockVerNbr.longValue());
417 }
418
419 @Override
420 public String getId() {
421 if (routeNodeId == null) {
422 return null;
423 }
424 return routeNodeId.toString();
425 }
426
427 @Override
428 public String getName() {
429 return getRouteNodeName();
430 }
431
432 @Override
433 public boolean isFinalApproval() {
434 if (finalApprovalInd == null) {
435 return false;
436 }
437 return finalApprovalInd.booleanValue();
438 }
439
440 @Override
441 public boolean isMandatory() {
442 if (mandatoryRouteInd == null) {
443 return false;
444 }
445 return mandatoryRouteInd.booleanValue();
446 }
447
448 @Override
449 public String getExceptionGroupId() {
450 return exceptionWorkgroupId;
451 }
452
453 @Override
454 public String getType() {
455 return nodeType;
456 }
457
458 @Override
459 public String getBranchName() {
460 if (branch == null) {
461 return null;
462 }
463 return branch.getName();
464 }
465
466 @Override
467 public String getNextDocumentStatus() {
468 return nextDocStatus;
469 }
470
471 @Override
472 public List<? extends RouteNodeConfigurationParameterContract> getConfigurationParameters() {
473 return configParams;
474 }
475
476 @Override
477 public List<String> getPreviousNodeIds() {
478 List<String> previousNodeIds = new ArrayList<String>();
479 if (previousNodes != null) {
480 for (RouteNode previousNode : previousNodes) {
481 previousNodeIds.add(previousNode.getRouteNodeId().toString());
482 }
483 }
484 return previousNodeIds;
485 }
486
487 @Override
488 public List<String> getNextNodeIds() {
489 List<String> nextNodeIds = new ArrayList<String>();
490 if (nextNodeIds != null) {
491 for (RouteNode nextNode : nextNodes) {
492 nextNodeIds.add(nextNode.getRouteNodeId().toString());
493 }
494 }
495 return nextNodeIds;
496 }
497
498
499
500 }