View Javadoc
1   /**
2    * Copyright 2005-2014 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.edl.impl.components;
17  
18  import org.kuali.rice.core.api.uif.RemotableAttributeErrorContract;
19  import org.kuali.rice.edl.impl.EDLContext;
20  import org.kuali.rice.edl.impl.EDLModelComponent;
21  import org.kuali.rice.edl.impl.RequestParser;
22  import org.kuali.rice.edl.impl.service.EdlServiceLocator;
23  import org.kuali.rice.kew.api.WorkflowDocument;
24  import org.kuali.rice.kew.api.WorkflowRuntimeException;
25  import org.kuali.rice.kew.api.document.PropertyDefinition;
26  import org.kuali.rice.kew.api.document.attribute.WorkflowAttributeDefinition;
27  import org.kuali.rice.kew.rule.xmlrouting.XPathHelper;
28  import org.w3c.dom.Document;
29  import org.w3c.dom.Element;
30  import org.w3c.dom.NodeList;
31  
32  import javax.xml.xpath.XPath;
33  import javax.xml.xpath.XPathConstants;
34  import java.util.List;
35  import java.util.Map;
36  
37  
38  /**
39   * Executes validations and generates XML for workflow attributes that are defined on the EDL Definitions.
40   * These attribute definitions exist in a form similiar to the following:
41   *
42   * <attributes>
43   *   <attribute name="AccountAttribute">
44   *     <field edlField="finCoaCd" attributeField="finCoaCd"/>
45   *     <field edlField="accountNbr" attributeField="accountNbr"/>
46   *     <field edlField="totalDollarAmount" attributeField="totalDollarAmount"/>
47   *   </attribute>
48   * </attributes>
49   *
50   * @author Kuali Rice Team (rice.collab@kuali.org)
51   */
52  public class GlobalAttributeComponent extends SimpleWorkflowEDLConfigComponent implements EDLModelComponent  {
53  
54  	public void updateDOM(Document dom, Element configElement, EDLContext edlContext) {
55  	    //String action = edlContext.getRequestParser().getPropertyValueAsString(WorkflowDocumentActions.USER_ACTION_REQUEST_KEY);
56  	    // we don't want to clear the attribute content if they are just opening up the document to view it!
57  	    if (!edlContext.getUserAction().isLoadAction()) {
58  		RequestParser requestParser = edlContext.getRequestParser();
59  		try {
60  			WorkflowDocument document = (WorkflowDocument)requestParser.getAttribute(RequestParser.WORKFLOW_DOCUMENT_SESSION_KEY);
61  			//			 clear attribute content so that duplicate attribute values are not added during submission of a new EDL form values version
62  			document.clearAttributeContent();
63  			Document edlDef = EdlServiceLocator.getEDocLiteService().getDefinitionXml(edlContext.getEdocLiteAssociation());
64  			XPath xpath = XPathHelper.newXPath(edlDef);
65  			NodeList attributeNodes = (NodeList)xpath.evaluate("/edl/attributes/attribute", edlDef, XPathConstants.NODESET);
66  			for (int index = 0; index < attributeNodes.getLength(); index++) {
67  				Element attributeElem = (Element)attributeNodes.item(index);
68  				String attributeName = attributeElem.getAttribute("name");
69  
70  
71  				WorkflowAttributeDefinition.Builder attributeDefBuilder = getWorkflowAttributeDefinitionVO(attributeName, document);
72  
73  				NodeList fieldNodes = (NodeList)xpath.evaluate("./field", attributeElem, XPathConstants.NODESET);
74  				for (int fIndex = 0; fIndex < fieldNodes.getLength(); fIndex++) {
75  					Element fieldElem = (Element)fieldNodes.item(fIndex);
76  					String edlField = fieldElem.getAttribute("edlField");
77  					String attributeField = fieldElem.getAttribute("attributeField");
78  					PropertyDefinition property = attributeDefBuilder.getPropertyDefinition(attributeField);
79  					String value = requestParser.getParameterValue(edlField);
80  					if (property == null) {
81  					    property = PropertyDefinition.create(attributeField, value);
82  					} else {
83  	                    // modify the current property
84  	                    attributeDefBuilder.getPropertyDefinitions().remove(property);
85  	                    property = PropertyDefinition.create(property.getName(), value);
86  					}
87  					attributeDefBuilder.addPropertyDefinition(property);
88  				}				
89  				
90  				// validate if they are taking an action on the document (i.e. it's annotatable)
91  				boolean curAttrValid = true;
92  				if (edlContext.getUserAction().isValidatableAction()) {
93  				    List<? extends RemotableAttributeErrorContract> errors = document.validateAttributeDefinition(attributeDefBuilder.build());
94  					if (!errors.isEmpty()) {
95  						edlContext.setInError(true);
96  						curAttrValid = false;
97  					}
98  					Map<String, String> fieldErrors = (Map<String, String>)edlContext.getRequestParser().getAttribute(RequestParser.GLOBAL_FIELD_ERRORS_KEY);
99  					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 }