Home » synapse-1.2-src » org.apache.synapse.util.xpath » [javadoc | source]

    1   /*
    2    *  Licensed to the Apache Software Foundation (ASF) under one
    3    *  or more contributor license agreements.  See the NOTICE file
    4    *  distributed with this work for additional information
    5    *  regarding copyright ownership.  The ASF licenses this file
    6    *  to you under the Apache License, Version 2.0 (the
    7    *  "License"); you may not use this file except in compliance
    8    *  with the License.  You may obtain a copy of the License at
    9    *
   10    *   http://www.apache.org/licenses/LICENSE-2.0
   11    *
   12    *  Unless required by applicable law or agreed to in writing,
   13    *  software distributed under the License is distributed on an
   14    *   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   15    *  KIND, either express or implied.  See the License for the
   16    *  specific language governing permissions and limitations
   17    *  under the License.
   18    */
   19   
   20   package org.apache.synapse.util.xpath;
   21   
   22   import org.apache.axiom.om.OMNamespace;
   23   import org.apache.axiom.om.impl.llom.OMDocumentImpl;
   24   import org.apache.axiom.om.impl.llom.OMElementImpl;
   25   import org.apache.axiom.om.impl.llom.OMTextImpl;
   26   import org.apache.axiom.om.xpath.AXIOMXPath;
   27   import org.apache.axiom.soap.SOAPEnvelope;
   28   import org.apache.commons.logging.Log;
   29   import org.apache.commons.logging.LogFactory;
   30   import org.apache.synapse.MessageContext;
   31   import org.apache.synapse.SynapseException;
   32   import org.jaxen;
   33   import org.jaxen.util.SingletonList;
   34   
   35   import java.util.List;
   36   
   37   /**
   38    * <p>XPath that has been used inside Synapse xpath processing. This has a extension function named
   39    * <code>get-property</code> which is use to retrieve message context properties with the given
   40    * name from the function</p>
   41    *
   42    * <p>For example the following function <code>get-property('prop')</code> can be evaluatedd using
   43    * an XPath to retrieve the message context property value with the name <code>prop</code>.</p>
   44    *
   45    * <p>Apart from that this XPath has a certain set of XPath variables associated with it. They are
   46    * as follows;
   47    * <dl>
   48    *   <dt><tt>body</tt></dt>
   49    *   <dd>The SOAP 1.1 or 1.2 body element.</dd>
   50    *   <dt><tt>header</tt></dt>
   51    *   <dd>The SOAP 1.1 or 1.2 header element.</dd>
   52    * </dl>
   53    * </p>
   54    *
   55    * <p>Also there are some XPath prefixes defined in <code>SynapseXPath</code> to access various
   56    * properties using XPath variables, where the variable name represents the particular prefix and
   57    * the property name as the local part of the variable. Those variables are;
   58    * <dl>
   59    *   <dt><tt>ctx</tt></dt>
   60    *   <dd>Prefix for Synapse MessageContext properties</dd>
   61    *   <dt><tt>axis2</tt></dt>
   62    *   <dd>Prefix for Axis2 MessageContext properties</dd>
   63    *   <dt><tt>trp</tt></dt>
   64    *   <dd>Prefix for the transport headers</dd>
   65    * </dl>
   66    * </p>
   67    *
   68    * <p>This XPath is Thread Safe, and provides a special set of evaluate functions for the
   69    * <code>MessageContext</code> and <code>SOAPEnvelope</code> as well as a method to retrieve
   70    * string values of the evaluated XPaths</p>
   71    *
   72    * @see org.apache.axiom.om.xpath.AXIOMXPath
   73    * @see #getContext(Object)
   74    * @see org.apache.synapse.util.xpath.SynapseXPathFunctionContext
   75    * @see org.apache.synapse.util.xpath.SynapseXPathVariableContext
   76    */
   77   public class SynapseXPath extends AXIOMXPath {
   78       private static final long serialVersionUID = 7639226137534334222L;
   79       
   80       private static final Log log = LogFactory.getLog(SynapseXPath.class);
   81   
   82       /**
   83        * <p>Initializes the <code>SynapseXPath</code> with the given <code>xpathString</code> as the
   84        * XPath</p>
   85        *
   86        * @param xpathString xpath in its string format
   87        * @throws JaxenException in case of an initialization failure
   88        */
   89       public SynapseXPath(String xpathString) throws JaxenException {
   90           super(xpathString);
   91       }
   92   
   93       /**
   94        * <P>Evaluates the XPath expression against the MessageContext of the current message and
   95        * returns a String representation of the result</p>
   96        *
   97        * @param synCtx the source message which holds the MessageContext against full context
   98        * @return a String representation of the result of evaluation
   99        */
  100       public String stringValueOf(MessageContext synCtx) {
  101   
  102           try {
  103   
  104               Object result = evaluate(synCtx);
  105   
  106               if (result == null) {
  107                   return null;
  108               }
  109   
  110               StringBuffer textValue = new StringBuffer();
  111               if (result instanceof List) {
  112   
  113                   List list = (List) result;
  114                   for (Object o : list) {
  115   
  116                       if (o == null && list.size() == 1) {
  117                           return null;
  118                       }
  119   
  120                       if (o instanceof OMTextImpl) {
  121                           textValue.append(((OMTextImpl) o).getText());
  122                       } else if (o instanceof OMElementImpl) {
  123   
  124                           String s = ((OMElementImpl) o).getText();
  125   
  126                           if (s.trim().length() == 0) {
  127                               s = o.toString();
  128                           }
  129                           textValue.append(s);
  130   
  131                       } else if (o instanceof OMDocumentImpl) {
  132   
  133                           textValue.append(
  134                               ((OMDocumentImpl) o).getOMDocumentElement().toString());
  135                       }
  136                   }
  137   
  138               } else {
  139                   textValue.append(result.toString());
  140               }
  141   
  142               return textValue.toString();
  143   
  144           } catch (JaxenException je) {
  145               handleException("Evaluation of the XPath expression " + this.toString() +
  146                   " resulted in an error", je);
  147           }
  148   
  149           return null;
  150       }
  151   
  152       public void addNamespace(OMNamespace ns) throws JaxenException {
  153           addNamespace(ns.getPrefix(), ns.getNamespaceURI());
  154       }
  155   
  156       /**
  157        * Create a {@link Context} wrapper for the provided object.
  158        * This methods implements the following class specific behavior:
  159        * <dl>
  160        *   <dt>{@link MessageContext}</dt>
  161        *   <dd>The XPath expression is evaluated against the SOAP envelope
  162        *       and the functions and variables defined by
  163        *       {@link SynapseXPathFunctionContext} and
  164        *       {@link SynapseXPathVariableContext} are
  165        *       available.</dd>
  166        *   <dt>{@link SOAPEnvelope}</dt>
  167        *   <dd>The variables defined by {@link SynapseXPathVariableContext}
  168        *       are available.</dd>
  169        * </dl>
  170        * For all other object types, the behavior is identical to
  171        * {@link BaseXPath#getContext(Object)}.
  172        * <p>
  173        * Note that the behavior described here also applies to all evaluation
  174        * methods such as {@link #evaluate(Object)} or {@link #selectSingleNode(Object)},
  175        * given that these methods all use {@link #getContext(Object)}.
  176        * 
  177        * @see SynapseXPathFunctionContext#getFunction(String, String, String)
  178        * @see SynapseXPathVariableContext#getVariableValue(String, String, String)
  179        */
  180       @Override
  181       protected Context getContext(Object obj) {
  182           if (obj instanceof MessageContext) {
  183               MessageContext synCtx = (MessageContext)obj;
  184               ContextSupport baseContextSupport = getContextSupport();
  185               ContextSupport contextSupport =
  186                   new ContextSupport(baseContextSupport.getNamespaceContext(),
  187                                      new SynapseXPathFunctionContext(baseContextSupport.getFunctionContext(), synCtx),
  188                                      new SynapseXPathVariableContext(baseContextSupport.getVariableContext(), synCtx),
  189                                      baseContextSupport.getNavigator());
  190               Context context = new Context(contextSupport);
  191               context.setNodeSet(new SingletonList(synCtx.getEnvelope()));
  192               return context;
  193           } else if (obj instanceof SOAPEnvelope) {
  194               SOAPEnvelope env = (SOAPEnvelope)obj;
  195               ContextSupport baseContextSupport = getContextSupport();
  196               ContextSupport contextSupport =
  197                   new ContextSupport(baseContextSupport.getNamespaceContext(),
  198                                      baseContextSupport.getFunctionContext(),
  199                                      new SynapseXPathVariableContext(baseContextSupport.getVariableContext(), env),
  200                                      baseContextSupport.getNavigator());
  201               Context context = new Context(contextSupport);
  202               context.setNodeSet(new SingletonList(env));
  203               return context;
  204           } else {
  205               return super.getContext(obj);
  206           }
  207       }
  208   
  209       private void handleException(String msg, Throwable e) {
  210           log.error(msg, e);
  211           throw new SynapseException(msg, e);
  212       }
  213   }

Home » synapse-1.2-src » org.apache.synapse.util.xpath » [javadoc | source]