View Javadoc

1   /*
2    * Copyright 2008-2009 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.edl.impl.EDLContext;
19  import org.kuali.rice.edl.impl.EDLModelComponent;
20  import org.kuali.rice.edl.impl.RequestParser;
21  import org.kuali.rice.edl.impl.service.EdlServiceLocator;
22  import org.kuali.rice.kew.api.WorkflowDocument;
23  import org.kuali.rice.kew.api.WorkflowRuntimeException;
24  import org.kuali.rice.kew.api.document.PropertyDefinition;
25  import org.kuali.rice.kew.api.document.attribute.WorkflowAttributeDefinition;
26  import org.kuali.rice.kew.api.document.attribute.WorkflowAttributeValidationError;
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<WorkflowAttributeValidationError> 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 (WorkflowAttributeValidationError error : errors) {
100 					    fieldErrors.put(error.getKey(), error.getMessage());
101 					}
102 				}
103 				
104 
105 				if(curAttrValid){
106 					for (int fIndex = 0; fIndex < fieldNodes.getLength(); fIndex++) {
107 						Element fieldElem = (Element)fieldNodes.item(fIndex);
108 						String edlField = fieldElem.getAttribute("edlField");
109 						String attributeField = fieldElem.getAttribute("attributeField");
110 						PropertyDefinition property = attributeDefBuilder.getPropertyDefinition(attributeField);
111 						String value = requestParser.getParameterValue(edlField);
112 						if (property == null) {
113 							property = PropertyDefinition.create(attributeField, value);							
114 						} else {
115 		                    // modify the current property
116 		                    attributeDefBuilder.getPropertyDefinitions().remove(property);
117 		                    property = PropertyDefinition.create(property.getName(), value);
118 						}
119 						attributeDefBuilder.addPropertyDefinition(property);
120 					}
121 					WorkflowAttributeDefinition attributeDef = attributeDefBuilder.build();
122 	                document.addAttributeDefinition(attributeDef);
123 				}
124 				
125 				
126 
127 			}
128 		} catch (Exception e) {
129 			if (e instanceof RuntimeException) {
130 				throw (RuntimeException)e;
131 			}
132 			throw new WorkflowRuntimeException("Failed to process attribute.", e);
133 		}
134 	    }
135 	}
136 
137     private WorkflowAttributeDefinition.Builder getWorkflowAttributeDefinitionVO(String attributeName, WorkflowDocument document) {
138         for (WorkflowAttributeDefinition attributeDefinition : document.getAttributeDefinitions()) {
139             if (attributeDefinition.getAttributeName().equals(attributeName)) {
140                 return WorkflowAttributeDefinition.Builder.create(attributeDefinition);
141             }
142         }
143         return WorkflowAttributeDefinition.Builder.create(attributeName);
144     }
145 
146 }