package org.jdom.xpath;

import java.util.*;
import org.jaxen.*;
import org.jaxen.jdom.*;
import org.jdom.*;

/**
 * @author  Antonio
 */
public class Ayuda extends XPath{
	 private static final String CVS_ID =
		    "@(#) $RCSfile: JaxenXPath.java,v $ $Revision: 1.19 $ $Date: 2004/09/03 07:27:39 $ $Name: jdom_1_0 $";

		   /**
		    * The compiled XPath object to select nodes.  This attribute can
		    * not be made final as it needs to be set upon object
		    * deserialization.
		    */
		   private transient JDOMXPath xPath;

		   /**
		    * The current context for XPath expression evaluation.
		    */
		   private           Object    currentContext;

		   /**
		    * Creates a new XPath wrapper object, compiling the specified
		    * XPath expression.
		    *
		    * @param  expr   the XPath expression to wrap.
		    *
		    * @throws JDOMException   if the XPath expression is invalid.
		    */
		   public Ayuda(String expr) throws JDOMException {
		      setXPath(expr);
		   }

		   /**
		    * Evaluates the wrapped XPath expression and returns the list
		    * of selected items.
		    *
		    * @param  context   the node to use as context for evaluating
		    *                   the XPath expression.
		    *
		    * @return the list of selected items, which may be of types: {@link Element},
		    *         {@link Attribute}, {@link Text}, {@link CDATA},
		    *         {@link Comment}, {@link ProcessingInstruction}, Boolean,
		    *         Double, or String.
		    *
		    * @throws JDOMException   if the evaluation of the XPath
		    *                         expression on the specified context
		    *                         failed.
		    */
		   public List selectNodes(Object context) throws JDOMException {
		      try {
		         currentContext = context;

		         return xPath.selectNodes(context);
		      }
		      catch (JaxenException ex1) {
		         throw new JDOMException("XPath error while evaluating \"" +
		                        xPath.toString() + "\": " + ex1.getMessage(), ex1);
		      }
		      finally {
		         currentContext = null;
		      }
		   }

		   /**
		    * Evaluates the wrapped XPath expression and returns the first
		    * entry in the list of selected nodes (or atomics).
		    *
		    * @param  context   the node to use as context for evaluating
		    *                   the XPath expression.
		    *
		    * @return the first selected item, which may be of types: {@link Element},
		    *         {@link Attribute}, {@link Text}, {@link CDATA},
		    *         {@link Comment}, {@link ProcessingInstruction}, Boolean,
		    *         Double, String, or <code>null</code> if no item was selected.
		    *
		    * @throws JDOMException   if the evaluation of the XPath
		    *                         expression on the specified context
		    *                         failed.
		    */
		   public Object selectSingleNode(Object context) throws JDOMException {
		      try {
		         currentContext = context;

		         return xPath.selectSingleNode(context);
		      }
		      catch (JaxenException ex1) {
		         throw new JDOMException("XPath error while evaluating \"" +
		                        xPath.toString() + "\": " + ex1.getMessage(), ex1);
		      }
		      finally {
		         currentContext = null;
		      }
		   }

		   /**
		    * Returns the string value of the first node selected by applying
		    * the wrapped XPath expression to the given context.
		    *
		    * @param  context   the element to use as context for evaluating
		    *                   the XPath expression.
		    *
		    * @return the string value of the first node selected by applying
		    *         the wrapped XPath expression to the given context.
		    *
		    * @throws JDOMException   if the XPath expression is invalid or
		    *                         its evaluation on the specified context
		    *                         failed.
		    */
		   public String valueOf(Object context) throws JDOMException {
		      try {
		         currentContext = context;

		         return xPath.stringValueOf(context);
		      }
		      catch (JaxenException ex1) {
		         throw new JDOMException("XPath error while evaluating \"" +
		                        xPath.toString() + "\": " + ex1.getMessage(), ex1);
		      }
		      finally {
		         currentContext = null;
		      }
		   }

