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.CoreApiServiceLocator;
021 import org.kuali.rice.core.api.util.xml.XmlJotter;
022 import org.kuali.rice.edl.impl.EDLContext;
023 import org.kuali.rice.edl.impl.EDLModelComponent;
024 import org.kuali.rice.kew.api.KEWPropertyConstants;
025 import org.kuali.rice.kew.api.WorkflowRuntimeException;
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 java.util.Collections;
034 import java.util.HashMap;
035 import java.util.Map;
036 import java.util.Properties;
037 import java.util.StringTokenizer;
038
039 public class PerformLookupComponent implements EDLModelComponent {
040
041 private static final Logger LOG = Logger.getLogger(PerformLookupComponent.class);
042
043 @Override
044 public void updateDOM(Document dom, Element configElement, EDLContext edlContext) {
045 String userAction = edlContext.getUserAction().getAction();
046 if (userAction != null && userAction.startsWith("performLookup")) {
047 edlContext.setRedirectUrl(constructRedirectUrl(dom, configElement, edlContext));
048 }
049 }
050
051 protected String constructRedirectUrl(Document dom, Element configElement, EDLContext edlContext) {
052 StringBuilder buf = new StringBuilder(30);
053 buf.append(CoreApiServiceLocator.getKualiConfigurationService().getPropertyValueAsString(
054 KRADConstants.APPLICATION_URL_KEY));
055 buf.append("/kr/").append(KRADConstants.LOOKUP_ACTION);
056
057 Properties parameters = new Properties();
058 parameters.put(KRADConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, getBusinessObjectClassName(dom, configElement, edlContext));
059 parameters.put(KEWPropertyConstants.DOC_FORM_KEY, edlContext.getUserSession().addObjectWithGeneratedKey(dom));
060 parameters.put(KRADConstants.RETURN_LOCATION_PARAMETER, constructReturnUrl(dom, configElement, edlContext));
061 parameters.putAll(getLookupParameters(dom, configElement, edlContext));
062 parameters.put(KRADConstants.CONVERSION_FIELDS_PARAMETER, getFieldConversions(dom, configElement, edlContext));
063
064 String url = UrlFactory.parameterizeUrl(buf.toString(), parameters);
065
066 return url;
067 }
068
069 protected String getBusinessObjectClassName(Document dom, Element configElement, EDLContext edlContext) {
070 String userAction = edlContext.getUserAction().getAction();
071 String lookupField = StringUtils.substringAfter(userAction, ".");
072 if (StringUtils.isBlank(lookupField)) {
073 LOG.error("Cannot find lookup field parameters definition for field " + lookupField);
074 return null;
075 }
076
077 XPath xPath = edlContext.getXpath();
078 try {
079 String businessObjectClassName = xPath.evaluate("//fieldDef[@name='" + lookupField + "']/lookup/businessObjectClassName", dom);
080 return businessObjectClassName;
081 } catch (XPathExpressionException e) {
082 throw new WorkflowRuntimeException(e);
083 }
084 }
085
086 protected String getFieldConversions(Document dom, Element configElement, EDLContext edlContext) {
087 String userAction = edlContext.getUserAction().getAction();
088 String lookupField = StringUtils.substringAfter(userAction, ".");
089 if (StringUtils.isBlank(lookupField)) {
090 LOG.error("Cannot find lookup field parameters definition for field " + lookupField);
091 return null;
092 }
093
094 XPath xPath = edlContext.getXpath();
095 try {
096 String lookupParameters = xPath.evaluate("//fieldDef[@name='" + lookupField + "']/lookup/fieldConversions", dom);
097 return lookupParameters;
098 } catch (XPathExpressionException e) {
099 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 = edlContext.getXpath();
125 try {
126 String parameterValue = xPath.evaluate("//field[@name='" + parameterValuePropertyName + "']/value", currentVersion);
127 if (LOG.isDebugEnabled()) {
128 LOG.debug(XmlJotter.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 = edlContext.getXpath();
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(CoreApiServiceLocator.getKualiConfigurationService().getPropertyValueAsString(
160 KRADConstants.APPLICATION_URL_KEY));
161 baseUrl.append("/kew/EDocLite");
162
163 Properties parameters = new Properties();
164
165 String url = UrlFactory.parameterizeUrl(baseUrl.toString(), parameters);
166 return url;
167 }
168 }