001/** 002 * Copyright 2005-2016 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 */ 016package org.kuali.rice.edl.impl.components; 017 018import org.apache.commons.lang.StringUtils; 019import org.apache.log4j.Logger; 020import org.kuali.rice.core.api.util.xml.XmlJotter; 021import org.kuali.rice.edl.impl.EDLContext; 022import org.kuali.rice.edl.impl.EDLModelComponent; 023import org.kuali.rice.kew.api.KEWPropertyConstants; 024import org.kuali.rice.kew.api.WorkflowRuntimeException; 025import org.kuali.rice.krad.service.KRADServiceLocator; 026import org.kuali.rice.krad.util.KRADConstants; 027import org.kuali.rice.krad.util.UrlFactory; 028import org.w3c.dom.Document; 029import org.w3c.dom.Element; 030 031import javax.xml.xpath.XPath; 032import javax.xml.xpath.XPathExpressionException; 033import javax.xml.xpath.XPathFactory; 034import java.util.Collections; 035import java.util.HashMap; 036import java.util.Map; 037import java.util.Properties; 038import java.util.StringTokenizer; 039 040public 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}