View Javadoc

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