001    /**
002     * Copyright 2005-2011 The Kuali Foundation
003     *
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.opensource.org/licenses/ecl2.php
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.rice.kew.rule.xmlrouting;
017    
018    import org.junit.Test;
019    import org.kuali.rice.core.api.uif.RemotableAttributeError;
020    import org.kuali.rice.kew.api.WorkflowDocument;
021    import org.kuali.rice.kew.api.WorkflowDocumentFactory;
022    import org.kuali.rice.kew.api.document.attribute.WorkflowAttributeDefinition;
023    import org.kuali.rice.kew.api.rule.RuleExtension;
024    import org.kuali.rice.kew.docsearch.xml.StandardGenericXMLSearchableAttribute;
025    import org.kuali.rice.kew.api.exception.WorkflowException;
026    import org.kuali.rice.kew.exception.WorkflowServiceError;
027    import org.kuali.rice.kew.routeheader.DocumentContent;
028    import org.kuali.rice.kew.routeheader.StandardDocumentContent;
029    import org.kuali.rice.kew.rule.RuleExtensionBo;
030    import org.kuali.rice.kew.rule.RuleExtensionValue;
031    import org.kuali.rice.kew.rule.bo.RuleAttribute;
032    import org.kuali.rice.kew.rule.bo.RuleTemplateAttributeBo;
033    import org.kuali.rice.kew.test.KEWTestCase;
034    import org.kuali.rice.kns.web.ui.Field;
035    import org.kuali.rice.kns.web.ui.Row;
036    import org.w3c.dom.Element;
037    import org.xml.sax.InputSource;
038    
039    import javax.xml.parsers.DocumentBuilderFactory;
040    import javax.xml.xpath.XPath;
041    import javax.xml.xpath.XPathConstants;
042    import javax.xml.xpath.XPathFactory;
043    import java.io.BufferedReader;
044    import java.io.StringReader;
045    import java.util.ArrayList;
046    import java.util.HashMap;
047    import java.util.Iterator;
048    import java.util.List;
049    import java.util.Map;
050    
051    import static org.junit.Assert.assertFalse;
052    import static org.junit.Assert.assertTrue;
053    
054    public class StandardGenericXMLRuleAttributeTest extends KEWTestCase {
055    
056            private DocumentContent docContent;
057            private StandardGenericXMLRuleAttribute attribute;
058            private List<RuleExtension> extensions;
059    
060            public void setUp() throws Exception {
061            super.setUp();
062                    attribute = new StandardGenericXMLRuleAttribute();
063                    String documentcontent =
064                            "<documentContent>" +
065                                    "<attributeContent>"+
066                                            "<xmlContent>"+
067                                                    "<fieldDef name=\"givenname\">"+
068                                                            "<value>Dave</value>"+
069                                                    "</fieldDef>"+
070                                                    "<fieldDef name=\"gender\">"+
071                                                            "<value>female</value>"+
072                                                    "</fieldDef>"+
073                                                    "<fieldDef name=\"color\">"+
074                                                            "<value>green</value>"+
075                                                    "</fieldDef>"+
076                                                    "<fieldDef name=\"totalDollar\">"+
077                                                            "<value>500</value>"+
078                                                    "</fieldDef>"+
079                                            "</xmlContent>"+
080                                            "<xmlContent>"+
081                                                    "<fieldDef name=\"givenname\">"+
082                                                            "<value>Jane</value>"+
083                                                    "</fieldDef>"+
084                                                    "<fieldDef name=\"gender\">"+
085                                                            "<value>female</value>"+
086                                                    "</fieldDef>"+
087                                                    "<fieldDef name=\"color\">"+
088                                                            "<value>blue</value>"+
089                                                    "</fieldDef>"+
090                                                    "<fieldDef name=\"totalDollar\">"+
091                                                            "<value>400</value>"+
092                                                    "</fieldDef>"+
093                                            "</xmlContent>"+
094                                    "</attributeContent>"+
095                                "</documentContent>";
096    
097                    String routingConfig =
098                            "<routingConfig>"+
099                                    "<globalEvaluations>" +
100                                            "<xpathexpression>//fieldDef/value != 'Nothing'</xpathexpression>" +
101                                    "</globalEvaluations>"+
102    
103                                    "<fieldDef name=\"givenname\" title=\"First name\" workflowType=\"ALL\">"+
104                                            "<value>Joe</value>"+
105                                            "<display>"+
106                                                    "<type>text</type>"+
107                                                    "<meta><name>size</name><value>20</value></meta>"+
108                                            "</display>" +
109                                            "<validation required=\"true\">"+
110                                                    "<regex>^[a-zA-Z ]+$</regex>"+
111                                                    "<message>Invalid first name</message>"+
112                                    "</validation>"+
113                                            "<fieldEvaluation><xpathexpression>//xmlContent/fieldDef[@name='givenname']/value = wf:ruledata('givenname')</xpathexpression></fieldEvaluation>"+
114                                    "</fieldDef>"+
115                                    "<fieldDef name=\"gender\" title=\"Gender\" workflowType=\"ALL\">"+
116                                            "<value>male</value>"+
117                                            "<display>"+
118                                                    "<type>radio</type>"+
119                                                    "<values title=\"Male\">male</values>"+
120                                                    "<values title=\"Female\">female</values>"+
121                                            "</display>"+
122                                    "<validation required=\"true\">" +
123                                            "<regex>(male|female)</regex>"+
124                                            "<message>Invalid gender</message>"+
125                                    "</validation>"+
126                                            "<fieldEvaluation><xpathexpression>//xmlContent/fieldDef[@name='gender']/value = wf:ruledata('gender')</xpathexpression></fieldEvaluation>"+
127                                    "</fieldDef>"+
128                                    "<fieldDef name=\"color\" title=\"Color\" workflowType=\"ALL\">" +
129                                            "<value>blue</value>" +
130                                            "<display>" +
131                                                    "<type>select</type>" +
132                                                    "<values title=\"Red\">red</values>" +
133                                                    "<values title=\"Green\">green</values>" +
134                                                    "<values title=\"Blue\" selected=\"true\">blue</values>" +
135                                            "</display>" +
136                                            "<validation required=\"true\">"+
137                                            "<regex>(red|green|blue|)</regex>"+
138                                            "<message>Invalid color</message>"+
139                                    "</validation>"+
140                                            "<fieldEvaluation><xpathexpression>//xmlContent/fieldDef[@name='color']/value = wf:ruledata('color')</xpathexpression></fieldEvaluation>"+
141                                    "</fieldDef>"+
142                                    "<fieldDef name=\"maxDollar\" title=\"Max dollar\" workflowType=\"RULE\">" +
143                                            "<display>" +
144                                                    "<type>text</type>" +
145                                            "</display>" +
146                                            "<fieldEvaluation><xpathexpression>//xmlContent/fieldDef[@name='totalDollar']/value &lt;= wf:ruledata('maxDollar')</xpathexpression></fieldEvaluation>"+
147                                    "</fieldDef>"+
148                                    "<fieldDef name=\"minDollar\" title=\"Min dollar\" workflowType=\"RULE\">" +
149                                            "<display>" +
150                                                    "<type>text</type>" +
151                                            "</display>" +
152                                            "<fieldEvaluation><xpathexpression>//xmlContent/fieldDef[@name='totalDollar']/value &gt;= wf:ruledata('minDollar')</xpathexpression></fieldEvaluation>"+
153                                "</fieldDef>"+
154                                    "<fieldDef name=\"totalDollar\" title=\"Total dollar\" workflowType=\"REPORT\">" +
155                                            "<display>" +
156                                                    "<type>text</type>" +
157                                            "</display>" +
158                            "</fieldDef>" +
159                "</routingConfig>";
160    
161                    docContent = new StandardDocumentContent(documentcontent);
162                    RuleAttribute ruleAttribute = new RuleAttribute();
163                    ruleAttribute.setXmlConfigData(routingConfig);
164                    ruleAttribute.setName("MyUniqueRuleAttribute1");
165            ruleAttribute.setType("SearchableXmlAttribute");
166            ruleAttribute.setResourceDescriptor(StandardGenericXMLSearchableAttribute.class.getName());
167                    attribute.setExtensionDefinition(RuleAttribute.to(ruleAttribute));
168            }
169    
170            @Test public void testValidateRoutingData(){
171            Map<String, String> paramMap = new HashMap<String, String>();
172                    paramMap.put("givenname", "Dave");
173                    paramMap.put("gender", "female");
174                    paramMap.put("color", "green");
175                    paramMap.put("totalDollar", "500");
176    
177                    assertTrue("Errors found", attribute.validateRoutingData(paramMap).isEmpty());
178            }
179    
180            @Test public void testValidateRuleData(){
181            Map<String, String> paramMap = new HashMap<String, String>();
182                    paramMap.put("givenname", "Dave");
183                    paramMap.put("gender", "female");
184                    paramMap.put("color", "green");
185                    paramMap.put("totalDollar", "500");
186    
187                    assertTrue("Errors found", attribute.validateRuleData(paramMap).isEmpty());
188    
189                    paramMap = new HashMap<String, String>();
190                    paramMap.put("givenname", "4444");
191                    paramMap.put("gender", "crap");
192                    paramMap.put("color", "green");
193                    paramMap.put("totalDollar", "500");
194    
195            assertFalse("Error list should contain at least one error.", attribute.validateRuleData(paramMap).isEmpty());
196    
197                    paramMap = new HashMap<String, String>();
198                    paramMap.put("givenname", "");
199                    paramMap.put("gender", "female");
200                    paramMap.put("color", "green");
201                    paramMap.put("totalDollar", "500");
202    
203                    assertFalse("givenname should be required.", attribute.validateRuleData(paramMap).isEmpty());
204            }
205    
206        @Test public void testRuleDataAttributeErrorTypesAreConformant() {
207            Map<String, String> paramMap = new HashMap<String, String>();
208                    paramMap.put("givenname", "4444");
209                    paramMap.put("gender", "crap");
210                    paramMap.put("color", "green");
211                    paramMap.put("totalDollar", "500");
212    
213                    List<RemotableAttributeError> errors = attribute.validateRuleData(paramMap);
214            assertFalse("Error list should contain at least one error.", errors.isEmpty());
215            for (Object e: errors) {
216                assertTrue(RemotableAttributeError.class.isAssignableFrom(e.getClass()));
217            }
218        }
219    
220        @Test public void testRoutingDataAttributeErrorTypesAreConformant(){
221            Map<String, String> paramMap = new HashMap<String, String>();
222            paramMap.put("givenname", "4444");
223            paramMap.put("gender", "crap");
224            paramMap.put("color", "green");
225            paramMap.put("totalDollar", "500");
226    
227            List<RemotableAttributeError> errors = attribute.validateRoutingData(paramMap);
228            assertFalse("Error list should contain at least one error.", errors.isEmpty());
229            for (Object e: errors) {
230                assertTrue(RemotableAttributeError.class.isAssignableFrom(e.getClass()));
231            }
232        }
233    
234        /**
235         * Tests SGXA attribute matching behavior with extension value keys that do not necessarily match
236         * a field defined in the attribute
237         */
238        @Test public void testNonMatchingExtensionKey() throws WorkflowException {
239            loadXmlFile("TestExtensionValueMatching.xml");
240            WorkflowDocument doc = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("arh14"), "TestDocument");
241    
242            WorkflowAttributeDefinition.Builder attr = WorkflowAttributeDefinition.Builder.create(StandardGenericXMLRuleAttribute.class.getName());
243            attr.setAttributeName("Attr1");
244            // expected to match RuleTemplate with extension value: value='1' with xpath expression /xmlRouting/field[@name=attr1] = wf:ruledata('value')
245            attr.addPropertyDefinition("attr1", "2");
246            doc.addAttributeDefinition(attr.build());
247    
248            doc.route("");
249    
250            String id = doc.getDocumentId();
251    
252            doc = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("user1"), id);
253            assertTrue("Request should have been generated to user1", doc.isApprovalRequested());
254    
255            doc = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("user2"), id);
256            assertTrue("Expected approval request to user2", doc.isApprovalRequested());
257        }
258    
259            /*
260             * Test method for 'org.kuali.rice.kew.rule.xmlrouting.StandardGenericXMLRuleAttribute.isMatch(DocumentContent, List)'
261             */
262            @Test public void testIsMatch() {
263                    RuleExtensionBo extension = new RuleExtensionBo();
264    
265                    List<RuleExtensionValue> values = new ArrayList<RuleExtensionValue>();
266                    RuleExtensionValue value = new RuleExtensionValue();
267                    value.setKey("givenname");
268                    value.setValue("Dave");
269                    values.add(value);
270    
271                    RuleExtensionValue value2 = new RuleExtensionValue();
272                    value2.setKey("gender");
273                    value2.setValue("female");
274                    values.add(value2);
275    
276                    RuleExtensionValue value3 = new RuleExtensionValue();
277                    value3.setKey("color");
278                    value3.setValue("green");
279                    values.add(value3);
280    
281                    extension.setExtensionValues(values);
282                    RuleTemplateAttributeBo ruleTemplateAttribute = new RuleTemplateAttributeBo();
283    
284                    RuleAttribute ruleAttribute = new RuleAttribute();
285                    ruleAttribute.setName("MyUniqueRuleAttribute1");
286            ruleAttribute.setType("RuleAttribute");
287            ruleAttribute.setResourceDescriptor("noClass");
288    
289                    ruleTemplateAttribute.setRuleAttribute(ruleAttribute);
290            ruleTemplateAttribute.setRuleTemplateId("ruleTemplateId1");
291            ruleTemplateAttribute.setDisplayOrder(new Integer(1));
292                    extension.setRuleTemplateAttribute(ruleTemplateAttribute);
293                    RuleExtensionBo extension2 = new RuleExtensionBo();
294    
295                    List values2 = new ArrayList();
296                    RuleExtensionValue valueNew = new RuleExtensionValue();
297                    valueNew.setKey("givenname");
298                    valueNew.setValue("Jack");
299    
300                    RuleExtensionValue minDollar = new RuleExtensionValue();
301                    minDollar.setKey("minDollar");
302                    minDollar.setValue("300");
303            RuleExtensionValue maxDollar = new RuleExtensionValue();
304            maxDollar.setKey("maxDollar");
305            maxDollar.setValue("600");
306    
307    
308                    values2.add(valueNew);
309                    values2.add(minDollar);
310                    values2.add(maxDollar);
311                    extension2.setExtensionValues(values2);
312                    RuleTemplateAttributeBo ruleTemplateAttribute2 = new RuleTemplateAttributeBo();
313    
314                    RuleAttribute ruleAttribute2 = new RuleAttribute();
315                    ruleAttribute2.setName("MyUniqueRuleAttribute2");
316            ruleAttribute2.setType("RuleAttribute");
317            ruleAttribute2.setResourceDescriptor("noClass");
318    
319                    ruleTemplateAttribute2.setRuleAttribute(ruleAttribute2);
320            ruleTemplateAttribute2.setRuleTemplateId("ruleTemplateId2");
321            ruleTemplateAttribute2.setDisplayOrder(new Integer(2));
322                    extension2.setRuleTemplateAttribute(ruleTemplateAttribute2);
323    
324                    extensions = new ArrayList();
325                    extensions.add(RuleExtensionBo.to(extension));
326                    extensions.add(RuleExtensionBo.to(extension2));
327    
328                    assertTrue("Givenname did not match Dave, gender did not match female, or color did not match green", attribute.isMatch(docContent, extensions));
329    
330                    extension = new RuleExtensionBo();
331                    values = new ArrayList();
332                    RuleExtensionValue value4 = new RuleExtensionValue();
333                    value4.setKey("givenname");
334                    value4.setValue("Dave");
335                    values.add(value4);
336    
337                    RuleExtensionValue value5 = new RuleExtensionValue();
338                    value5.setKey("gender");
339                    value5.setValue("male");
340                    values.add(value5);
341    
342                    RuleExtensionValue value6 = new RuleExtensionValue();
343                    value6.setKey("color");
344                    value6.setValue("green");
345                    values.add(value6);
346    
347                    extension.setExtensionValues(values);
348                    ruleTemplateAttribute = new RuleTemplateAttributeBo();
349    
350                    ruleAttribute = new RuleAttribute();
351                    ruleAttribute.setName("MyUniqueRuleAttribute1");
352            ruleAttribute.setType("RuleAttribute");
353            ruleAttribute.setResourceDescriptor("noClass");
354    
355    
356                    ruleTemplateAttribute.setRuleAttribute(ruleAttribute);
357            ruleTemplateAttribute.setRuleTemplateId("ruleTemplateId");
358            ruleTemplateAttribute.setDisplayOrder(new Integer(1));
359                    extension.setRuleTemplateAttribute(ruleTemplateAttribute);
360    
361    
362                    values2 = new ArrayList();
363                    valueNew = new RuleExtensionValue();
364                    valueNew.setKey("givenname");
365                    valueNew.setValue("Jack");
366    
367                    values2.add(valueNew);
368                    extension2.setExtensionValues(values2);
369                    ruleTemplateAttribute2 = new RuleTemplateAttributeBo();
370    
371                    ruleAttribute2 = new RuleAttribute();
372                    ruleAttribute2.setName("MyUniqueRuleAttribute2");
373            ruleAttribute2.setType("RuleAttribute");
374            ruleAttribute2.setResourceDescriptor("noClass");
375    
376    
377                    ruleTemplateAttribute2.setRuleAttribute(ruleAttribute2);
378            ruleTemplateAttribute2.setRuleTemplateId("ruleTemplateId2");
379            ruleTemplateAttribute2.setDisplayOrder(new Integer(2));
380                    extension2.setRuleTemplateAttribute(ruleTemplateAttribute2);
381    
382                    extensions = new ArrayList();
383                    extensions.add(RuleExtensionBo.to(extension));
384                    extensions.add(RuleExtensionBo.to(extension2));
385                    assertFalse("Gender female != male.", attribute.isMatch(docContent, extensions));
386    
387                    ///////
388    
389                    extension = new RuleExtensionBo();
390                    values = new ArrayList();
391    
392                    RuleExtensionValue value7 = new RuleExtensionValue();
393                    value7.setKey("maxDollar");
394                    value7.setValue("500");
395    
396    
397                    RuleExtensionValue value8 = new RuleExtensionValue();
398                    value8.setKey("minDollar");
399                    value8.setValue("100");
400    
401            values.add(value7);
402                    values.add(value8);
403                    extension.setExtensionValues(values);
404                    ruleTemplateAttribute = new RuleTemplateAttributeBo();
405                    ruleAttribute = new RuleAttribute();
406                    ruleAttribute.setName("MyUniqueRuleAttribute1");
407            ruleAttribute.setType("RuleAttribute");
408            ruleAttribute.setResourceDescriptor("noClass");
409    
410                    ruleTemplateAttribute.setRuleAttribute(ruleAttribute);
411            ruleTemplateAttribute.setRuleTemplateId("ruleTemplateId");
412            ruleTemplateAttribute.setDisplayOrder(new Integer(1));
413                    extension.setRuleTemplateAttribute(ruleTemplateAttribute);
414    
415                    values2 = new ArrayList();
416    
417                    valueNew = new RuleExtensionValue();
418                    valueNew.setKey("givenname");
419                    valueNew.setValue("Jack");
420                    values2.add(valueNew);
421    
422                    extension2.setExtensionValues(values2);
423                    ruleTemplateAttribute2 = new RuleTemplateAttributeBo();
424    
425                    ruleAttribute2 = new RuleAttribute();
426                    ruleAttribute2.setName("MyUniqueRuleAttribute2");
427            ruleAttribute2.setType("RuleAttribute");
428            ruleAttribute2.setResourceDescriptor("noClass");
429    
430    
431                    ruleTemplateAttribute2.setRuleAttribute(ruleAttribute2);
432            ruleTemplateAttribute2.setRuleTemplateId("ruleTemplateId2");
433            ruleTemplateAttribute2.setDisplayOrder(new Integer(2));
434                    extension2.setRuleTemplateAttribute(ruleTemplateAttribute2);
435    
436                    extensions = new ArrayList();
437                    extensions.add(RuleExtensionBo.to(extension));
438                    extensions.add(RuleExtensionBo.to(extension2));
439                    assertTrue("Total dollar is greater than the max or less than the min.", attribute.isMatch(docContent, extensions));
440            }
441    
442            /*
443             * Test method for 'org.kuali.rice.kew.rule.xmlrouting.StandardGenericXMLRuleAttribute.getRuleRows()'
444             */
445            @Test public void testGetRuleRows() {
446                    assertTrue("Invalid number of rule rows", attribute.getRuleRows().size() == 5);
447    
448                    String routingConfigWithQuickfinders =
449                            "<routingConfig>"+
450                                    "<globalEvaluations>" +
451                                            "<xpathexpression>//field/value != 'Nothing'</xpathexpression>" +
452                                    "</globalEvaluations>"+
453    
454                                    "<fieldDef name=\"chart\" title=\"Chart\" workflowType=\"ALL\">"+
455                                            "<value>BL</value>"+
456                                            "<display>"+
457                                                    "<type>text</type>"+
458                                                    "<meta><name>size</name><value>20</value></meta>"+
459                                            "</display>" +
460                                            "<fieldEvaluation><xpathexpression>//xmlContent/field[@name='chart']/value = wf:ruledata('chart')</xpathexpression></fieldEvaluation>"+
461                                    "</fieldDef>"+
462                                    "<fieldDef name=\"org\" title=\"Org\" workflowType=\"ALL\">"+
463                                            "<display>"+
464                                                    "<type>text</type>"+
465                                            "</display>" +
466                                            "<lookup businessObjectClass=\"ChartOrgLookupableImplService\">" +
467                                                "<fieldConversions>" +
468                                              "<fieldConversion lookupFieldName=\"fin_coa_cd\" localFieldName=\"chart\"/>" +
469                                                  "<fieldConversion lookupFieldName=\"org_cd\" localFieldName=\"org\"/>" +
470                                                "</fieldConversions>" +
471                                            "</lookup>" +
472                                            "<fieldEvaluation><xpathexpression>//xmlContent/field[@name='gender']/value = wf:ruledata('gender')</xpathexpression></fieldEvaluation>"+
473                                    "</fieldDef>" +
474                "</routingConfig>";
475    
476                    RuleAttribute ruleAttribute = new RuleAttribute();
477                    ruleAttribute.setXmlConfigData(routingConfigWithQuickfinders);
478                    ruleAttribute.setName("MyUniqueRuleAttribute3");
479            ruleAttribute.setType("SearchableXmlAttribute");
480            ruleAttribute.setResourceDescriptor(StandardGenericXMLSearchableAttribute.class.getName());
481                    StandardGenericXMLRuleAttribute myAttribute = new StandardGenericXMLRuleAttribute();
482                    myAttribute.setExtensionDefinition(RuleAttribute.to(ruleAttribute));
483    
484                    for (Iterator iter = myAttribute.getRuleRows().iterator(); iter.hasNext();) {
485                            Row row = (Row) iter.next();
486                            for (Iterator iterator = row.getFields().iterator(); iterator.hasNext();) {
487                                    Field field = (Field) iterator.next();
488                                    if(field.getFieldType().equals(Field.QUICKFINDER)){
489                                            assertTrue("Did not find quickfinder.", true);
490                                    }
491                            }
492                    }
493                    assertTrue("Should have 2 rows and 3 fields: chart, org, and quickfinder.", myAttribute.getRuleRows().size() == 2);
494            }
495    
496            @Test public void testGetRoutingDataRows() {
497                    assertTrue("Invalid number of routing data rows",attribute.getRoutingDataRows().size() == 4);
498            }
499    
500            @Test public void testGetDocContent() {
501                    //test the standard doc content...
502            Map<String, String> paramMap = new HashMap<String, String>();
503                    paramMap.put("givenname", "Dave");
504                    paramMap.put("gender", "female");
505                    paramMap.put("color", "green");
506                    paramMap.put("totalDollar", "500");
507    
508                    attribute.setParamMap(paramMap);
509                    try{
510                            XPath xpath = XPathFactory.newInstance().newXPath();
511                            Element element = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new BufferedReader(new StringReader(attribute.getDocContent())))).getDocumentElement();
512    
513                            String findStuff = "//xmlRouting/field[@name='givenname']/value";
514                            assertTrue("Document content does not contain field givenname with value of Dave.", "Dave".equals(xpath.evaluate(findStuff, element, XPathConstants.STRING)));
515    
516                            findStuff = "//xmlRouting/field[@name='gender']/value";
517                            assertTrue("Document content does not contain field gender with value of female.", "female".equals(xpath.evaluate(findStuff, element, XPathConstants.STRING)));
518    
519                            findStuff = "//xmlRouting/field[@name='color']/value";
520                            assertTrue("Document content does not contain field color with value of green.", "green".equals(xpath.evaluate(findStuff, element, XPathConstants.STRING)));
521    
522                            findStuff = "//xmlRouting/field[@name='totalDollar']/value";
523                            assertTrue("Document content does not contain field totalDollar with value of 500.", "500".equals(xpath.evaluate(findStuff, element, XPathConstants.STRING)));
524                    } catch (Exception e){
525                            e.printStackTrace();
526                    }
527    
528                    // Now test the custom doc content...
529                    String routingConfig =
530                            "<routingConfig>" +
531                                    "<fieldDef name=\"myname\" title=\"First name\" workflowType=\"ALL\">"+
532                                            "<value>Joe</value>"+
533                                            "<display>"+
534                                                    "<type>text</type>"+
535                                                    "<meta><name>size</name><value>20</value></meta>"+
536                                            "</display>"+
537                                            "<fieldEvaluation><xpathexpression>//putWhateverWordsIwantInsideThisTag/myname/value = wf:ruledata('myname')</xpathexpression></fieldEvaluation>"+
538                                    "</fieldDef>"+
539                                    "<fieldDef name=\"theGender\" title=\"Gender\" workflowType=\"ALL\">"+
540                                            "<value>male</value>"+
541                                            "<display>"+
542                                                    "<type>radio</type>"+
543                                                    "<values title=\"Male\">male</values>"+
544                                                    "<values title=\"Female\">female</values>"+
545                                            "</display>"+
546                                            "<fieldEvaluation><xpathexpression>//putWhateverWordsIwantInsideThisTag/theGender/value = wf:ruledata('theGender')</xpathexpression></fieldEvaluation>"+
547                                    "</fieldDef>"+
548                                    "<fieldDef name=\"myFavoriteColor\" title=\"Color\" workflowType=\"ALL\">" +
549                                            "<value>blue</value>" +
550                                            "<display>" +
551                                                    "<type>select</type>" +
552                                                    "<values title=\"Red\">red</values>" +
553                                                    "<values title=\"Green\">green</values>" +
554                                                    "<values title=\"Blue\" selected=\"true\">blue</values>" +
555                                            "</display>" +
556                                            "<fieldEvaluation><xpathexpression>//putWhateverWordsIwantInsideThisTag/myFavoriteColor/value = wf:ruledata('myFavoriteColor')</xpathexpression></fieldEvaluation>"+
557                                    "</fieldDef>"+
558                                    "<fieldDef name=\"maxDollar\" title=\"Max dollar\" workflowType=\"RULE\">" +
559                                            "<display>" +
560                                                    "<type>text</type>" +
561                                            "</display>" +
562                                            "<fieldEvaluation><xpathexpression>//putWhateverWordsIwantInsideThisTag/myMoney/value &lt;= wf:ruledata('maxDollar')</xpathexpression></fieldEvaluation>"+
563                                    "</fieldDef>"+
564                                    "<fieldDef name=\"minDollar\" title=\"Min dollar\" workflowType=\"RULE\">" +
565                                            "<display>" +
566                                                    "<type>text</type>" +
567                                            "</display>" +
568                                            "<fieldEvaluation><xpathexpression>//putWhateverWordsIwantInsideThisTag/myMoney/value &gt;= wf:ruledata('minDollar')</xpathexpression></fieldEvaluation>"+
569                                "</fieldDef>"+
570                                    "<fieldDef name=\"myMoney\" title=\"Total dollar\" workflowType=\"REPORT\">" +
571                                            "<display>" +
572                                                    "<type>text</type>" +
573                                            "</display>" +
574                            "</fieldDef>"+
575    
576                            "<xmlDocumentContent>"+
577                                    "<putWhateverWordsIwantInsideThisTag>"+
578                                            "<myname>"+
579                                                    "<value>%myname%</value>"+
580                                        "</myname>"+
581                                        "<theGender>"+
582                                            "<value>%theGender%</value>"+
583                                            "</theGender>"+
584                                            "<myFavoriteColor>"+
585                                                    "<value>%myFavoriteColor%</value>"+
586                                                    "</myFavoriteColor>"+
587                                            "<myMoney>"+
588                                                    "<value>%myMoney%</value>"+
589                                            "</myMoney>"+
590                                            "</putWhateverWordsIwantInsideThisTag>"+
591                            "</xmlDocumentContent>"+
592                "</routingConfig>";
593                    try {
594                            paramMap = new HashMap<String, String>();
595                            paramMap.put("myname", "jack");
596                            paramMap.put("theGender", "male");
597                            paramMap.put("myFavoriteColor", "blue");
598                            paramMap.put("myMoney", "10");
599    
600                            attribute.setParamMap(paramMap);
601    
602                            RuleAttribute ruleAttribute = new RuleAttribute();
603                            ruleAttribute.setXmlConfigData(routingConfig);
604                            ruleAttribute.setName("MyUniqueRuleAttribute2");
605                            attribute.setExtensionDefinition(RuleAttribute.to(ruleAttribute));
606    
607                            String docContent = attribute.getDocContent();
608                            assertTrue("DocContent was not found.", docContent != null && docContent.length() > 0);
609    
610    
611                            XPath xpath = XPathFactory.newInstance().newXPath();
612                            Element foundDocContent = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new BufferedReader(new StringReader(docContent)))).getDocumentElement();
613    
614                            String findStuff = "//putWhateverWordsIwantInsideThisTag/myMoney/value";
615                            assertTrue("Document content does not contain field myMoney with a value of 10.", "10".equals(xpath.evaluate(findStuff, foundDocContent, XPathConstants.STRING)));
616    
617                            findStuff = "//putWhateverWordsIwantInsideThisTag/myFavoriteColor/value";
618                            assertTrue("Document content does not contain field myFavoriteColor with value of blue.", "blue".equals(xpath.evaluate(findStuff, foundDocContent, XPathConstants.STRING)));
619    
620                            findStuff = "//putWhateverWordsIwantInsideThisTag/theGender/value";
621                            assertTrue("Document content does not contain field theGender with value of male.", "male".equals(xpath.evaluate(findStuff, foundDocContent, XPathConstants.STRING)));
622    
623                            findStuff = "//putWhateverWordsIwantInsideThisTag/myname/value";
624                            assertTrue("Document content does not contain field myname with value of jack.", "jack".equals(xpath.evaluate(findStuff, foundDocContent, XPathConstants.STRING)));
625    
626                    } catch(Exception e){
627                            e.printStackTrace();
628                    }
629            }
630    }