Coverage Report - org.mule.module.xml.filters.JaxenFilter
 
Classes in this File Line Coverage Branch Coverage Complexity
JaxenFilter
0%
0/92
0%
0/40
2.368
 
 1  
 /*
 2  
  * $Id: JXPathFilter.java 11195 2008-03-06 04:13:01Z tcarlson $
 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.module.xml.filters;
 12  
 
 13  
 import org.mule.api.MuleMessage;
 14  
 import org.mule.api.routing.filter.Filter;
 15  
 import org.mule.module.xml.util.XMLUtils;
 16  
 
 17  
 import java.io.InputStream;
 18  
 import java.util.Iterator;
 19  
 import java.util.Map;
 20  
 
 21  
 import javax.xml.transform.dom.DOMSource;
 22  
 
 23  
 import org.apache.commons.jxpath.AbstractFactory;
 24  
 import org.apache.commons.logging.Log;
 25  
 import org.apache.commons.logging.LogFactory;
 26  
 import org.dom4j.Document;
 27  
 import org.jaxen.BaseXPath;
 28  
 import org.jaxen.JaxenException;
 29  
 import org.jaxen.dom.DOMXPath;
 30  
 import org.jaxen.dom4j.Dom4jXPath;
 31  
 import org.jaxen.javabean.JavaBeanXPath;
 32  
 
 33  
 /**
 34  
  * <code>JaxenFilter</code> evaluates an XPath expression against an XML document
 35  
  * using Jaxen.
 36  
  */
 37  
 public class JaxenFilter implements Filter
 38  
 {
 39  0
     protected transient Log logger = LogFactory.getLog(getClass());
 40  
 
 41  
     private String pattern;
 42  
     private String expectedValue;
 43  0
     private Map namespaces = null;
 44  0
     private Map contextProperties = null;
 45  
     private AbstractFactory factory;
 46  
 
 47  
     public JaxenFilter()
 48  
     {
 49  0
         super();
 50  0
     }
 51  
 
 52  
     public JaxenFilter(String pattern)
 53  0
     {
 54  0
         this.pattern = pattern;
 55  0
     }
 56  
 
 57  
     public JaxenFilter(String pattern, String expectedValue)
 58  0
     {
 59  0
         this.pattern = pattern;
 60  0
         this.expectedValue = expectedValue;
 61  0
     }
 62  
 
 63  
     public boolean accept(MuleMessage obj)
 64  
     {
 65  0
         Object payload = obj.getPayload();
 66  
         
 67  
         try 
 68  
         {
 69  
             // Ensure that we have an object we can run an XPath on
 70  0
             if (payload instanceof DOMSource)
 71  
             {
 72  0
                 accept(((DOMSource) payload).getNode());
 73  
             }
 74  0
             else if (payload instanceof byte[] 
 75  
                      || payload instanceof InputStream 
 76  
                      || payload instanceof String)
 77  
             {
 78  
                 try
 79  
                 {
 80  0
                     return accept(obj.getPayload(org.w3c.dom.Document.class));
 81  
                 }
 82  0
                 catch (Exception e)
 83  
                 {
 84  0
                     logger.warn("JaxenPath filter rejected message because it could not convert from " 
 85  
                             + payload.getClass() 
 86  
                             + " to Source: "+ e.getMessage(), e);
 87  0
                     return false;
 88  
                 }
 89  
             }
 90  
         
 91  0
             return accept(payload);
 92  
         }
 93  0
         catch (JaxenException e) 
 94  
         {
 95  0
             logger.warn("JaxenPath filter rejected message because it could not build/evaluate the XPath expression.", e);
 96  0
             return false;
 97  
         }
 98  
     }
 99  
 
 100  
     private boolean accept(Object obj) throws JaxenException
 101  
     {
 102  0
         if (obj == null)
 103  
         {
 104  0
             logger.warn("Applying JaxenFilter to null object.");
 105  0
             return false;
 106  
         }
 107  0
         if (pattern == null)
 108  
         {
 109  0
             logger.warn("Expression for JaxenFilter is not set.");
 110  0
             return false;
 111  
         }
 112  0
         if (expectedValue == null)
 113  
         {
 114  
             // Handle the special case where the expected value really is null.
 115  0
             if (pattern.endsWith("= null") || pattern.endsWith("=null"))
 116  
             {
 117  0
                 expectedValue = "null";
 118  0
                 pattern = pattern.substring(0, pattern.lastIndexOf("="));
 119  
             }
 120  
             else
 121  
             {
 122  0
                 if (logger.isInfoEnabled())
 123  
                 {
 124  0
                     logger.info("Expected value for JaxenFilter is not set, using 'true' by default");
 125  
                 }
 126  0
                 expectedValue = Boolean.TRUE.toString();
 127  
             }
 128  
         }
 129  
 
 130  0
         Object xpathResult = null;
 131  0
         boolean accept = false;
 132  
 
 133  
         Document dom4jDoc;
 134  
         try
 135  
         {
 136  0
             dom4jDoc = XMLUtils.toDocument(obj);
 137  
         }
 138  0
         catch (Exception e)
 139  
         {
 140  0
             throw new JaxenException(e);
 141  0
         }
 142  
         
 143  
         // Payload is a DOM Document
 144  0
         if (dom4jDoc != null)
 145  
         {
 146  0
             xpathResult = getDom4jXPath().valueOf(dom4jDoc);
 147  
         }
 148  
         // Payload is a W3C Document
 149  0
         else if (obj instanceof DOMSource)
 150  
         {
 151  0
             xpathResult = getDOMXPath().valueOf(obj);
 152  
         }
 153  
         // Payload is a W3C Document
 154  0
         else if (obj instanceof org.w3c.dom.Document)
 155  
         {
 156  0
             xpathResult = getDOMXPath().valueOf(obj);
 157  
         }
 158  
         // Payload is a Java object
 159  
         else
 160  
         {
 161  0
             if (logger.isDebugEnabled())
 162  
             {
 163  0
                 logger.debug("Passing object of type " + obj.getClass().getName() + " to JaxenContext");
 164  
             }
 165  0
             xpathResult = getJavaBeanXPath().valueOf(obj);
 166  
         }
 167  
 
 168  0
         if (logger.isDebugEnabled())
 169  
         {
 170  0
             logger.debug("JaxenFilter Expression result = '" + xpathResult + "' -  Expected value = '"
 171  
                     + expectedValue + "'");
 172  
         }
 173  
         // Compare the XPath result with the expected result.
 174  0
         if (xpathResult != null)
 175  
         {
 176  0
             accept = xpathResult.toString().equals(expectedValue);
 177  
         }
 178  
         else
 179  
         {
 180  
             // A null result was actually expected.
 181  0
             if (expectedValue.equals("null"))
 182  
             {
 183  0
                 accept = true;
 184  
             }
 185  
             // A null result was not expected, something probably went wrong.
 186  
             else
 187  
             {
 188  0
                 logger.warn("JaxenFilter expression evaluates to null: " + pattern);
 189  
             }
 190  
         }
 191  
 
 192  0
         if (logger.isDebugEnabled())
 193  
         {
 194  0
             logger.debug("JaxenFilter accept object  : " + accept);
 195  
         }
 196  
 
 197  0
         return accept;
 198  
     }
 199  
 
 200  
     protected DOMXPath getDOMXPath() throws JaxenException
 201  
     {
 202  0
         DOMXPath xpath = new DOMXPath(pattern);
 203  0
         setupNamespaces(xpath);
 204  0
         return xpath;
 205  
     }
 206  
 
 207  
     protected Dom4jXPath getDom4jXPath() throws JaxenException
 208  
     {
 209  0
         Dom4jXPath xpath = new Dom4jXPath(pattern);
 210  0
         setupNamespaces(xpath);
 211  0
         return xpath;
 212  
     }
 213  
     
 214  
     protected JavaBeanXPath getJavaBeanXPath() throws JaxenException
 215  
     {
 216  0
         JavaBeanXPath xpath = new JavaBeanXPath(pattern);
 217  0
         setupNamespaces(xpath);
 218  0
         return xpath;
 219  
     }
 220  
 
 221  
     private void setupNamespaces(BaseXPath xpath) throws JaxenException
 222  
     {
 223  0
         if (namespaces != null) 
 224  
         {
 225  0
             for (Iterator itr = namespaces.entrySet().iterator(); itr.hasNext();)
 226  
             {
 227  0
                 Map.Entry entry = (Map.Entry) itr.next();
 228  
                 
 229  0
                 xpath.addNamespace((String) entry.getKey(), (String) entry.getValue());
 230  0
             }
 231  
         }
 232  0
     }
 233  
 
 234  
     /** @return XPath expression */
 235  
     public String getPattern()
 236  
     {
 237  0
         return pattern;
 238  
     }
 239  
 
 240  
     /** @param pattern The XPath expression */
 241  
     public void setPattern(String pattern)
 242  
     {
 243  0
         this.pattern = pattern;
 244  0
     }
 245  
 
 246  
     /** @return The expected result value of the XPath expression */
 247  
     public String getExpectedValue()
 248  
     {
 249  0
         return expectedValue;
 250  
     }
 251  
 
 252  
     /** Sets the expected result value of the XPath expression */
 253  
     public void setExpectedValue(String expectedValue)
 254  
     {
 255  0
         this.expectedValue = expectedValue;
 256  0
     }
 257  
 
 258  
     public Map getNamespaces()
 259  
     {
 260  0
         return namespaces;
 261  
     }
 262  
 
 263  
     public void setNamespaces(Map namespaces)
 264  
     {
 265  0
         this.namespaces = namespaces;
 266  0
     }
 267  
 
 268  
     public Map getContextProperties()
 269  
     {
 270  0
         return contextProperties;
 271  
     }
 272  
 
 273  
     public void setContextProperties(Map contextProperties)
 274  
     {
 275  0
         this.contextProperties = contextProperties;
 276  0
     }
 277  
 
 278  
     public AbstractFactory getFactory()
 279  
     {
 280  0
         return factory;
 281  
     }
 282  
 
 283  
     public void setFactory(AbstractFactory factory)
 284  
     {
 285  0
         this.factory = factory;
 286  0
     }
 287  
 }