View Javadoc

1   /*
2    * $Id: JXPathExtractor.java 12273 2008-07-10 13:25:32Z 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.transformer;
12  
13  import org.mule.api.transformer.TransformerException;
14  import org.mule.module.xml.util.XMLUtils;
15  import org.mule.transformer.AbstractTransformer;
16  
17  import java.util.ArrayList;
18  import java.util.List;
19  
20  import org.apache.commons.jxpath.JXPathContext;
21  import org.dom4j.Document;
22  import org.dom4j.Node;
23  import org.dom4j.XPath;
24  
25  /**
26   * The JXPathExtractor is a simple transformer that evaluates an xpath expression
27   * against the given bean and that returns the result. <p/> By default, a single
28   * result will be returned. If multiple values are expected, set the
29   * {@link #singleResult} property to <code>false</code>. In this case a
30   * {@link List} of values will be returned. Note the property is currently ignored
31   * for non-String/XML payloads.
32   */
33  public class JXPathExtractor extends AbstractTransformer
34  {
35  
36      private volatile String expression;
37  
38      private volatile boolean singleResult = true;
39  
40      /**
41       * Evaluate the expression in the context of the given object and returns the
42       * result. If the given object is a string, it assumes it is an valid xml and
43       * parses it before evaluating the xpath expression.
44       */
45      public Object doTransform(Object src, String encoding) throws TransformerException
46      {
47          try
48          {
49              Object result;
50              Document doc = XMLUtils.toDocument(src);
51              
52              // Payload is XML
53              if (doc != null)
54              {
55                  if (singleResult)
56                  {
57                      result = doc.valueOf(expression);
58                  }
59                  else
60                  {
61                      XPath xpath = doc.createXPath(expression);
62                      // TODO handle non-list cases, see
63                      // http://www.dom4j.org/apidocs/org/dom4j/XPath.html#evaluate(java.lang.Object)
64                      List obj = (List)xpath.evaluate(doc);
65                      result = new ArrayList(obj.size());
66                      for (int i = 0; i < obj.size(); i++)
67                      {
68                          final Node node = (Node)obj.get(i);
69                          ((List)result).add(node.getText());
70                      }
71                  }
72              }
73              // Payload is a Java object
74              else
75              {
76                  JXPathContext context = JXPathContext.newContext(src);
77                  result = context.getValue(expression);
78              }
79              return result;
80          }
81          catch (Exception e)
82          {
83              throw new TransformerException(this, e);
84          }
85      }
86  
87      /**
88       * @return Returns the expression.
89       */
90      public String getExpression()
91      {
92          return expression;
93      }
94  
95      /**
96       * @param expression The expression to set.
97       */
98      public void setExpression(String expression)
99      {
100         this.expression = expression;
101     }
102 
103     /**
104      * Should a single value be returned.
105      * 
106      * @return value
107      */
108     public boolean isSingleResult()
109     {
110         return singleResult;
111     }
112 
113     /**
114      * If multiple results are expected from the {@link #expression} evaluation, set
115      * this to false.
116      * 
117      * @param singleResult flag
118      */
119     public void setSingleResult(boolean singleResult)
120     {
121         this.singleResult = singleResult;
122     }
123 }