View Javadoc

1   /**
2    * Copyright 2005-2013 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.kew.xml.export;
17  
18  import org.apache.commons.collections.CollectionUtils;
19  import org.apache.commons.lang.ObjectUtils;
20  import org.apache.commons.lang.StringUtils;
21  import org.jdom.Element;
22  import org.jdom.Namespace;
23  import org.kuali.rice.core.api.exception.RiceRuntimeException;
24  import org.kuali.rice.core.api.impex.ExportDataSet;
25  import org.kuali.rice.core.api.util.xml.XmlRenderer;
26  import org.kuali.rice.core.framework.impex.xml.XmlExporter;
27  import org.kuali.rice.kew.export.KewExportDataSet;
28  import org.kuali.rice.kew.rule.RuleBaseValues;
29  import org.kuali.rice.kew.rule.RuleDelegationBo;
30  import org.kuali.rice.kew.rule.RuleExtensionBo;
31  import org.kuali.rice.kew.rule.RuleExtensionValue;
32  import org.kuali.rice.kew.rule.RuleResponsibilityBo;
33  import org.kuali.rice.kew.rule.bo.RuleTemplateAttributeBo;
34  import org.kuali.rice.kew.rule.web.WebRuleUtils;
35  import org.kuali.rice.kew.service.KEWServiceLocator;
36  import org.kuali.rice.kim.api.group.Group;
37  import org.kuali.rice.kim.api.identity.principal.Principal;
38  
39  import java.util.ArrayList;
40  import java.util.Collection;
41  import java.util.Collections;
42  import java.util.Comparator;
43  import java.util.HashSet;
44  import java.util.Iterator;
45  import java.util.List;
46  import java.util.Set;
47  
48  import static org.kuali.rice.core.api.impex.xml.XmlConstants.*;
49  
50  /**
51   * Exports rules to XML.
52   *
53   * @see RuleBaseValues
54   *
55   * @author Kuali Rice Team (rice.collab@kuali.org)
56   */
57  public class RuleXmlExporter implements XmlExporter {
58  
59      protected final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(getClass());
60  
61      private XmlRenderer renderer;
62      
63      public RuleXmlExporter(Namespace namespace) {
64      	this.renderer = new XmlRenderer(namespace);
65      }
66      
67  	@Override
68  	public boolean supportPrettyPrint() {
69  		return true;
70  	}
71  
72      public Element export(ExportDataSet exportDataSet) {
73      	KewExportDataSet dataSet = KewExportDataSet.fromExportDataSet(exportDataSet);
74          if (!dataSet.getRules().isEmpty()) {
75              Element rootElement = renderer.renderElement(null, RULES);
76              rootElement.setAttribute(SCHEMA_LOCATION_ATTR, RULE_SCHEMA_LOCATION, SCHEMA_NAMESPACE);
77              for (Iterator iterator = dataSet.getRules().iterator(); iterator.hasNext();) {
78              	RuleBaseValues rule = (RuleBaseValues) iterator.next();
79              	exportRule(rootElement, rule);
80              	//turn below on if need export delegates in rule exportation
81  //            	if(rule.getDelegateRule().booleanValue()){	
82  //            		exportRuleDelegations(rootElement, rule);
83  //            	}
84              }
85              return rootElement;
86          }
87          return null;
88      }
89  
90      public void exportRule(Element parent, RuleBaseValues rule) {
91      	Element ruleElement = renderer.renderElement(parent, RULE);
92          if (rule.getName() != null) {
93              renderer.renderTextElement(ruleElement, NAME, rule.getName());
94          }
95          renderer.renderTextElement(ruleElement, DOCUMENT_TYPE, rule.getDocTypeName());
96          if (rule.getRuleTemplateName() != null) {
97              renderer.renderTextElement(ruleElement, RULE_TEMPLATE, rule.getRuleTemplateName());
98          }
99          renderer.renderTextElement(ruleElement, DESCRIPTION, rule.getDescription());
100         if(rule.getFromDateString() != null){
101             renderer.renderTextElement(ruleElement, FROM_DATE, rule.getFromDateString());
102         }
103         if(rule.getToDateString() != null){
104             renderer.renderTextElement(ruleElement, TO_DATE, rule.getToDateString());
105         }
106         if (rule.getRuleExpressionDef() != null) {
107             Element expressionElement = renderer.renderTextElement(ruleElement, EXPRESSION, rule.getRuleExpressionDef().getExpression());
108             if (rule.getRuleExpressionDef().getType() != null) {
109                 expressionElement.setAttribute("type", rule.getRuleExpressionDef().getType());
110             }
111         }
112         renderer.renderBooleanElement(ruleElement, FORCE_ACTION, rule.isForceAction(), false);
113         
114         if (CollectionUtils.isEmpty(rule.getRuleExtensions()) &&
115         		/* field values is not empty */
116         		!(rule.getFieldValues() == null || rule.getFieldValues().size() == 0)) {
117         	// the rule is in the wrong state (as far as we are concerned).
118         	// translate it
119         	WebRuleUtils.translateResponsibilitiesForSave(rule);
120         	WebRuleUtils.translateFieldValuesForSave(rule);
121         	
122         	// do our exports
123     		exportRuleExtensions(ruleElement, rule.getRuleExtensions());
124         	
125         	// translate it back
126         	WebRuleUtils.populateRuleMaintenanceFields(rule);
127         } else { 
128         	exportRuleExtensions(ruleElement, rule.getRuleExtensions());
129         }
130         
131         // put responsibilities in a single collection 
132         Set<RuleResponsibilityBo> responsibilities = new HashSet<RuleResponsibilityBo>();
133         responsibilities.addAll(rule.getRuleResponsibilities());
134         responsibilities.addAll(rule.getPersonResponsibilities());
135         responsibilities.addAll(rule.getGroupResponsibilities());
136         responsibilities.addAll(rule.getRoleResponsibilities());
137         
138         exportResponsibilities(ruleElement, responsibilities);
139     }
140 
141     private void exportRuleExtensions(Element parent, List ruleExtensions) {
142         if (!ruleExtensions.isEmpty()) {
143             Element extsElement = renderer.renderElement(parent, RULE_EXTENSIONS);
144             for (Iterator iterator = ruleExtensions.iterator(); iterator.hasNext();) {
145                 RuleExtensionBo extension = (RuleExtensionBo) iterator.next();
146                 Element extElement = renderer.renderElement(extsElement, RULE_EXTENSION);
147                 RuleTemplateAttributeBo attribute = extension.getRuleTemplateAttribute();
148                 renderer.renderTextElement(extElement, ATTRIBUTE, attribute.getRuleAttribute().getName());
149                 renderer.renderTextElement(extElement, RULE_TEMPLATE, attribute.getRuleTemplate().getName());
150                 exportRuleExtensionValues(extElement, extension.getExtensionValues());
151             }
152         }
153     }
154 
155     // sorts by rule extension value key in order to establish a deterministic order
156     private void exportRuleExtensionValues(Element parent, List<RuleExtensionValue> extensionValues) {
157         if (!extensionValues.isEmpty()) {
158             List<RuleExtensionValue> sorted = new ArrayList<RuleExtensionValue>(extensionValues);
159             // establish deterministic ordering of keys
160             Collections.sort(sorted, new Comparator<RuleExtensionValue>() {
161                 @Override
162                 public int compare(RuleExtensionValue o1, RuleExtensionValue o2) {
163                     if (o1 == null) return -1;
164                     if (o2 == null) return 1;
165                     return ObjectUtils.compare(o1.getKey(), o2.getKey());
166                 }
167             });
168             Element extValuesElement = renderer.renderElement(parent, RULE_EXTENSION_VALUES);
169             for (Iterator iterator = sorted.iterator(); iterator.hasNext();) {
170                 RuleExtensionValue extensionValue = (RuleExtensionValue) iterator.next();
171                 Element extValueElement = renderer.renderElement(extValuesElement, RULE_EXTENSION_VALUE);
172                 renderer.renderTextElement(extValueElement, KEY, extensionValue.getKey());
173                 renderer.renderTextElement(extValueElement, VALUE, extensionValue.getValue());
174             }
175         }
176     }
177 
178     private void exportResponsibilities(Element parent, Collection<? extends RuleResponsibilityBo> responsibilities) {
179         if (responsibilities != null && !responsibilities.isEmpty()) {
180             Element responsibilitiesElement = renderer.renderElement(parent, RESPONSIBILITIES);
181             for (RuleResponsibilityBo ruleResponsibility : responsibilities) {
182                 Element respElement = renderer.renderElement(responsibilitiesElement, RESPONSIBILITY);
183                 renderer.renderTextElement(respElement, RESPONSIBILITY_ID, "" + ruleResponsibility.getResponsibilityId());
184                 if (ruleResponsibility.isUsingPrincipal()) {
185 				    renderer.renderTextElement(respElement, PRINCIPAL_NAME, ruleResponsibility.getPrincipal().getPrincipalName());
186 				} else if (ruleResponsibility.isUsingGroup()) {
187 					Group group = ruleResponsibility.getGroup();
188 				    Element groupElement = renderer.renderTextElement(respElement, GROUP_NAME, group.getName());
189 				    groupElement.setAttribute(NAMESPACE, group.getNamespaceCode());
190 				} else if (ruleResponsibility.isUsingRole()) {
191 				    renderer.renderTextElement(respElement, ROLE, ruleResponsibility.getRuleResponsibilityName());
192 				    renderer.renderTextElement(respElement, APPROVE_POLICY, ruleResponsibility.getApprovePolicy());
193 				}
194                 if (!StringUtils.isBlank(ruleResponsibility.getActionRequestedCd())) {
195                 	renderer.renderTextElement(respElement, ACTION_REQUESTED, ruleResponsibility.getActionRequestedCd());
196                 }
197                 if (ruleResponsibility.getPriority() != null) {
198                 	renderer.renderTextElement(respElement, PRIORITY, ruleResponsibility.getPriority().toString());
199                 }
200             }
201         }
202     }
203     
204     //below are for exporting rule delegations in rule exportation
205     private void exportRuleDelegations(Element rootElement, RuleBaseValues rule){
206 		List<RuleDelegationBo> ruleDelegationDefaults = KEWServiceLocator.getRuleDelegationService().findByDelegateRuleId(rule.getId());
207 		for(RuleDelegationBo dele : ruleDelegationDefaults){
208 			if (LOG.isInfoEnabled()) {
209 				LOG.info("*******delegates********\t"  +  dele.getRuleDelegationId()) ;
210 			}
211 			exportRuleDelegation(rootElement, dele);	
212 		}
213     }
214     
215     private void exportRuleDelegation(Element parent, RuleDelegationBo ruleDelegation) {
216     	Element ruleDelegationElement = renderer.renderElement(parent, RULE_DELEGATION);
217     	exportRuleDelegationParentResponsibility(ruleDelegationElement, ruleDelegation);
218     	renderer.renderTextElement(ruleDelegationElement, DELEGATION_TYPE, ruleDelegation.getDelegationType().getCode());
219     	exportRule(ruleDelegationElement, ruleDelegation.getDelegationRule());
220     }
221     
222     private void exportRuleDelegationParentResponsibility(Element parent, RuleDelegationBo delegation) {
223         Element parentResponsibilityElement = renderer.renderElement(parent, PARENT_RESPONSIBILITY);
224         RuleResponsibilityBo ruleResponsibility = KEWServiceLocator.getRuleService().findRuleResponsibility(delegation.getResponsibilityId());
225         renderer.renderTextElement(parentResponsibilityElement, PARENT_RULE_NAME, ruleResponsibility.getRuleBaseValues().getName());
226         if (ruleResponsibility.isUsingPrincipal()) {
227         	Principal principal = ruleResponsibility.getPrincipal();
228         	renderer.renderTextElement(parentResponsibilityElement, PRINCIPAL_NAME, principal.getPrincipalName());
229         } else if (ruleResponsibility.isUsingGroup()) {
230         	Group group = ruleResponsibility.getGroup();
231         	Element groupElement = renderer.renderElement(parentResponsibilityElement, GROUP_NAME);
232         	groupElement.setText(group.getName());
233         	groupElement.setAttribute(NAMESPACE, group.getNamespaceCode());
234         } else if (ruleResponsibility.isUsingRole()) {
235         	renderer.renderTextElement(parentResponsibilityElement, ROLE, ruleResponsibility.getRuleResponsibilityName());
236         } else {
237         	throw new RiceRuntimeException("Encountered a rule responsibility when exporting with an invalid type of '" + ruleResponsibility.getRuleResponsibilityType());
238         }
239     }
240 
241 }