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.kuali.rice.core.api.uif.RemotableAttributeErrorContract; 019import org.kuali.rice.edl.impl.EDLContext; 020import org.kuali.rice.edl.impl.EDLModelComponent; 021import org.kuali.rice.edl.impl.RequestParser; 022import org.kuali.rice.edl.impl.service.EdlServiceLocator; 023import org.kuali.rice.kew.api.WorkflowDocument; 024import org.kuali.rice.kew.api.WorkflowRuntimeException; 025import org.kuali.rice.kew.api.document.PropertyDefinition; 026import org.kuali.rice.kew.api.document.attribute.WorkflowAttributeDefinition; 027import org.kuali.rice.kew.rule.xmlrouting.XPathHelper; 028import org.w3c.dom.Document; 029import org.w3c.dom.Element; 030import org.w3c.dom.NodeList; 031 032import javax.xml.xpath.XPath; 033import javax.xml.xpath.XPathConstants; 034import java.util.List; 035import java.util.Map; 036 037 038/** 039 * Executes validations and generates XML for workflow attributes that are defined on the EDL Definitions. 040 * These attribute definitions exist in a form similiar to the following: 041 * 042 * <attributes> 043 * <attribute name="AccountAttribute"> 044 * <field edlField="finCoaCd" attributeField="finCoaCd"/> 045 * <field edlField="accountNbr" attributeField="accountNbr"/> 046 * <field edlField="totalDollarAmount" attributeField="totalDollarAmount"/> 047 * </attribute> 048 * </attributes> 049 * 050 * @author Kuali Rice Team (rice.collab@kuali.org) 051 */ 052public class GlobalAttributeComponent extends SimpleWorkflowEDLConfigComponent implements EDLModelComponent { 053 054 public void updateDOM(Document dom, Element configElement, EDLContext edlContext) { 055 //String action = edlContext.getRequestParser().getPropertyValueAsString(WorkflowDocumentActions.USER_ACTION_REQUEST_KEY); 056 // we don't want to clear the attribute content if they are just opening up the document to view it! 057 if (!edlContext.getUserAction().isLoadAction()) { 058 RequestParser requestParser = edlContext.getRequestParser(); 059 try { 060 WorkflowDocument document = (WorkflowDocument)requestParser.getAttribute(RequestParser.WORKFLOW_DOCUMENT_SESSION_KEY); 061 // clear attribute content so that duplicate attribute values are not added during submission of a new EDL form values version 062 document.clearAttributeContent(); 063 Document edlDef = EdlServiceLocator.getEDocLiteService().getDefinitionXml(edlContext.getEdocLiteAssociation()); 064 XPath xpath = XPathHelper.newXPath(edlDef); 065 NodeList attributeNodes = (NodeList)xpath.evaluate("/edl/attributes/attribute", edlDef, XPathConstants.NODESET); 066 for (int index = 0; index < attributeNodes.getLength(); index++) { 067 Element attributeElem = (Element)attributeNodes.item(index); 068 String attributeName = attributeElem.getAttribute("name"); 069 070 071 WorkflowAttributeDefinition.Builder attributeDefBuilder = getWorkflowAttributeDefinitionVO(attributeName, document); 072 073 NodeList fieldNodes = (NodeList)xpath.evaluate("./field", attributeElem, XPathConstants.NODESET); 074 for (int fIndex = 0; fIndex < fieldNodes.getLength(); fIndex++) { 075 Element fieldElem = (Element)fieldNodes.item(fIndex); 076 String edlField = fieldElem.getAttribute("edlField"); 077 String attributeField = fieldElem.getAttribute("attributeField"); 078 PropertyDefinition property = attributeDefBuilder.getPropertyDefinition(attributeField); 079 String value = requestParser.getParameterValue(edlField); 080 if (property == null) { 081 property = PropertyDefinition.create(attributeField, value); 082 } else { 083 // modify the current property 084 attributeDefBuilder.getPropertyDefinitions().remove(property); 085 property = PropertyDefinition.create(property.getName(), value); 086 } 087 attributeDefBuilder.addPropertyDefinition(property); 088 } 089 090 // validate if they are taking an action on the document (i.e. it's annotatable) 091 boolean curAttrValid = true; 092 if (edlContext.getUserAction().isValidatableAction()) { 093 List<? extends RemotableAttributeErrorContract> errors = document.validateAttributeDefinition(attributeDefBuilder.build()); 094 if (!errors.isEmpty()) { 095 edlContext.setInError(true); 096 curAttrValid = false; 097 } 098 Map<String, String> fieldErrors = (Map<String, String>)edlContext.getRequestParser().getAttribute(RequestParser.GLOBAL_FIELD_ERRORS_KEY); 099 for (RemotableAttributeErrorContract error : errors) { 100 fieldErrors.put(error.getAttributeName(), error.getMessage()); 101 } 102 } 103 104 105 if(curAttrValid){ 106 if (edlContext.getUserAction().isValidatableAction()) { 107 for (int fIndex = 0; fIndex < fieldNodes.getLength(); fIndex++) { 108 Element fieldElem = (Element)fieldNodes.item(fIndex); 109 String edlField = fieldElem.getAttribute("edlField"); 110 String attributeField = fieldElem.getAttribute("attributeField"); 111 PropertyDefinition property = attributeDefBuilder.getPropertyDefinition(attributeField); 112 String value = requestParser.getParameterValue(edlField); 113 if (property == null) { 114 property = PropertyDefinition.create(attributeField, value); 115 } else { 116 // modify the current property 117 attributeDefBuilder.getPropertyDefinitions().remove(property); 118 property = PropertyDefinition.create(property.getName(), value); 119 } 120 attributeDefBuilder.addPropertyDefinition(property); 121 } 122 WorkflowAttributeDefinition attributeDef = attributeDefBuilder.build(); 123 document.addAttributeDefinition(attributeDef); 124 } 125 } 126 127 128 129 } 130 } catch (Exception e) { 131 if (e instanceof RuntimeException) { 132 throw (RuntimeException)e; 133 } 134 throw new WorkflowRuntimeException("Failed to process attribute.", e); 135 } 136 } 137 } 138 139 private WorkflowAttributeDefinition.Builder getWorkflowAttributeDefinitionVO(String attributeName, WorkflowDocument document) { 140 for (WorkflowAttributeDefinition attributeDefinition : document.getAttributeDefinitions()) { 141 if (attributeDefinition.getAttributeName().equals(attributeName)) { 142 return WorkflowAttributeDefinition.Builder.create(attributeDefinition); 143 } 144 } 145 return WorkflowAttributeDefinition.Builder.create(attributeName); 146 } 147 148}