1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kew.routemodule;
17
18 import org.apache.log4j.Logger;
19 import org.jdom.Document;
20 import org.jdom.Element;
21 import org.kuali.rice.core.api.impex.xml.XmlConstants;
22 import org.kuali.rice.core.api.reflect.ObjectDefinition;
23 import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
24 import org.kuali.rice.core.api.util.xml.XmlHelper;
25 import org.kuali.rice.kew.actionrequest.ActionRequestFactory;
26 import org.kuali.rice.kew.actionrequest.ActionRequestValue;
27 import org.kuali.rice.kew.api.KewApiServiceLocator;
28 import org.kuali.rice.kew.api.extension.ExtensionDefinition;
29 import org.kuali.rice.kew.api.rule.RuleExtension;
30 import org.kuali.rice.kew.engine.RouteContext;
31 import org.kuali.rice.kew.engine.node.RouteNodeInstance;
32 import org.kuali.rice.kew.rule.RuleBaseValues;
33 import org.kuali.rice.kew.rule.RuleExtensionBo;
34 import org.kuali.rice.kew.rule.RuleResponsibilityBo;
35 import org.kuali.rice.kew.rule.WorkflowRuleAttribute;
36 import org.kuali.rice.kew.rule.bo.RuleAttribute;
37 import org.kuali.rice.kew.rule.xmlrouting.GenericXMLRuleAttribute;
38 import org.kuali.rice.kew.rule.xmlrouting.XPathHelper;
39 import org.kuali.rice.kew.service.KEWServiceLocator;
40 import org.kuali.rice.kew.api.KewApiConstants;
41 import org.kuali.rice.kew.xml.RuleXmlParser;
42
43 import javax.xml.xpath.XPath;
44 import javax.xml.xpath.XPathConstants;
45 import java.io.ByteArrayInputStream;
46 import java.util.ArrayList;
47 import java.util.Collections;
48 import java.util.List;
49
50
51
52
53
54
55
56 public class InlineRequestsRouteModule extends FlexRMAdapter {
57 private static final Logger LOG = Logger.getLogger(InlineRequestsRouteModule.class);
58
59
60
61
62
63
64
65 @Override
66 public List<ActionRequestValue> findActionRequests(RouteContext context) throws Exception {
67
68
69 List<ActionRequestValue> actionRequests = new ArrayList<ActionRequestValue>();
70 RouteNodeInstance currentNode = context.getNodeInstance();
71 String contentFragment = currentNode.getRouteNode().getContentFragment();
72
73 Document doc = XmlHelper.trimSAXXml(new ByteArrayInputStream(contentFragment.getBytes()));
74 Element root = doc.getRootElement();
75 List<String> ruleAttributeNames = new ArrayList<String>();
76 List<String> ruleAttributeClassNames = new ArrayList<String>();
77 List<String> xpathExpressions = new ArrayList<String>();
78
79 Element ruleAttributes = root.getChild("ruleAttributes");
80 if (ruleAttributes != null) {
81 for (Object o : ruleAttributes.getChildren("name")) {
82 Element e = (Element) o;
83 ruleAttributeNames.add(e.getText());
84 }
85 for (Object o : ruleAttributes.getChildren("className")) {
86 Element e = (Element) o;
87 ruleAttributeClassNames.add(e.getText());
88 }
89 }
90
91 for (Object o: root.getChildren("match")) {
92 Element e = (Element) o;
93 xpathExpressions.add(e.getText());
94 }
95 if ( (ruleAttributeNames.isEmpty()) && (ruleAttributeClassNames.isEmpty()) && (xpathExpressions.isEmpty()) ) {
96 throw new RuntimeException("Match xpath expression not specified (should be parse-time exception...)");
97 }
98
99 List<WorkflowRuleAttribute> attributes = new ArrayList<WorkflowRuleAttribute>();
100 for (String attributeName : ruleAttributeNames) {
101 attributes.add(getRuleAttributeByName(attributeName));
102 }
103 for (String attributeClassName : ruleAttributeClassNames) {
104 attributes.addAll(getRuleAttributeByClassName(attributeClassName));
105 }
106
107
108 if (attributes.isEmpty() && xpathExpressions.isEmpty()) {
109 return actionRequests;
110 }
111
112 Boolean match = Boolean.TRUE;
113 if (!xpathExpressions.isEmpty()) {
114 XPath xpath = XPathHelper.newXPath();
115 for (String xpathExpression : xpathExpressions) {
116 match &= (Boolean) xpath.evaluate(xpathExpression, context.getDocumentContent().getDocument(), XPathConstants.BOOLEAN);
117 }
118 }
119 for (WorkflowRuleAttribute workflowAttribute : attributes) {
120
121 match &= workflowAttribute.isMatch(context.getDocumentContent(), Collections.<RuleExtension>emptyList());
122 }
123
124 if (match.booleanValue()) {
125
126 } else {
127
128
129 return actionRequests;
130 }
131
132 List<org.kuali.rice.kew.api.rule.RuleResponsibility> responsibilities = new ArrayList<org.kuali.rice.kew.api.rule.RuleResponsibility>();
133 RuleXmlParser parser = new RuleXmlParser();
134 ActionRequestFactory arf = new ActionRequestFactory(context.getDocument(), currentNode);
135
136 RuleBaseValues fakeRule = new RuleBaseValues();
137 fakeRule.setName("fakeRule");
138 fakeRule.setActive(Boolean.TRUE);
139 fakeRule.setCurrentInd(Boolean.TRUE);
140 fakeRule.setDescription("a fake rule");
141 fakeRule.setForceAction(Boolean.TRUE);
142 fakeRule.setId(null);
143
144 for (Object o: root.getChildren("responsibility", XmlConstants.RULE_NAMESPACE)) {
145 Element e = (Element) o;
146 RuleResponsibilityBo responsibility = parser.parseResponsibility(e, fakeRule);
147 responsibility.setResponsibilityId(KewApiConstants.MACHINE_GENERATED_RESPONSIBILITY_ID);
148 responsibilities.add(org.kuali.rice.kew.api.rule.RuleResponsibility.Builder.create(responsibility).build());
149 }
150 if (responsibilities.isEmpty()) {
151 throw new RuntimeException("No responsibilities found on node " + currentNode.getName());
152 }
153
154 makeActionRequests(arf, responsibilities, context, RuleBaseValues.to(fakeRule), context.getDocument(), null, null);
155 actionRequests.addAll(arf.getRequestGraphs());
156 return actionRequests;
157 }
158
159 @Override
160 public String toString() {
161 return "InlineRequestsRouteModule";
162 }
163
164 private WorkflowRuleAttribute getRuleAttributeByName(String ruleAttributeName) {
165 return materializeRuleAttribute(KewApiServiceLocator.getExtensionRepositoryService().getExtensionByName(
166 ruleAttributeName));
167 }
168
169 private List<WorkflowRuleAttribute> getRuleAttributeByClassName(String ruleAttributeClassName) {
170 List<ExtensionDefinition> extensionDefinitions =
171 KewApiServiceLocator.getExtensionRepositoryService().getExtensionsByResourceDescriptor(ruleAttributeClassName);
172 List<WorkflowRuleAttribute> workflowRuleAttributes = new ArrayList<WorkflowRuleAttribute>();
173 for (ExtensionDefinition extension : extensionDefinitions) {
174 workflowRuleAttributes.add(materializeRuleAttribute(extension));
175 }
176 return workflowRuleAttributes;
177 }
178
179 private WorkflowRuleAttribute materializeRuleAttribute(ExtensionDefinition extensionDefinition) {
180 if (extensionDefinition != null) {
181 if (KewApiConstants.RULE_ATTRIBUTE_TYPE.equals(extensionDefinition.getType())) {
182 ObjectDefinition objDef = new ObjectDefinition(extensionDefinition.getResourceDescriptor(), extensionDefinition.getApplicationId());
183 return (WorkflowRuleAttribute) GlobalResourceLoader.getObject(objDef);
184 } else if (KewApiConstants.RULE_XML_ATTRIBUTE_TYPE.equals(extensionDefinition.getType())) {
185 ObjectDefinition objDef = new ObjectDefinition(extensionDefinition.getResourceDescriptor(), extensionDefinition.getApplicationId());
186 WorkflowRuleAttribute workflowAttribute = (WorkflowRuleAttribute) GlobalResourceLoader.getObject(objDef);
187
188 ((GenericXMLRuleAttribute) workflowAttribute).setExtensionDefinition(extensionDefinition);
189 return workflowAttribute;
190 }
191 }
192 return null;
193 }
194
195 }