001/** 002 * Copyright 2005-2014 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.CoreApiServiceLocator; 021import org.kuali.rice.core.api.util.xml.XmlJotter; 022import org.kuali.rice.edl.impl.EDLContext; 023import org.kuali.rice.edl.impl.EDLModelComponent; 024import org.kuali.rice.kew.api.KEWPropertyConstants; 025import org.kuali.rice.kew.api.WorkflowRuntimeException; 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 java.util.Collections; 034import java.util.HashMap; 035import java.util.Map; 036import java.util.Properties; 037import java.util.StringTokenizer; 038 039public 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}