View Javadoc

1   /**
2    * Copyright 2005-2013 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.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 = edlContext.getXpath();
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 = edlContext.getXpath();
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 		// where all of the field values are stored
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 = edlContext.getXpath();
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 = edlContext.getXpath();
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 }