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.kuali.rice.core.api.uif.RemotableAttributeErrorContract;
019 import org.kuali.rice.edl.impl.EDLContext;
020 import org.kuali.rice.edl.impl.EDLModelComponent;
021 import org.kuali.rice.edl.impl.RequestParser;
022 import org.kuali.rice.edl.impl.service.EdlServiceLocator;
023 import org.kuali.rice.kew.api.WorkflowDocument;
024 import org.kuali.rice.kew.api.WorkflowRuntimeException;
025 import org.kuali.rice.kew.api.document.PropertyDefinition;
026 import org.kuali.rice.kew.api.document.attribute.WorkflowAttributeDefinition;
027 import org.kuali.rice.kew.rule.xmlrouting.XPathHelper;
028 import org.w3c.dom.Document;
029 import org.w3c.dom.Element;
030 import org.w3c.dom.NodeList;
031
032 import javax.xml.xpath.XPath;
033 import javax.xml.xpath.XPathConstants;
034 import java.util.List;
035 import 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 */
052 public 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 }