View Javadoc

1   /*
2    * Copyright 2005-2007 The Kuali Foundation
3    *
4    *
5    * Licensed under the Educational Community License, Version 2.0 (the "License");
6    * you may not use this file except in compliance with the License.
7    * You may obtain a copy of the License at
8    *
9    * http://www.opensource.org/licenses/ecl2.php
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.kuali.rice.kew.xml.export;
18  
19  import java.io.BufferedInputStream;
20  import java.io.ByteArrayInputStream;
21  import java.io.FileInputStream;
22  import java.util.ArrayList;
23  import java.util.Calendar;
24  import java.util.HashSet;
25  import java.util.Iterator;
26  import java.util.List;
27  import java.util.Set;
28  
29  import org.apache.commons.lang.StringUtils;
30  import org.apache.commons.lang.time.DateUtils;
31  import org.junit.Test;
32  import org.kuali.rice.kew.export.ExportDataSet;
33  import org.kuali.rice.kew.rule.RuleBaseValues;
34  import org.kuali.rice.kew.rule.RuleDelegation;
35  import org.kuali.rice.kew.rule.RuleExtension;
36  import org.kuali.rice.kew.rule.RuleExtensionValue;
37  import org.kuali.rice.kew.rule.RuleResponsibility;
38  import org.kuali.rice.kew.rule.web.WebRuleUtils;
39  import org.kuali.rice.kew.service.KEWServiceLocator;
40  import org.kuali.rice.test.ClearDatabaseLifecycle;
41  
42  
43  /**
44   * Tests the RuleXmlExporter by importing XML, exporting it, and then re-importing the xml.<br><br>
45   *
46   * NOTE: It's important to note that the success of this test depends on all of the Rules in any
47   * XML having unique descriptions as this is the only way for the test to identify
48   * the rules from the original imported XML and the XML imported from the export.
49   *
50   * @author Kuali Rice Team (rice.collab@kuali.org)
51   */
52  public class RuleXmlExporterTest extends XmlExporterTestCase {
53  
54  	@Test public void testExport() throws Exception {
55          loadXmlFile("org/kuali/rice/kew/actions/ActionsConfig.xml");
56          loadXmlStream(new FileInputStream(getBaseDir() + "/src/test/resources/org/kuali/rice/kew/batch/data/RuleAttributeContent.xml"));
57          loadXmlStream(new FileInputStream(getBaseDir() + "/src/test/resources/org/kuali/rice/kew/batch/data/RuleTemplateContent.xml"));
58          loadXmlStream(new FileInputStream(getBaseDir() + "/src/test/resources/org/kuali/rice/kew/batch/data/DocumentTypeContent.xml"));
59          loadXmlStream(new FileInputStream(getBaseDir() + "/src/test/resources/org/kuali/rice/kew/batch/data/RuleContent.xml"));
60          assertRuleBaseValuesStateIndependence();
61          assertExport();
62      }
63  
64      /**
65       * Note that the assertion here will fail if you have multiple rules with the same description.
66       */
67      protected void assertExport() throws Exception {
68          // export all existing rules and their dependencies (document types, rule templates, rule attributes)
69          List oldRules = KEWServiceLocator.getRuleService().fetchAllRules(true);
70          assertAllRulesHaveUniqueNames(oldRules);
71          List oldRuleDelegations = KEWServiceLocator.getRuleDelegationService().findAllCurrentRuleDelegations();
72          assertAllRuleDelegationsHaveUniqueNames(oldRuleDelegations);
73  
74          ExportDataSet dataSet = new ExportDataSet();
75          dataSet.getRules().addAll(oldRules);
76          dataSet.getRuleDelegations().addAll(oldRuleDelegations);
77          dataSet.getDocumentTypes().addAll(KEWServiceLocator.getDocumentTypeService().findAllCurrent());
78          dataSet.getRuleTemplates().addAll(KEWServiceLocator.getRuleTemplateService().findAll());
79          dataSet.getRuleAttributes().addAll(KEWServiceLocator.getRuleAttributeService().findAll());
80          byte[] xmlBytes = KEWServiceLocator.getXmlExporterService().export(dataSet);
81          assertTrue("XML should be non empty.", xmlBytes != null && xmlBytes.length > 0);
82          
83          // now clear the tables
84          ClearDatabaseLifecycle clearLifeCycle = new ClearDatabaseLifecycle();
85          clearLifeCycle.getTablesToClear().add("KREW_RULE_T");
86          clearLifeCycle.getTablesToClear().add("KREW_RULE_RSP_T");
87          clearLifeCycle.getTablesToClear().add("KREW_DLGN_RSP_T");
88          clearLifeCycle.getTablesToClear().add("KREW_RULE_ATTR_T");
89          clearLifeCycle.getTablesToClear().add("KREW_RULE_TMPL_T");
90          clearLifeCycle.getTablesToClear().add("KREW_DOC_TYP_T");
91          clearLifeCycle.start();
92          new ClearCacheLifecycle().stop();
93  
94          // import the exported xml
95          loadXmlStream(new BufferedInputStream(new ByteArrayInputStream(xmlBytes)));
96  
97          List newRules = KEWServiceLocator.getRuleService().fetchAllRules(true);
98          assertEquals("Should have same number of old and new Rules.", oldRules.size(), newRules.size());
99          for (Iterator iterator = oldRules.iterator(); iterator.hasNext();) {
100             RuleBaseValues oldRule = (RuleBaseValues) iterator.next();
101             boolean foundRule = false;
102             for (Iterator iterator2 = newRules.iterator(); iterator2.hasNext();) {
103                 RuleBaseValues newRule = (RuleBaseValues) iterator2.next();
104                 if (oldRule.getDescription().equals(newRule.getDescription())) {
105                     assertRuleExport(oldRule, newRule);
106                     foundRule = true;
107                 }
108             }
109             assertTrue("Could not locate the new rule for description " + oldRule.getDescription(), foundRule);
110         }
111         
112         List newRuleDelegations = KEWServiceLocator.getRuleDelegationService().findAllCurrentRuleDelegations();
113         assertDelegations(oldRuleDelegations, newRuleDelegations);
114     }
115     
116     /**
117      * verifies that rule exports are the same regardless of whether the rule is ready for render, or
118      * for persistance.
119      */
120     protected void assertRuleBaseValuesStateIndependence() throws Exception {
121     	for (Object o : KEWServiceLocator.getRuleService().fetchAllRules(true)) {
122         	RuleBaseValues rule = (RuleBaseValues)o;
123         	ExportDataSet dataSet = new ExportDataSet();
124         	dataSet.getRules().add(rule);
125         	
126         	// first, do a conversion in the just-loaded state:
127         	byte[] saveXmlBytes = KEWServiceLocator.getXmlExporterService().export(dataSet);
128         	String saveStr = new String(saveXmlBytes);
129         	
130         	// now, convert for render:
131         	WebRuleUtils.populateRuleMaintenanceFields(rule);
132         	
133         	// do another conversion in the ready-for-render state:
134         	byte[] loadXmlBytes = KEWServiceLocator.getXmlExporterService().export(dataSet);
135         	String loadStr = new String(loadXmlBytes);
136         	
137         	// check that the results are identical:
138         	assertTrue("The load/render state of the RuleBaseValues shouldn't effect the export: \n" + 
139         			saveStr + "\n\n != \n\n" + loadStr, 
140         			StringUtils.equals(saveStr, loadStr));
141         }
142     }
143 
144     private void assertRuleExport(RuleBaseValues oldRule, RuleBaseValues newRule) {
145         assertFalse("Ids should be different.", oldRule.getRuleBaseValuesId().equals(newRule.getRuleBaseValuesId()));
146         assertEquals(oldRule.getActiveInd(), newRule.getActiveInd());
147         assertEquals(DateUtils.round(oldRule.getActivationDate(), Calendar.DATE), DateUtils.round(newRule.getActivationDate(), Calendar.DATE));
148         assertEquals(oldRule.getName(), newRule.getName());
149         assertEquals(oldRule.getCurrentInd(), newRule.getCurrentInd());
150         assertEquals(oldRule.getDeactivationDate(), newRule.getDeactivationDate());
151         assertEquals(oldRule.getDelegateRule(), newRule.getDelegateRule());
152         assertEquals(oldRule.getDescription(), newRule.getDescription());
153         assertEquals(oldRule.getDocTypeName(), newRule.getDocTypeName());
154         
155         if (oldRule.getFromDate() == null) {
156         	assertNull(newRule.getFromDate());
157         } else {
158         	assertEquals(DateUtils.round(oldRule.getFromDate(), Calendar.DATE), DateUtils.round(newRule.getFromDate(), Calendar.DATE));
159         }
160         if (oldRule.getToDate() == null) {
161         	assertNull(newRule.getToDate());
162         } else {
163         	assertEquals(DateUtils.round(oldRule.getToDate(), Calendar.DATE), DateUtils.round(newRule.getToDate(), Calendar.DATE));
164         }
165         assertEquals(oldRule.getFromDateString(),newRule.getFromDateString() );
166         assertEquals(oldRule.getToDateString(),newRule.getToDateString() );
167         
168         assertEquals(oldRule.getForceAction(), newRule.getForceAction());
169         
170         if(!oldRule.getDelegateRule().booleanValue())
171         	assertEquals(oldRule.getPreviousVersionId(), newRule.getPreviousVersionId());
172         
173         assertEquals(oldRule.getRouteHeaderId(), newRule.getRouteHeaderId());
174         
175         if (oldRule.getRuleTemplate() == null) {
176             assertNull(newRule.getRuleTemplate());
177         } else {
178             assertEquals(oldRule.getRuleTemplate().getName(), newRule.getRuleTemplate().getName());
179         }
180         if (oldRule.getRuleExpressionDef() == null) {
181             assertNull(newRule.getRuleExpressionDef());
182         } else {
183             assertEquals(oldRule.getRuleExpressionDef().getExpression(), newRule.getRuleExpressionDef().getExpression());
184             assertEquals(oldRule.getRuleExpressionDef().getType(), newRule.getRuleExpressionDef().getType());
185         }
186         if(!oldRule.getDelegateRule().booleanValue())
187         	assertEquals(oldRule.getVersionNbr(), newRule.getVersionNbr());
188 
189         assertRuleExtensions(oldRule.getRuleExtensions(), newRule.getRuleExtensions());
190         assertResponsibilities(oldRule.getResponsibilities(), newRule.getResponsibilities());
191 
192 
193     }
194 
195     private void assertRuleExtensions(List oldRuleExtensions, List newRuleExtensions) {
196         assertEquals(oldRuleExtensions.size(), newRuleExtensions.size());
197         for (Iterator iterator = oldRuleExtensions.iterator(); iterator.hasNext();) {
198             RuleExtension oldExtension = (RuleExtension) iterator.next();
199             boolean foundExtension = false;
200             for (Iterator iterator2 = newRuleExtensions.iterator(); iterator2.hasNext();) {
201                 RuleExtension newExtension = (RuleExtension) iterator2.next();
202                 if (oldExtension.getRuleTemplateAttribute().getRuleAttribute().getName().equals(newExtension.getRuleTemplateAttribute().getRuleAttribute().getName()) &&
203                         oldExtension.getRuleTemplateAttribute().getRuleTemplate().getName().equals(newExtension.getRuleTemplateAttribute().getRuleTemplate().getName())) {
204                         assertExtensionValues(oldExtension.getExtensionValues(), newExtension.getExtensionValues());
205                         foundExtension = true;
206                         break;
207                 }
208             }
209             assertTrue("Could not locate rule extension.", foundExtension);
210         }
211     }
212 
213     private void assertExtensionValues(List oldExtensionValues, List newExtensionValues) {
214         assertEquals(oldExtensionValues.size(), newExtensionValues.size());
215         for (Iterator iterator = oldExtensionValues.iterator(); iterator.hasNext();) {
216             RuleExtensionValue oldValue = (RuleExtensionValue) iterator.next();
217             boolean foundValue = false;
218             for (Iterator iterator2 = oldExtensionValues.iterator(); iterator2.hasNext();) {
219                 RuleExtensionValue newValue = (RuleExtensionValue) iterator2.next();
220                 if (oldValue.getKey().equals(newValue.getKey())) {
221                     assertEquals(oldValue.getValue(), newValue.getValue());
222                     foundValue = true;
223                     break;
224                 }
225             }
226             assertTrue("Could not locate extension value.", foundValue);
227         }
228     }
229 
230     private void assertResponsibilities(List oldResps, List newResps) {
231         assertEquals(oldResps.size(), newResps.size());
232         for (Iterator iterator = oldResps.iterator(); iterator.hasNext();) {
233             RuleResponsibility oldResp = (RuleResponsibility) iterator.next();
234             boolean foundResp = false;
235             for (Iterator iterator2 = newResps.iterator(); iterator2.hasNext();) {
236                 RuleResponsibility newResp = (RuleResponsibility) iterator2.next();
237                 if (oldResp.getRuleResponsibilityName().equals(newResp.getRuleResponsibilityName())) {
238                     assertEquals(oldResp.getActionRequestedCd(), newResp.getActionRequestedCd());
239                     assertEquals(oldResp.getApprovePolicy(), newResp.getApprovePolicy());
240                     assertEquals(oldResp.getResolvedRoleName(), newResp.getResolvedRoleName());
241                     assertEquals(oldResp.getRole(), newResp.getRole());
242                     assertEquals(oldResp.getRuleResponsibilityType(), newResp.getRuleResponsibilityType());
243                     assertEquals(oldResp.getPriority(), newResp.getPriority());
244                     foundResp = true;
245                     break;
246                 }
247             }
248             assertTrue("Could not locate responsibility "+oldResp.getRuleResponsibilityName()+" on rule "+oldResp.getRuleBaseValues().getDescription(), foundResp);
249         }
250     }
251 
252     private void assertDelegations(List oldDelegations, List newDelegations) {
253         assertEquals(oldDelegations.size(), newDelegations.size());
254         for (Iterator iterator = oldDelegations.iterator(); iterator.hasNext();) {
255             RuleDelegation oldDelegation = (RuleDelegation) iterator.next();
256             boolean foundDelegation = false;
257             for (Iterator iterator2 = newDelegations.iterator(); iterator2.hasNext();) {
258                 RuleDelegation newDelegation = (RuleDelegation) iterator2.next();
259                 if (oldDelegation.getDelegationRuleBaseValues().getName().equals(newDelegation.getDelegationRuleBaseValues().getName())) {
260                     assertEquals(oldDelegation.getDelegationType(), newDelegation.getDelegationType());
261                     assertFalse(oldDelegation.getResponsibilityId().equals(newDelegation.getResponsibilityId()));
262                     assertRuleExport(oldDelegation.getDelegationRuleBaseValues(), newDelegation.getDelegationRuleBaseValues());
263                     foundDelegation = true;
264                     break;
265                 }
266             }
267             assertTrue("Could not locate delegation.", foundDelegation);
268         }
269     }
270 
271     private void assertAllRulesHaveUniqueNames(List rules) throws Exception {
272     	Set<String> ruleDescriptions = new HashSet<String>();
273     	for (Iterator iterator = rules.iterator(); iterator.hasNext();) {
274 			RuleBaseValues rule = (RuleBaseValues) iterator.next();
275 			assertFalse("Found 2 rules with the same description '" + rule.getDescription() + "'.  " +
276 					"In order for this test to work, all rules in the configuration files must have unique descriptions.",
277 					ruleDescriptions.contains(rule.getDescription()));
278 			ruleDescriptions.add(rule.getDescription());
279 		}
280     }
281     
282     private void assertAllRuleDelegationsHaveUniqueNames(List<RuleDelegation> ruleDelegations) throws Exception {
283     	List<RuleBaseValues> rules = new ArrayList<RuleBaseValues>();
284     	for (RuleDelegation ruleDelegation : ruleDelegations) {
285     		rules.add(ruleDelegation.getDelegationRuleBaseValues());
286     	}
287     	assertAllRulesHaveUniqueNames(rules);
288     }
289 
290 }