View Javadoc

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