1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.edl.impl.components;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.apache.log4j.Logger;
20 import org.kuali.rice.core.api.util.xml.XmlJotter;
21 import org.kuali.rice.edl.impl.EDLContext;
22 import org.kuali.rice.edl.impl.EDLModelComponent;
23 import org.kuali.rice.kew.api.KEWPropertyConstants;
24 import org.kuali.rice.kew.api.WorkflowRuntimeException;
25 import org.kuali.rice.krad.service.KRADServiceLocator;
26 import org.kuali.rice.krad.util.KRADConstants;
27 import org.kuali.rice.krad.util.UrlFactory;
28 import org.w3c.dom.Document;
29 import org.w3c.dom.Element;
30
31 import javax.xml.xpath.XPath;
32 import javax.xml.xpath.XPathExpressionException;
33 import javax.xml.xpath.XPathFactory;
34 import java.util.Collections;
35 import java.util.HashMap;
36 import java.util.Map;
37 import java.util.Properties;
38 import java.util.StringTokenizer;
39
40 public class PerformLookupComponent implements EDLModelComponent {
41
42 private static final Logger LOG = Logger.getLogger(PerformLookupComponent.class);
43
44 @Override
45 public void updateDOM(Document dom, Element configElement, EDLContext edlContext) {
46 String userAction = edlContext.getUserAction().getAction();
47 if (userAction != null && userAction.startsWith("performLookup")) {
48 edlContext.setRedirectUrl(constructRedirectUrl(dom, configElement, edlContext));
49 }
50 }
51
52 protected String constructRedirectUrl(Document dom, Element configElement, EDLContext edlContext) {
53 StringBuilder buf = new StringBuilder(30);
54 buf.append(KRADServiceLocator.getKualiConfigurationService().getPropertyValueAsString(
55 KRADConstants.APPLICATION_URL_KEY));
56 buf.append("/kr/").append(KRADConstants.LOOKUP_ACTION);
57
58 Properties parameters = new Properties();
59 parameters.put(KRADConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, getBusinessObjectClassName(dom, configElement, edlContext));
60 parameters.put(KEWPropertyConstants.DOC_FORM_KEY, edlContext.getUserSession().addObjectWithGeneratedKey(dom));
61 parameters.put(KRADConstants.RETURN_LOCATION_PARAMETER, constructReturnUrl(dom, configElement, edlContext));
62 parameters.putAll(getLookupParameters(dom, configElement, edlContext));
63 parameters.put(KRADConstants.CONVERSION_FIELDS_PARAMETER, getFieldConversions(dom, configElement, edlContext));
64
65 String url = UrlFactory.parameterizeUrl(buf.toString(), parameters);
66
67 return url;
68 }
69
70 protected String getBusinessObjectClassName(Document dom, Element configElement, EDLContext edlContext) {
71 String userAction = edlContext.getUserAction().getAction();
72 String lookupField = StringUtils.substringAfter(userAction, ".");
73 if (StringUtils.isBlank(lookupField)) {
74 LOG.error("Cannot find lookup field parameters definition for field " + lookupField);
75 return null;
76 }
77
78 XPath xPath = XPathFactory.newInstance().newXPath();
79 try {
80 String businessObjectClassName = xPath.evaluate("//fieldDef[@name='" + lookupField + "']/lookup/businessObjectClassName", dom);
81 return businessObjectClassName;
82 } catch (XPathExpressionException e) {
83 throw new WorkflowRuntimeException(e);
84 }
85 }
86
87 protected String getFieldConversions(Document dom, Element configElement, EDLContext edlContext) {
88 String userAction = edlContext.getUserAction().getAction();
89 String lookupField = StringUtils.substringAfter(userAction, ".");
90 if (StringUtils.isBlank(lookupField)) {
91 LOG.error("Cannot find lookup field parameters definition for field " + lookupField);
92 return null;
93 }
94
95 XPath xPath = XPathFactory.newInstance().newXPath();
96 try {
97 String lookupParameters = xPath.evaluate("//fieldDef[@name='" + lookupField + "']/lookup/fieldConversions", dom);
98 return lookupParameters;
99 } catch (XPathExpressionException e) {
100 throw new WorkflowRuntimeException(e);
101 }
102 }
103
104 protected Map<String, String> getLookupParameters(Document dom, Element configElement, EDLContext edlContext) {
105 String lookupParameterDefinition = retrieveLookupParametersString(dom, configElement, edlContext);
106 if (StringUtils.isBlank(lookupParameterDefinition)) {
107 return Collections.emptyMap();
108 }
109 StringTokenizer tok = new StringTokenizer(lookupParameterDefinition, ",");
110 Map<String, String> lookupParameters = new HashMap<String, String>();
111
112
113 Element currentVersion = VersioningPreprocessor.findCurrentVersion(dom);
114
115 while (tok.hasMoreTokens()) {
116 String parameterDefinition = tok.nextToken();
117 int colonInd = parameterDefinition.indexOf(':');
118 if (colonInd == -1) {
119 throw new WorkflowRuntimeException("Lookup definition string improperly formatted " + lookupParameterDefinition);
120 }
121
122 String parameterName = parameterDefinition.substring(colonInd + 1);
123 String parameterValuePropertyName = parameterDefinition.substring(0, colonInd);
124
125 XPath xPath = XPathFactory.newInstance().newXPath();
126 try {
127 String parameterValue = xPath.evaluate("//field[@name='" + parameterValuePropertyName + "']/value", currentVersion);
128 if (LOG.isDebugEnabled()) {
129 LOG.debug(XmlJotter.jotNode(currentVersion, true));
130 }
131 if (StringUtils.isNotBlank(parameterValue)) {
132 lookupParameters.put(parameterName, parameterValue);
133 }
134 } catch (XPathExpressionException e) {
135 throw new WorkflowRuntimeException(e);
136 }
137 }
138 return lookupParameters;
139 }
140
141 protected String retrieveLookupParametersString(Document dom, Element configElement, EDLContext edlContext) {
142 String userAction = edlContext.getUserAction().getAction();
143 String lookupField = StringUtils.substringAfter(userAction, ".");
144 if (StringUtils.isBlank(lookupField)) {
145 LOG.error("Cannot find lookup field parameters definition for field " + lookupField);
146 return null;
147 }
148
149 XPath xPath = XPathFactory.newInstance().newXPath();
150 try {
151 String lookupParameters = xPath.evaluate("//fieldDef[@name='" + lookupField + "']/lookup/lookupParameters", dom);
152 return lookupParameters;
153 } catch (XPathExpressionException e) {
154 throw new WorkflowRuntimeException(e);
155 }
156 }
157
158 protected String constructReturnUrl(Document dom, Element configElement, EDLContext edlContext) {
159 StringBuilder baseUrl = new StringBuilder(30);
160 baseUrl.append(KRADServiceLocator.getKualiConfigurationService().getPropertyValueAsString(
161 KRADConstants.APPLICATION_URL_KEY));
162 baseUrl.append("/kew/EDocLite");
163
164 Properties parameters = new Properties();
165
166 String url = UrlFactory.parameterizeUrl(baseUrl.toString(), parameters);
167 return url;
168 }
169 }