		   /**
		    * Returns the number value of the first item selected by applying
		    * the wrapped XPath expression to the given context.
		    *
		    * @param  context   the element to use as context for evaluating
		    *                   the XPath expression.
		    *
		    * @return the number value of the first item selected by applying
		    *         the wrapped XPath expression to the given context,
		    *         <code>null</code> if no node was selected or the
		    *         special value {@link java.lang.Double#NaN}
		    *         (Not-a-Number) if the selected value can not be
		    *         converted into a number value.
		    *
		    * @throws JDOMException   if the XPath expression is invalid or
		    *                         its evaluation on the specified context
		    *                         failed.
		    */
		   public Number numberValueOf(Object context) throws JDOMException {
		      try {
		         currentContext = context;

		         return xPath.numberValueOf(context);
		      }
		      catch (JaxenException ex1) {
		         throw new JDOMException("XPath error while evaluating \"" +
		                        xPath.toString() + "\": " + ex1.getMessage(), ex1);
		      }
		      finally {
		         currentContext = null;
		      }
		   }

		   /**
		    * Defines an XPath variable and sets its value.
		    *
		    * @param  name    the variable name.
		    * @param  value   the variable value.
		    *
		    * @throws IllegalArgumentException   if <code>name</code> is not
		    *                                    a valid XPath variable name
		    *                                    or if the value type is not
		    *                                    supported by the underlying
		    *                                    implementation
		    */
		   public void setVariable(String name, Object value)
		                                        throws IllegalArgumentException {
		      Object o = xPath.getVariableContext();
		      if (o instanceof SimpleVariableContext) {
		           ((SimpleVariableContext)o).setVariableValue(null, name, value);
		      }
		   }

		   /**
		    * Adds a namespace definition to the list of namespaces known of
		    * this XPath expression.
		    * <p>
		    * <strong>Note</strong>: In XPath, there is no such thing as a
		    * 'default namespace'.  The empty prefix <b>always</b> resolves
		    * to the empty namespace URI.</p>
		    *
		    * @param  namespace   the namespace.
		    */
		   public void addNamespace(Namespace namespace) {
		      try {
		         xPath.addNamespace(namespace.getPrefix(), namespace.getURI());
		      }
		      catch (JaxenException ex1) { /* Can't happen here. */ }
		   }

		   /**
		 * Returns the wrapped XPath expression as a string.
		 * @return  the wrapped XPath expression as a string.
		 * @uml.property  name="xPath"
		 */
		   public String getXPath() {
		      return (xPath.toString());
		   }

		   /**
		    * Compiles and sets the XPath expression wrapped by this object.
		    *
		    * @param  expr   the XPath expression to wrap.
		    *
		    * @throws JDOMException   if the XPath expression is invalid.
		    */
		   private void setXPath(String expr) throws JDOMException {
		      try {
		         xPath = new JDOMXPath(expr);
		         xPath.setNamespaceContext(new NSContext());
		      }
		      catch (Exception ex1) {
		         throw new JDOMException(
		                        "Invalid XPath expression: \"" + expr + "\"", ex1);
		      }
		   }

		   public String toString() {
		      return (xPath.toString());
		   }

		   public boolean equals(Object o) {
		      if (o instanceof JaxenXPath) {
		         Ayuda x = (Ayuda)o;

		         return (super.equals(o) &&
		                 xPath.toString().equals(x.xPath.toString()));
		      }
		      return false;
		   }

		   public int hashCode() {
		      return xPath.hashCode();
		   }

		   private class NSContext extends SimpleNamespaceContext {
		      public NSContext() {
		         super();
		      }

		      /**
		       * <i>[Jaxen NamespaceContext interface support]</i> Translates
		       * the provided namespace prefix into the matching bound
		       * namespace URI.
		       *
		       * @param  prefix   the namespace prefix to resolve.
		       *
		       * @return the namespace URI matching the prefix.
		       */
		     /* public String translateNamespacePrefixToUri(String prefix) {
		         if ((prefix == null) || (prefix.length() == 0)) {
		            return null;
		         }

		         String uri = super.translateNamespacePrefixToUri(prefix);
		         if (uri == null) {
		            Object ctx = currentContext;
		            if (ctx != null) {
		               Element elt = null;

		               // Get closer element node
		               if (ctx instanceof Element) {
		                  elt = (Element)ctx;
		               } else if (ctx instanceof Attribute) {
		                  elt = ((Attribute)ctx).getParent();
		               } else if (ctx instanceof Content) {
		                  elt = ((Content) ctx).getParentElement();
		               } else if (ctx instanceof Document) {
		                  elt = ((Document)ctx).getRootElement();
		               }

		               if (elt != null) {
		                  Namespace ns = elt.getNamespace(prefix);
		                  if (ns != null) {
		                     uri = ns.getURI();
		                  }
		               }
		            }
		         }
		         return uri;
		      }*/
		   }
	
}
