You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by dm...@apache.org on 2002/10/13 04:59:02 UTC

cvs commit: jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/dom DOMNodePointer.java

dmitri      2002/10/12 19:59:02

  Modified:    jxpath/src/java/org/apache/commons/jxpath/ri/axes
                        SimplePathInterpreter.java
               jxpath/src/java/org/apache/commons/jxpath/ri/compiler
                        Path.java
               jxpath/src/java/org/apache/commons/jxpath/ri/model/beans
                        NullPropertyPointer.java BeanAttributeIterator.java
               jxpath/src/java/org/apache/commons/jxpath/ri/model
                        NodePointer.java
               jxpath/src/java/org/apache/commons/jxpath/ri/model/jdom
                        JDOMNodePointer.java
               jxpath/src/java/org/apache/commons/jxpath/ri/model/dom
                        DOMNodePointer.java
  Log:
  1. Now bean's properties can be accessed either with the child:: or the attribute:: axis.
  2. Missing attributes can be created with an AbstractFactory
  
  Revision  Changes    Path
  1.7       +60 -29    jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/axes/SimplePathInterpreter.java
  
  Index: SimplePathInterpreter.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/axes/SimplePathInterpreter.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- SimplePathInterpreter.java	10 Aug 2002 01:35:47 -0000	1.6
  +++ SimplePathInterpreter.java	13 Oct 2002 02:59:01 -0000	1.7
  @@ -119,7 +119,7 @@
        * starts with the given root, which is the result of evaluation
        * of the root expression of the expression path, applies the
        * given predicates to it and then follows the given steps.
  -     * All steps must have the axis "child::"
  +     * All steps must have the axis "child::" or "attribute::"
        * and a name test.  They can also optionally have predicates
        * of type [@name=...] or simply [...] interpreted as an index.
        */
  @@ -204,17 +204,7 @@
                   Step[] steps, int current_step)
       {
           Step step = steps[current_step];
  -        NodePointer childPointer;
  -        if (step.getAxis() == Compiler.AXIS_CHILD){
  -            // Treat the name test as a property name
  -            QName name = ((NodeNameTest)step.getNodeTest()).getNodeName();
  -
  -            childPointer = parentPointer.getPropertyPointer();
  -            ((PropertyPointer)childPointer).setPropertyName(name.toString());
  -        }
  -        else {
  -            childPointer = parentPointer;
  -        }
  +        NodePointer childPointer = createChildPointerForStep(parentPointer, step);
   
           if (!childPointer.isActual()){
               // The property does not exist - create a null pointer.
  @@ -272,10 +262,14 @@
                   Step[] steps, int current_step)
       {
           Step step = steps[current_step];
  +
  +        if (step.getAxis() == Compiler.AXIS_SELF){
  +            return doStep(context, parentPointer, steps, current_step + 1);
  +        }
  +
           int bestQuality = 0;
           NodePointer bestMatch = null;
  -        NodeIterator it =
  -                parentPointer.childIterator(step.getNodeTest(), false, null);
  +        NodeIterator it = getNodeIterator(parentPointer, step);
           if (it != null){
               for (int i = 1; it.setPosition(i); i++){
                   NodePointer childPointer = it.getNodePointer();
  @@ -316,15 +310,8 @@
           Step step = steps[current_step];
           Expression predicates[] = step.getPredicates();
   
  -        NodePointer childPointer;
  -        if (step.getAxis() == Compiler.AXIS_CHILD){
  -            QName name = ((NodeNameTest)step.getNodeTest()).getNodeName();
  -            childPointer = parentPointer.getPropertyPointer();
  -            ((PropertyPointer)childPointer).setPropertyName(name.toString());
  -        }
  -        else {
  -            childPointer = parentPointer;
  -        }
  +        NodePointer childPointer =
  +                createChildPointerForStep(parentPointer, step);
           if (!childPointer.isActual()){
               // Property does not exist - return a null pointer
               return createNullPointer(
  @@ -336,6 +323,28 @@
               context, childPointer, steps, current_step, predicates, 0);
       }
   
  +    private static NodePointer createChildPointerForStep(
  +                PropertyOwnerPointer parentPointer, Step step)
  +    {
  +        int axis = step.getAxis();
  +        if (axis == Compiler.AXIS_CHILD || axis == Compiler.AXIS_ATTRIBUTE){
  +            NodePointer childPointer;
  +            QName name = ((NodeNameTest)step.getNodeTest()).getNodeName();
  +            if (axis == Compiler.AXIS_ATTRIBUTE && isLangAttribute(name)){
  +                childPointer = new LangAttributePointer(parentPointer);
  +            }
  +            else {
  +                childPointer = parentPointer.getPropertyPointer();
  +                ((PropertyPointer)childPointer).setPropertyName(name.toString());
  +                childPointer.setAttribute(axis == Compiler.AXIS_ATTRIBUTE);
  +            }
  +            return childPointer;
  +        }
  +        else {
  +            return parentPointer;
  +        }
  +    }
  +
       /**
        * A path that starts with a standard InfoSet node, e.g. a DOM Node.
        * The method evaluates the first predicate in a special way and
  @@ -348,7 +357,8 @@
           Step step = steps[current_step];
           Expression predicates[] = step.getPredicates();
   
  -        if (step.getAxis() == Compiler.AXIS_SELF){
  +        int axis = step.getAxis();
  +        if (axis == Compiler.AXIS_SELF){
               return doPredicate(context, parent,
                   steps, current_step, predicates, 0);
           }
  @@ -361,8 +371,7 @@
           // It is a very common use case, so it deserves individual
           // attention
           if (predicates.length == 1){
  -            NodeIterator it = parent.childIterator(
  -                    step.getNodeTest(), false, null);
  +            NodeIterator it = getNodeIterator(parent, step);
               NodePointer pointer = null;
               if (it != null){
                   if (predicate instanceof NameAttributeTest){ // [@name = key]
  @@ -387,8 +396,7 @@
               }
           }
           else {
  -            NodeIterator it = parent.childIterator(
  -                    step.getNodeTest(), false, null);
  +            NodeIterator it = getNodeIterator(parent, step);
               if (it != null){
                   List list = new ArrayList();
                   for (int i = 1; it.setPosition(i); i++){
  @@ -686,10 +694,12 @@
   
           Step step = steps[current_step];
   
  -        if (step.getAxis() == Compiler.AXIS_CHILD){
  +        int axis = step.getAxis();
  +        if (axis == Compiler.AXIS_CHILD || axis == Compiler.AXIS_ATTRIBUTE){
               NullPropertyPointer pointer = new NullPropertyPointer(parent);
               QName name = ((NodeNameTest)step.getNodeTest()).getNodeName();
               pointer.setPropertyName(name.toString());
  +            pointer.setAttribute(axis == Compiler.AXIS_ATTRIBUTE);
               parent = pointer;
           }
           // else { it is self::node() }
  @@ -729,5 +739,26 @@
           // Proceed with the remaining steps
           return createNullPointer(
                       context, parent, steps, current_step + 1);
  +    }
  +
  +    private static NodeIterator getNodeIterator(NodePointer pointer, Step step){
  +        if (step.getAxis() == Compiler.AXIS_CHILD){
  +            return pointer.childIterator(step.getNodeTest(), false, null);
  +        }
  +        else {      // Compiler.AXIS_ATTRIBUTE
  +            if (!(step.getNodeTest() instanceof NodeNameTest)){
  +                throw new UnsupportedOperationException(
  +                    "Not supported node test for attributes: " +
  +                        step.getNodeTest());
  +            }
  +            return pointer.attributeIterator(
  +                ((NodeNameTest)step.getNodeTest()).getNodeName());
  +        }
  +    }
  +
  +    private static boolean isLangAttribute(QName name){
  +        return name.getPrefix() != null &&
  +                name.getPrefix().equals("xml") &&
  +                name.getName().equals("lang");
       }
   }
  
  
  
  1.6       +6 -5      jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/compiler/Path.java
  
  Index: Path.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/compiler/Path.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- Path.java	10 Aug 2002 01:39:29 -0000	1.5
  +++ Path.java	13 Oct 2002 02:59:01 -0000	1.6
  @@ -115,7 +115,8 @@
                                   Compiler.NODE_TYPE_NODE){
                       accepted = true;
                   }
  -                else if (steps[i].getAxis() == Compiler.AXIS_CHILD &&
  +                else if ((steps[i].getAxis() == Compiler.AXIS_CHILD ||
  +                          steps[i].getAxis() == Compiler.AXIS_ATTRIBUTE)  &&
                           (steps[i].getNodeTest() instanceof NodeNameTest) &&
                           !((NodeNameTest)steps[i].getNodeTest()).
                                       getNodeName().getName().equals("*")){
  
  
  
  1.8       +24 -12    jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/beans/NullPropertyPointer.java
  
  Index: NullPropertyPointer.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/beans/NullPropertyPointer.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- NullPropertyPointer.java	10 Aug 2002 16:13:04 -0000	1.7
  +++ NullPropertyPointer.java	13 Oct 2002 02:59:01 -0000	1.8
  @@ -82,7 +82,7 @@
       }
   
       public QName getName(){
  -        return new QName(null, propertyName);
  +        return new QName(propertyName);
       }
   
       public void setPropertyIndex(int index){
  @@ -101,7 +101,7 @@
       }
   
       public NodePointer getValuePointer(){
  -        return new NullPointer(this,  new QName(null, getPropertyName()));
  +        return new NullPointer(this,  new QName(getPropertyName()));
       }
   
       protected boolean isActualProperty(){
  @@ -122,19 +122,31 @@
       }
   
       public NodePointer createPath(JXPathContext context){
  -        return parent.createChild(context, getName(), getIndex());
  +        if (isAttribute()){
  +            return parent.createAttribute(context, getName());
  +        }
  +        else {
  +            return parent.createChild(context, getName(), getIndex());
  +        }
       }
   
       public NodePointer createPath(JXPathContext context, Object value){
  -        return parent.createChild(context, getName(), getIndex(), value);
  +        if (isAttribute()){
  +            NodePointer pointer = parent.createAttribute(context, getName());
  +            pointer.setValue(value);
  +            return pointer;
  +        }
  +        else {
  +            return parent.createChild(context, getName(), getIndex(), value);
  +        }
       }
   
  -    public NodePointer createChild(JXPathContext context, 
  +    public NodePointer createChild(JXPathContext context,
               QName name, int index, Object value){
           return createPath(context).createChild(context, name, index, value);
       }
   
  -    public NodePointer createChild(JXPathContext context, 
  +    public NodePointer createChild(JXPathContext context,
               QName name, int index){
           return createPath(context).createChild(context, name, index);
       }
  @@ -184,13 +196,13 @@
       private String escape(String string){
           int index = string.indexOf('\'');
           while (index != -1){
  -            string = string.substring(0, index) + "'" + 
  +            string = string.substring(0, index) + "'" +
                       string.substring(index + 1);
               index = string.indexOf('\'');
           }
           index = string.indexOf('\"');
           while (index != -1){
  -            string = string.substring(0, index) + """ + 
  +            string = string.substring(0, index) + """ +
                       string.substring(index + 1);
               index = string.indexOf('\"');
           }
  
  
  
  1.3       +34 -13    jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/beans/BeanAttributeIterator.java
  
  Index: BeanAttributeIterator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/beans/BeanAttributeIterator.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- BeanAttributeIterator.java	24 Apr 2002 04:06:46 -0000	1.2
  +++ BeanAttributeIterator.java	13 Oct 2002 02:59:01 -0000	1.3
  @@ -66,24 +66,35 @@
   import org.apache.commons.jxpath.ri.model.NodePointer;
   
   /**
  - * An iterator of attributes of a JavaBean. Currently supports only one
  - * attribute - "lang".
  + * An iterator of attributes of a JavaBean. Returns bean properties as
  + * well as the "xml:lang" attribute.
    *
    * @author Dmitri Plotnikov
    * @version $Revision$ $Date$
    */
  -public class BeanAttributeIterator implements NodeIterator {
  +public class BeanAttributeIterator extends PropertyIterator {
       private NodePointer parent;
  -    private QName name;
       private int position = 0;
  +    private boolean includeXmlLang;
   
  -    public BeanAttributeIterator(NodePointer parent, QName name){
  +    public BeanAttributeIterator(PropertyOwnerPointer parent, QName name){
  +        super(parent,
  +                (name.getPrefix() == null &&
  +                 (name.getName() == null || name.getName().equals("*"))) ?
  +                        null : name.toString(), false, null);
           this.parent = parent;
  -        this.name = name;
  +        includeXmlLang =
  +            (name.getPrefix() != null && name.getPrefix().equals("xml")) &&
  +            (name.getName().equals("lang") || name.getName().equals("*"));
       }
   
       public NodePointer getNodePointer(){
  -        return new LangAttributePointer(parent);
  +        if (includeXmlLang && position == 1){
  +            return new LangAttributePointer(parent);
  +        }
  +        else {
  +            return super.getNodePointer();
  +        }
       }
   
       public int getPosition(){
  @@ -92,7 +103,17 @@
   
       public boolean setPosition(int position){
           this.position = position;
  -        return position == 1 && name.getPrefix() != null && name.getPrefix().equals("xml") &&
  -            (name.getName().equals("lang") || name.getName().equals("*"));
  +        if (includeXmlLang){
  +            if (position == 1){
  +                return true;
  +            }
  +            else {
  +                return super.setPosition(position - 1);
  +            }
  +        }
  +        else {
  +            this.position = position;
  +            return super.setPosition(position);
  +        }
       }
   }
  
  
  
  1.11      +86 -43    jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/NodePointer.java
  
  Index: NodePointer.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/NodePointer.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- NodePointer.java	10 Aug 2002 16:13:03 -0000	1.10
  +++ NodePointer.java	13 Oct 2002 02:59:01 -0000	1.11
  @@ -91,45 +91,51 @@
       public static int WHOLE_COLLECTION = Integer.MIN_VALUE;
       protected int index = WHOLE_COLLECTION;
       public static String UNKNOWN_NAMESPACE = "<<unknown namespace>>";
  +    private boolean attribute = false;
   
       /**
        * Allocates an entirely new NodePointer by iterating through all installed
        * NodePointerFactories until it finds one that can create a pointer.
        */
       public static NodePointer newNodePointer(
  -        QName name,
  -        Object bean,
  -        Locale locale) {
  +            QName name, Object bean, Locale locale)
  +    {
           if (bean == null) {
               return new NullPointer(name, locale);
           }
           NodePointerFactory[] factories =
               JXPathContextReferenceImpl.getNodePointerFactories();
           for (int i = 0; i < factories.length; i++) {
  -            NodePointer pointer = factories[i].createNodePointer(name, bean, locale);
  +            NodePointer pointer = factories[i].
  +                    createNodePointer(name, bean, locale);
               if (pointer != null) {
                   return pointer;
               }
           }
           throw new JXPathException(
  -            "Could not allocate a NodePointer for object of " + bean.getClass());
  +            "Could not allocate a NodePointer for object of " +
  +            bean.getClass());
       }
   
       /**
        * Allocates an new child NodePointer by iterating through all installed
        * NodePointerFactories until it finds one that can create a pointer.
        */
  -    public static NodePointer newChildNodePointer(NodePointer parent, QName name, Object bean) {
  +    public static NodePointer newChildNodePointer(
  +            NodePointer parent, QName name, Object bean)
  +    {
           NodePointerFactory[] factories =
               JXPathContextReferenceImpl.getNodePointerFactories();
           for (int i = 0; i < factories.length; i++) {
  -            NodePointer pointer = factories[i].createNodePointer(parent, name, bean);
  +            NodePointer pointer = factories[i].
  +                    createNodePointer(parent, name, bean);
               if (pointer != null) {
                   return pointer;
               }
           }
           throw new JXPathException(
  -            "Could not allocate a NodePointer for object of " + bean.getClass());
  +            "Could not allocate a NodePointer for object of " +
  +            bean.getClass());
       }
   
       protected NodePointer parent;
  @@ -149,6 +155,20 @@
       }
   
       /**
  +     * Set to true if the pointer represents the "attribute::" axis.
  +     */
  +    public void setAttribute(boolean attribute){
  +        this.attribute = attribute;
  +    }
  +
  +    /**
  +     * Returns true if the pointer represents the "attribute::" axis.
  +     */
  +    public boolean isAttribute(){
  +        return attribute;
  +    }
  +
  +    /**
        * Returns true if this Pointer has no parent.
        */
       public boolean isRoot() {
  @@ -198,7 +218,8 @@
   
       /**
        * If the pointer represents a collection (or collection element),
  -     * returns the length of the collection. Otherwise returns 1 (even if the value is null).
  +     * returns the length of the collection.
  +     * Otherwise returns 1 (even if the value is null).
        */
       public int getLength() {
           Object value = getBaseValue();
  @@ -232,11 +253,13 @@
        * if it is null. A non-actual pointer represents a part that does not exist
        * at all.
        * For instance consider the pointer "/address/street".
  -     * If both <em>address</em> and <em>street</em> are not null, the pointer is actual.
  -     * If <em>address</em> is not null, but <em>street</em> is null, the pointer is still actual.
  +     * If both <em>address</em> and <em>street</em> are not null,
  +     * the pointer is actual.
  +     * If <em>address</em> is not null, but <em>street</em> is null,
  +     * the pointer is still actual.
        * If <em>address</em> is null, the pointer is not actual.
  -     * (In JavaBeans) if <em>address</em> is not a property of the root bean, a Pointer
  -     * for this path cannot be obtained at all - actual or otherwise.
  +     * (In JavaBeans) if <em>address</em> is not a property of the root bean,
  +     * a Pointer for this path cannot be obtained at all - actual or otherwise.
        */
       public boolean isActual() {
           if (index == WHOLE_COLLECTION) {
  @@ -262,11 +285,11 @@
       /**
        * Returns the object the pointer points to; does not convert it
        * to a "canonical" type.
  -     * 
  +     *
        * @deprecated 1.1 Please use getNode()
        */
       public Object getNodeValue(){
  -    	return getNode();
  +        return getNode();
       }
   
       /**
  @@ -274,7 +297,7 @@
        * to a "canonical" type.
        */
       public abstract Object getNode();
  -    
  +
       /**
        * Converts the value to the required type and changes the corresponding
        * object to that value.
  @@ -285,7 +308,8 @@
        * Compares two child NodePointers and returns a positive number,
        * zero or a positive number according to the order of the pointers.
        */
  -    public abstract int compareChildNodePointers(NodePointer pointer1, NodePointer pointer2);
  +    public abstract int compareChildNodePointers(
  +            NodePointer pointer1, NodePointer pointer2);
   
       /**
        * Checks if this Pointer matches the supplied NodeTest.
  @@ -316,7 +340,7 @@
               return testLocalName.equals(nodeName.getName());
           }
           else if (test instanceof NodeTypeTest) {
  -            if (((NodeTypeTest) test).getNodeType() == Compiler.NODE_TYPE_NODE) {
  +            if (((NodeTypeTest) test).getNodeType() == Compiler.NODE_TYPE_NODE){
                   return isNode();
               }
           }
  @@ -371,20 +395,31 @@
                               int index, Object value) {
           throw new JXPathException(
               "Cannot create an object for path "
  -                + asPath()
  +                + asPath() + "/" + name + "[" + (index + 1) + "]"
                   + ", operation is not allowed for this type of node");
       }
   
       /**
        * Called by a child pointer when it needs to create a parent object
  -     * for a non-existent collection element.  It may have to expand the collection,
  -     * then create an element object and return a new pointer describing the
  -     * newly created element.
  +     * for a non-existent collection element.  It may have to expand the
  +     * collection, then create an element object and return a new pointer
  +     * describing the newly created element.
        */
  -    public NodePointer createChild(JXPathContext context, QName name, int index) {
  +    public NodePointer createChild(
  +            JXPathContext context, QName name, int index) {
           throw new JXPathException(
               "Cannot create an object for path "
  -                + asPath()
  +                + asPath() + "/" + name + "[" + (index + 1) + "]"
  +                + ", operation is not allowed for this type of node");
  +    }
  +
  +    /**
  +     * Called to create a non-existing attribute
  +     */
  +    public NodePointer createAttribute(JXPathContext context, QName name){
  +        throw new JXPathException(
  +            "Cannot create an attribute for path "
  +                + asPath() + "/@" + name
                   + ", operation is not allowed for this type of node");
       }
   
  @@ -426,8 +461,8 @@
       }
   
       /**
  -     * Returns a NodeIterator that iterates over all attributes of the current node
  -     * matching the supplied node name (could have a wildcard).
  +     * Returns a NodeIterator that iterates over all attributes of the current
  +     * node matching the supplied node name (could have a wildcard).
        * May return null if the object does not support the attributes.
        */
       public NodeIterator attributeIterator(QName qname) {
  @@ -449,7 +484,8 @@
   
       /**
        * Returns a NodePointer for the specified namespace. Will return null
  -     * if namespaces are not supported. Will return UNKNOWN_NAMESPACE if there is no such namespace.
  +     * if namespaces are not supported.
  +     * Will return UNKNOWN_NAMESPACE if there is no such namespace.
        */
       public NodePointer namespacePointer(String namespace) {
           return null;
  @@ -520,20 +556,27 @@
           StringBuffer buffer = new StringBuffer();
           if (getParent() != null) {
               buffer.append(getParent().asPath());
  -            // TBD: the following needs to be redesigned.  What this condition says is
  -            // "if the parent of this node has already appended this node's name,
  -            // don't do it again".  However, I would hate to add an ugly API like
  -            // "isResponsibleForAppendingChildName()".
  -            if (getParent().isNode() || (parent instanceof NullElementPointer)) {
  +            // TBD: the following needs to be redesigned.
  +            // What this condition says is
  +            // "if the parent of this node has already appended this node's
  +            // name, don't do it again".  However, I would hate to add an ugly
  +            // API like "isResponsibleForAppendingChildName()".
  +            if (getParent().isNode() || (parent instanceof NullElementPointer)){
                   QName name = getName();
                   if (name != null) {
                       buffer.append('/');
  +                    if (attribute){
  +                        buffer.append('@');
  +                    }
                       buffer.append(name);
                   }
               }
           }
           else {
               QName name = getName();
  +            if (attribute){
  +                buffer.append('@');
  +            }
               buffer.append(name);
           }
           if (index != WHOLE_COLLECTION && isCollection()) {
  @@ -542,9 +585,7 @@
           return buffer.toString();
       }
   
  -    public static int count = 0;
       public Object clone() {
  -        count ++;
           try {
               NodePointer ptr = (NodePointer)super.clone();
               if (parent != null){
  @@ -564,7 +605,8 @@
       }
   
       public int compareTo(Object object){
  -        NodePointer pointer = (NodePointer) object;         // Let it throw a ClassCastException
  +        // Let it throw a ClassCastException
  +        NodePointer pointer = (NodePointer) object;
           if (parent == pointer.parent){
               if (parent == null){
                   return 0;
  @@ -588,9 +630,9 @@
           return compareNodePointers(this, depth1, pointer, depth2);
       }
   
  -    private int compareNodePointers(NodePointer p1, int depth1, NodePointer p2, int depth2){
  -//        System.err.println("Comparing " + p1.asPath() + " (" + depth1 + ") ~ " +
  -//                p2.asPath() + " (" + depth2 + ")");
  +    private int compareNodePointers(
  +            NodePointer p1, int depth1, NodePointer p2, int depth2)
  +    {
           if (depth1 < depth2){
               int r = compareNodePointers(p1, depth1, p2.parent, depth2-1);
               if (r != 0){
  @@ -618,7 +660,8 @@
                   "Cannot compare pointers that do not belong to the same tree: '"
                   + p1 + "' and '" + p2 + "'");
           }
  -        int r = compareNodePointers(p1.parent, depth1 - 1, p2.parent, depth2 - 1);
  +        int r = compareNodePointers(
  +                p1.parent, depth1 - 1, p2.parent, depth2 - 1);
           if (r != 0){
               return r;
           }
  
  
  
  1.2       +32 -4     jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/jdom/JDOMNodePointer.java
  
  Index: JDOMNodePointer.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/jdom/JDOMNodePointer.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- JDOMNodePointer.java	26 Aug 2002 22:29:48 -0000	1.1
  +++ JDOMNodePointer.java	13 Oct 2002 02:59:02 -0000	1.2
  @@ -486,6 +486,34 @@
           return ptr;
       }
   
  +    public NodePointer createAttribute(JXPathContext context, QName name){
  +        if (!(node instanceof Element)){
  +            return super.createAttribute(context, name);
  +        }
  +
  +        Element element = (Element)node;
  +        String prefix = name.getPrefix();
  +        if (prefix != null){
  +            Namespace ns = element.getNamespace(prefix);
  +            if (ns == null){
  +                throw new JXPathException("Unknown namespace prefix: " + prefix);
  +            }
  +            Attribute attr = element.getAttribute(name.getName(), ns);
  +            if (attr == null){
  +                element.setAttribute(name.getName(), "", ns);
  +            }
  +        }
  +        else {
  +            Attribute attr = element.getAttribute(name.getName());
  +            if (attr == null){
  +                element.setAttribute(name.getName(), "");
  +            }
  +        }
  +        NodeIterator it = attributeIterator(name);
  +        it.setPosition(1);
  +        return it.getNodePointer();
  +    }
  +
       public void remove(){
           Element parent = nodeParent(node);
           if (parent == null){
  
  
  
  1.10      +27 -4     jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/dom/DOMNodePointer.java
  
  Index: DOMNodePointer.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/jxpath/src/java/org/apache/commons/jxpath/ri/model/dom/DOMNodePointer.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- DOMNodePointer.java	26 Aug 2002 22:15:26 -0000	1.9
  +++ DOMNodePointer.java	13 Oct 2002 02:59:02 -0000	1.10
  @@ -403,6 +403,29 @@
           return ptr;
       }
   
  +    public NodePointer createAttribute(JXPathContext context, QName name){
  +        if (!(node instanceof Element)){
  +            return super.createAttribute(context, name);
  +        }
  +        Element element = (Element)node;
  +        String prefix = name.getPrefix();
  +        if (prefix != null){
  +            String ns = getNamespaceURI(prefix);
  +            if (ns == null){
  +                throw new JXPathException("Unknown namespace prefix: " + prefix);
  +            }
  +            element.setAttributeNS(ns, name.toString(), "");
  +        }
  +        else {
  +            if (!element.hasAttribute(name.getName())){
  +                element.setAttribute(name.getName(), "");
  +            }
  +        }
  +        NodeIterator it = attributeIterator(name);
  +        it.setPosition(1);
  +        return it.getNodePointer();
  +    }
  +
       public void remove(){
           Node parent = node.getParentNode();
           if (parent == null){
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>