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