001 /**
002 * Copyright 2005-2013 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.kuali.rice.edl.impl.components;
017
018 import org.apache.commons.lang.StringUtils;
019 import org.apache.log4j.Logger;
020 import org.kuali.rice.core.api.util.xml.XmlJotter;
021 import org.kuali.rice.edl.impl.EDLContext;
022 import org.kuali.rice.edl.impl.EDLModelComponent;
023 import org.kuali.rice.kew.api.KEWPropertyConstants;
024 import org.kuali.rice.kew.api.WorkflowRuntimeException;
025 import org.kuali.rice.krad.service.KRADServiceLocator;
026 import org.kuali.rice.krad.util.KRADConstants;
027 import org.kuali.rice.krad.util.UrlFactory;
028 import org.w3c.dom.Document;
029 import org.w3c.dom.Element;
030
031 import javax.xml.xpath.XPath;
032 import javax.xml.xpath.XPathExpressionException;
033 import javax.xml.xpath.XPathFactory;
034 import java.util.Collections;
035 import java.util.HashMap;
036 import java.util.Map;
037 import java.util.Properties;
038 import java.util.StringTokenizer;
039
040 public class PerformLookupComponent implements EDLModelComponent {
041
042 private static final Logger LOG = Logger.getLogger(PerformLookupComponent.class);
043
044 @Override
045 public void updateDOM(Document dom, Element configElement, EDLContext edlContext) {
046 String userAction = edlContext.getUserAction().getAction();
047 if (userAction != null && userAction.startsWith("performLookup")) {
048 edlContext.setRedirectUrl(constructRedirectUrl(dom, configElement, edlContext));
049 }
050 }
051
052 protected String constructRedirectUrl(Document dom, Element configElement, EDLContext edlContext) {
053 StringBuilder buf = new StringBuilder(30);
054 buf.append(KRADServiceLocator.getKualiConfigurationService().getPropertyValueAsString(
055 KRADConstants.APPLICATION_URL_KEY));
056 buf.append("/kr/").append(KRADConstants.LOOKUP_ACTION);
057
058 Properties parameters = new Properties();
059 parameters.put(KRADConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, getBusinessObjectClassName(dom, configElement, edlContext));
060 parameters.put(KEWPropertyConstants.DOC_FORM_KEY, edlContext.getUserSession().addObjectWithGeneratedKey(dom));
061 parameters.put(KRADConstants.RETURN_LOCATION_PARAMETER, constructReturnUrl(dom, configElement, edlContext));
062 parameters.putAll(getLookupParameters(dom, configElement, edlContext));
063 parameters.put(KRADConstants.CONVERSION_FIELDS_PARAMETER, getFieldConversions(dom, configElement, edlContext));
064
065 String url = UrlFactory.parameterizeUrl(buf.toString(), parameters);
066
067 return url;
068 }
069
070 protected String getBusinessObjectClassName(Document dom, Element configElement, EDLContext edlContext) {
071 String userAction = edlContext.getUserAction().getAction();
072 String lookupField = StringUtils.substringAfter(userAction, ".");
073 if (StringUtils.isBlank(lookupField)) {
074 LOG.error("Cannot find lookup field parameters definition for field " + lookupField);
075 return null;
076 }
077
078 XPath xPath = edlContext.getXpath();
079 try {
080 String businessObjectClassName = xPath.evaluate("//fieldDef[@name='" + lookupField + "']/lookup/businessObjectClassName", dom);
081 return businessObjectClassName;
082 } catch (XPathExpressionException e) {
083 throw new WorkflowRuntimeException(e);
084 }
085 }
086
087 protected String getFieldConversions(Document dom, Element configElement, EDLContext edlContext) {
088 String userAction = edlContext.getUserAction().getAction();
089 String lookupField = StringUtils.substringAfter(userAction, ".");
090 if (StringUtils.isBlank(lookupField)) {
091 LOG.error("Cannot find lookup field parameters definition for field " + lookupField);
092 return null;
093 }
094
095 XPath xPath = edlContext.getXpath();
096 try {
097 String lookupParameters = xPath.evaluate("//fieldDef[@name='" + lookupField + "']/lookup/fieldConversions", dom);
098 return lookupParameters;
099 } 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 }