View Javadoc

    1   /*
    2    * Copyright 2002,2004 The Apache Software Foundation.
    3    *
    4    * Licensed under the Apache License, Version 2.0 (the "License");
    5    * you may not use this file except in compliance with the License.
    6    * You may obtain a copy of the License at
    7    *
    8    *      http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  package org.apache.commons.jelly.expression.xpath;
    17
    18  import java.util.Hashtable;
    19  import java.util.Iterator;
    20  import java.util.Map;
    21
    22  import org.apache.commons.jelly.JellyContext;
    23  import org.apache.commons.jelly.expression.Expression;
    24  import org.apache.commons.jelly.expression.ExpressionSupport;
    25  import org.apache.commons.jelly.impl.TagScript;
    26  import org.apache.commons.logging.Log;
    27  import org.apache.commons.logging.LogFactory;
    28  import org.jaxen.SimpleNamespaceContext;
    29  import org.jaxen.VariableContext;
    30  import org.jaxen.XPath;
    31  import org.jaxen.JaxenException;
    32  import org.jaxen.dom4j.Dom4jXPath;
    33
    34  /*** An expression which returns an XPath object.
    35    *
    36    * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
    37    * @version $Revision: 155420 $
    38    */
    39  public class XPathExpression extends ExpressionSupport implements VariableContext {
    40
    41      /*** The Log to which logging calls will be made. */
    42      private Log log = LogFactory.getLog(XPathExpression.class);
    43
    44      private String text;
    45      private Expression xpathExpr;
    46      private JellyContext context;
    47      private Map uris;
    48
    49      public XPathExpression() {
    50      }
    51
    52      public XPathExpression(String text,
    53                             Expression xpathExpr,
    54                             TagScript tagScript) {
    55          this.text = text;
    56          this.xpathExpr = xpathExpr;
    57
    58          Map namespaceContext = tagScript.getNamespaceContext();
    59
    60          this.uris = createUriMap(namespaceContext);
    61      }
    62
    63      public String toString() {
    64          return getExpressionText();
    65      }
    66
    67      // Expression interface
    68      //-------------------------------------------------------------------------
    69      public String getExpressionText() {
    70          return this.text;
    71      }
    72
    73      public Object evaluate(JellyContext context) {
    74          this.context = context;
    75
    76          try
    77          {
    78              XPath xpath = new Dom4jXPath( this.xpathExpr.evaluateAsString( context ) );
    79
    80              xpath.setVariableContext(this);
    81
    82              if (log.isDebugEnabled()) {
    83                  log.debug( "Setting the namespace context to be: " + uris );
    84              }
    85
    86              xpath.setNamespaceContext( new SimpleNamespaceContext( this.uris ) );
    87
    88              return xpath;
    89          }
    90          catch (JaxenException e)
    91          {
    92              log.error( "Error constructing xpath",
    93                         e );
    94          }
    95
    96          return null;
    97      }
    98
    99      // VariableContext interface
    100     //-------------------------------------------------------------------------
    101     public Object getVariableValue(
    102         String namespaceURI,
    103         String prefix,
    104         String localName) {
    105
    106         Object value = context.getVariable(localName);
    107
    108         //log.debug( "Looking up XPath variable of name: " + localName + " value is: " + value );
    109
    110         return value;
    111     }
    112
    113     // Implementation methods
    114     //-------------------------------------------------------------------------
    115
    116     /***
    117      * Factory method to create a synchronized Map of non-null and non-blank
    118      * namespace prefixes to namespace URIs
    119      */
    120     protected Map createUriMap(Map namespaceContext) {
    121         // now lets clone the Map but ignoring default or null prefixes
    122         Map uris = new Hashtable(namespaceContext.size());
    123         for (Iterator iter = namespaceContext.entrySet().iterator(); iter.hasNext(); ) {
    124             Map.Entry entry = (Map.Entry) iter.next();
    125             String prefix = (String) entry.getKey();
    126             if (prefix != null && prefix.length() != 0) {
    127                 uris.put(prefix, entry.getValue());
    128             }
    129         }
    130         return uris;
    131     }
    132 }