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