Coverage Report - org.mule.routing.filters.xml.JXPathFilter
 
Classes in this File Line Coverage Branch Coverage Complexity
JXPathFilter
0%
0/95
0%
0/21
2.3
 
 1  
 /*
 2  
  * $Id: JXPathFilter.java 7976 2007-08-21 14:26:13Z dirk.olmes $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
 5  
  *
 6  
  * The software in this package is published under the terms of the CPAL v1.0
 7  
  * license, a copy of which has been included with this distribution in the
 8  
  * LICENSE.txt file.
 9  
  */
 10  
 
 11  
 package org.mule.routing.filters.xml;
 12  
 
 13  
 import org.mule.umo.UMOFilter;
 14  
 import org.mule.umo.UMOMessage;
 15  
 import org.mule.util.StringMessageUtils;
 16  
 
 17  
 import java.util.Iterator;
 18  
 import java.util.Map;
 19  
 
 20  
 import org.apache.commons.jxpath.AbstractFactory;
 21  
 import org.apache.commons.jxpath.JXPathContext;
 22  
 import org.apache.commons.logging.Log;
 23  
 import org.apache.commons.logging.LogFactory;
 24  
 import org.dom4j.Document;
 25  
 import org.dom4j.DocumentException;
 26  
 import org.dom4j.DocumentHelper;
 27  
 import org.dom4j.XPath;
 28  
 
 29  
 /**
 30  
  * <code>JXPathFilter</code> evaluates an XPath expression against a W3C Document,
 31  
  * XML string, or Java bean and returns true if the result is as expected.
 32  
  */
 33  
 public class JXPathFilter implements UMOFilter
 34  
 {
 35  
 
 36  0
     protected transient Log logger = LogFactory.getLog(getClass());
 37  
 
 38  
     private String expression;
 39  
     private String expectedValue;
 40  0
     private Map namespaces = null;
 41  0
     private Map contextProperties = null;
 42  
     private AbstractFactory factory;
 43  0
     private boolean lenient = true;
 44  
 
 45  
     public JXPathFilter()
 46  
     {
 47  0
         super();
 48  0
     }
 49  
 
 50  
     public JXPathFilter(String expression)
 51  0
     {
 52  0
         this.expression = expression;
 53  0
     }
 54  
 
 55  
     public JXPathFilter(String expression, String expectedValue)
 56  0
     {
 57  0
         this.expression = expression;
 58  0
         this.expectedValue = expectedValue;
 59  0
     }
 60  
 
 61  
     public boolean accept(UMOMessage obj)
 62  
     {
 63  0
         return accept(obj.getPayload());
 64  
     }
 65  
 
 66  
     private boolean accept(Object obj)
 67  
     {
 68  0
         if (obj == null)
 69  
         {
 70  0
             logger.warn("Applying JXPathFilter to null object.");
 71  0
             return false;
 72  
         }
 73  0
         if (expression == null)
 74  
         {
 75  0
             logger.warn("Expression for JXPathFilter is not set.");
 76  0
             return false;
 77  
         }
 78  0
         if (expectedValue == null)
 79  
         {
 80  
             // Handle the special case where the expected value really is null.
 81  0
             if (expression.endsWith("= null") || expression.endsWith("=null"))
 82  
             {
 83  0
                 expectedValue = "null";
 84  0
                 expression = expression.substring(0, expression.lastIndexOf("="));
 85  
             }
 86  
             else
 87  
             {
 88  0
                 if (logger.isInfoEnabled())
 89  
                 {
 90  0
                     logger.info("Expected value for JXPathFilter is not set, using 'true' by default");
 91  
                 }
 92  0
                 expectedValue = Boolean.TRUE.toString();
 93  
             }
 94  
         }
 95  
 
 96  0
         Object xpathResult = null;
 97  0
         boolean accept = false;
 98  
 
 99  
         // Payload is a DOM Document
 100  0
         if (obj instanceof Document)
 101  
         {
 102  0
             if (namespaces == null)
 103  
             {
 104  
                 // no namespace defined, let's perform a direct evaluation
 105  0
                 xpathResult = ((Document)obj).valueOf(expression);
 106  
             }
 107  
             else
 108  
             {
 109  
                 // create an xpath expression with namespaces and evaluate it
 110  0
                 XPath xpath = DocumentHelper.createXPath(expression);
 111  0
                 xpath.setNamespaceURIs(namespaces);
 112  0
                 xpathResult = xpath.valueOf(obj);
 113  
             }
 114  
 
 115  
         }
 116  
         // Payload is a String of XML
 117  0
         else if (obj instanceof String)
 118  
         {
 119  
             try
 120  
             {
 121  0
                 return accept(DocumentHelper.parseText((String)obj));
 122  
             }
 123  0
             catch (DocumentException e)
 124  
             {
 125  0
                 logger.warn("JXPathFilter unable to parse XML document: " + e.getMessage(), e);
 126  0
                 if (logger.isDebugEnabled())
 127  0
                     logger.debug("XML = " + StringMessageUtils.truncate((String)obj, 200, false));
 128  0
                 return false;
 129  
             }
 130  
         }
 131  
         // Payload is a Java object
 132  
         else
 133  
         {
 134  0
             if (logger.isDebugEnabled())
 135  
             {
 136  0
                 logger.debug("Passing object of type " + obj.getClass().getName() + " to JXPathContext");
 137  
             }
 138  0
             JXPathContext context = JXPathContext.newContext(obj);
 139  0
             initialise(context);
 140  0
             xpathResult = context.getValue(expression);
 141  
         }
 142  
 
 143  0
         if (logger.isDebugEnabled())
 144  
         {
 145  0
             logger.debug("JXPathFilter Expression result = '" + xpathResult + "' -  Expected value = '"
 146  
                          + expectedValue + "'");
 147  
         }
 148  
         // Compare the XPath result with the expected result.
 149  0
         if (xpathResult != null)
 150  
         {
 151  0
             accept = xpathResult.toString().equals(expectedValue);
 152  
         }
 153  
         else
 154  
         {
 155  
             // A null result was actually expected.
 156  0
             if (expectedValue.equals("null"))
 157  
             {
 158  0
                 accept = true;
 159  
             }
 160  
             // A null result was not expected, something probably went wrong.
 161  
             else
 162  
             {
 163  0
                 logger.warn("JXPathFilter expression evaluates to null: " + expression);
 164  
             }
 165  
         }
 166  
 
 167  0
         if (logger.isDebugEnabled())
 168  
         {
 169  0
             logger.debug("JXPathFilter accept object  : " + accept);
 170  
         }
 171  
 
 172  0
         return accept;
 173  
     }
 174  
 
 175  
     /**
 176  
      * Initializes the JXPathContext based on any relevant properties set for the
 177  
      * filter.
 178  
      * 
 179  
      * @param the JXPathContext to initialize
 180  
      */
 181  
     protected void initialise(JXPathContext context)
 182  
     {
 183  0
         Map.Entry entry = null;
 184  0
         if (namespaces != null)
 185  
         {
 186  0
             if (logger.isDebugEnabled())
 187  
             {
 188  0
                 logger.debug("Initializing JXPathContext with namespaces: " + namespaces);
 189  
             }
 190  
 
 191  0
             for (Iterator iterator = namespaces.entrySet().iterator(); iterator.hasNext();)
 192  
             {
 193  0
                 entry = (Map.Entry)iterator.next();
 194  0
                 context.registerNamespace(entry.getKey().toString(), entry.getValue().toString());
 195  
             }
 196  
         }
 197  
 
 198  0
         if (contextProperties != null)
 199  
         {
 200  0
             if (logger.isDebugEnabled())
 201  
             {
 202  0
                 logger.debug("Initializing JXPathContext with properties: " + contextProperties);
 203  
             }
 204  
 
 205  0
             for (Iterator iterator = contextProperties.entrySet().iterator(); iterator.hasNext();)
 206  
             {
 207  0
                 entry = (Map.Entry)iterator.next();
 208  0
                 context.setValue(entry.getKey().toString(), entry.getValue());
 209  
             }
 210  
         }
 211  
 
 212  0
         if (factory != null)
 213  
         {
 214  0
             context.setFactory(factory);
 215  
         }
 216  
 
 217  0
         context.setLenient(lenient);
 218  0
     }
 219  
 
 220  
     /**
 221  
      * @return XPath expression
 222  
      */
 223  
     public String getExpression()
 224  
     {
 225  0
         return expression;
 226  
     }
 227  
 
 228  
     /**
 229  
      * @param expression The XPath expression
 230  
      */
 231  
     public void setExpression(String expression)
 232  
     {
 233  0
         this.expression = expression;
 234  0
     }
 235  
 
 236  
     /**
 237  
      * @return The expected result value of the XPath expression
 238  
      */
 239  
     public String getExpectedValue()
 240  
     {
 241  0
         return expectedValue;
 242  
     }
 243  
 
 244  
     /**
 245  
      * Sets the expected result value of the XPath expression
 246  
      */
 247  
     public void setExpectedValue(String expectedValue)
 248  
     {
 249  0
         this.expectedValue = expectedValue;
 250  0
     }
 251  
 
 252  
     /**
 253  
      * @return The expected result value of the XPath expression
 254  
      * @deprecated Use <code>getExpectedValue()</code>.
 255  
      */
 256  
     public String getValue()
 257  
     {
 258  0
         return getExpectedValue();
 259  
     }
 260  
 
 261  
     /**
 262  
      * Sets the expected result value of the XPath expression
 263  
      * 
 264  
      * @deprecated Use <code>setExpectedValue(String expectedValue)</code>.
 265  
      */
 266  
     public void setValue(String value)
 267  
     {
 268  0
         setExpectedValue(value);
 269  0
     }
 270  
 
 271  
     public Map getNamespaces()
 272  
     {
 273  0
         return namespaces;
 274  
     }
 275  
 
 276  
     public void setNamespaces(Map namespaces)
 277  
     {
 278  0
         this.namespaces = namespaces;
 279  0
     }
 280  
 
 281  
     public Map getContextProperties()
 282  
     {
 283  0
         return contextProperties;
 284  
     }
 285  
 
 286  
     public void setContextProperties(Map contextProperties)
 287  
     {
 288  0
         this.contextProperties = contextProperties;
 289  0
     }
 290  
 
 291  
     public AbstractFactory getFactory()
 292  
     {
 293  0
         return factory;
 294  
     }
 295  
 
 296  
     public void setFactory(AbstractFactory factory)
 297  
     {
 298  0
         this.factory = factory;
 299  0
     }
 300  
 
 301  
     public boolean isLenient()
 302  
     {
 303  0
         return lenient;
 304  
     }
 305  
 
 306  
     public void setLenient(boolean lenient)
 307  
     {
 308  0
         this.lenient = lenient;
 309  0
     }
 310  
 }