You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by mo...@apache.org on 2001/10/16 12:59:00 UTC

cvs commit: xml-xalan/java/src/org/apache/xalan/xsltc/dom DOMAdapter.java DOMImpl.java

morten      01/10/16 03:58:59

  Modified:    java/src/org/apache/xalan/xsltc DOM.java
               java/src/org/apache/xalan/xsltc/compiler XSLTC.java
                        xpath.cup
               java/src/org/apache/xalan/xsltc/dom DOMAdapter.java
                        DOMImpl.java
  Log:
  Added support for the namespace axis.
  PR:		bugzilla 1379
  Obtained from:	n/a
  Submitted by:	morten@xml.apache.org
  Reviewed by:	morten@xml.apache.org
  
  Revision  Changes    Path
  1.7       +2 -2      xml-xalan/java/src/org/apache/xalan/xsltc/DOM.java
  
  Index: DOM.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/DOM.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- DOM.java	2001/10/05 09:47:55	1.6
  +++ DOM.java	2001/10/16 10:58:59	1.7
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: DOM.java,v 1.6 2001/10/05 09:47:55 morten Exp $
  + * @(#)$Id: DOM.java,v 1.7 2001/10/16 10:58:59 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -72,7 +72,7 @@
       public final static int  NO_TYPE                = -1;
       public final static int  ROOT                   = 0;
       public final static int  TEXT                   = 1;
  -    public final static int  UNUSED                 = 2;
  +    public final static int  NAMESPACE              = 2;
       public final static int  ELEMENT                = 3;
       public final static int  ATTRIBUTE              = 4;
       public final static int  PROCESSING_INSTRUCTION = 5;
  
  
  
  1.25      +12 -1     xml-xalan/java/src/org/apache/xalan/xsltc/compiler/XSLTC.java
  
  Index: XSLTC.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/XSLTC.java,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- XSLTC.java	2001/08/27 09:07:20	1.24
  +++ XSLTC.java	2001/10/16 10:58:59	1.25
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: XSLTC.java,v 1.24 2001/08/27 09:07:20 morten Exp $
  + * @(#)$Id: XSLTC.java,v 1.25 2001/10/16 10:58:59 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -575,6 +575,17 @@
   	    registerNamespace(name.getNamespace());
   	}
   	return code.intValue();
  +    }
  +
  +    /**
  +     * Registers an element and gives it a type so that it can be mapped to
  +     * DOM element types at run-time.
  +     */
  +    public int registerNamespace(QName name) {
  +	final SymbolTable stable = _parser.getSymbolTable();
  +	final String uri = stable.lookupNamespace(name.toString());
  +	final int code = registerNamespace(uri);
  +	return code; 
       }
   
       /**
  
  
  
  1.24      +27 -9     xml-xalan/java/src/org/apache/xalan/xsltc/compiler/xpath.cup
  
  Index: xpath.cup
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/xpath.cup,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- xpath.cup	2001/10/10 10:14:10	1.23
  +++ xpath.cup	2001/10/16 10:58:59	1.24
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: xpath.cup,v 1.23 2001/10/10 10:14:10 morten Exp $
  + * @(#)$Id: xpath.cup,v 1.24 2001/10/16 10:58:59 morten Exp $
    *
    * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved.
    * 
  @@ -70,27 +70,45 @@
   
       public int findNodeType(int axis, Object test, boolean inPattern) {
   	if (test == null) {  // *
  -            return axis == Axis.ATTRIBUTE
  -                   ? NodeTest.ATTRIBUTE
  -                   : NodeTest.ELEMENT;
  +            if (axis == Axis.ATTRIBUTE)
  +                return NodeTest.ATTRIBUTE;
  +            else if (axis == Axis.NAMESPACE)
  +                return -1;
  +            else
  +                return NodeTest.ELEMENT;
           }
           else if (test instanceof Integer) {
               return ((Integer)test).intValue();
           }
           else {
   	    QName name = (QName)test;
  +
  +	    if (axis == Axis.NAMESPACE) {
  +                if (name.toString().equals("*"))
  +                    return -1;
  +                else
  +                    return _xsltc.registerNamespace(name);
  +            }
  +
               if (name.getPrefix() == null || name.getNamespace() == null) {
                   final String local = name.getLocalPart();
  -	        if (local.equals("*"))
  -                    return(NodeTest.ELEMENT);
  +	        if (local.equals("*")) {
  +                    if (axis == Axis.ATTRIBUTE)
  +                        return(NodeTest.ATTRIBUTE);
  +                    else
  +                        return(NodeTest.ELEMENT);
  +                }
                   else if (local.equals("@*"))
                       return(NodeTest.ATTRIBUTE);
   	        if (inPattern)
                       name = new QName(null,null,local);
  +            }
  +            if (axis == Axis.ATTRIBUTE) {
  +                return _xsltc.registerAttribute(name);
  +            }
  +            else {
  +		return _xsltc.registerElement(name);
               }
  -	    return axis == Axis.ATTRIBUTE
  -		? _xsltc.registerAttribute(name)
  -		: _xsltc.registerElement(name);
           }
       }
   
  
  
  
  1.9       +12 -3     xml-xalan/java/src/org/apache/xalan/xsltc/dom/DOMAdapter.java
  
  Index: DOMAdapter.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/DOMAdapter.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- DOMAdapter.java	2001/10/05 09:47:55	1.8
  +++ DOMAdapter.java	2001/10/16 10:58:59	1.9
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: DOMAdapter.java,v 1.8 2001/10/05 09:47:55 morten Exp $
  + * @(#)$Id: DOMAdapter.java,v 1.9 2001/10/16 10:58:59 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -141,8 +141,17 @@
       }
       
       public NodeIterator getTypedAxisIterator(final int axis, final int type) {
  -	NodeIterator iterator =
  -	    _domImpl.getTypedAxisIterator(axis, _reverse[type]);
  +	NodeIterator iterator;
  +
  +	if (axis == Axis.NAMESPACE) {
  +	    if ((type == NO_TYPE) || (type > _NSreverse.length))
  +		iterator = _domImpl.getAxisIterator(axis);
  +	    else
  +		iterator = _domImpl.getTypedAxisIterator(axis,_NSreverse[type]);
  +	}
  +	else
  +	    iterator = _domImpl.getTypedAxisIterator(axis, _reverse[type]);
  +	
   	if ((_reverse[type] == DOM.TEXT) && (_filter != null))
   	    iterator = _domImpl.strippingIterator(iterator,_mapping,_filter);
   	return(iterator);
  
  
  
  1.45      +201 -38   xml-xalan/java/src/org/apache/xalan/xsltc/dom/DOMImpl.java
  
  Index: DOMImpl.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/dom/DOMImpl.java,v
  retrieving revision 1.44
  retrieving revision 1.45
  diff -u -r1.44 -r1.45
  --- DOMImpl.java	2001/10/15 10:10:39	1.44
  +++ DOMImpl.java	2001/10/16 10:58:59	1.45
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: DOMImpl.java,v 1.44 2001/10/15 10:10:39 morten Exp $
  + * @(#)$Id: DOMImpl.java,v 1.45 2001/10/16 10:58:59 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -406,6 +406,10 @@
   	public NamedNodeMap getAttributes() {
   	    if (getNodeType() == Node.ELEMENT_NODE) {
   		int attribute = _lengthOrAttr[_index];
  +		// Skip attribute nodes
  +		while (_type[attribute] == NAMESPACE) {
  +		    attribute = _nextSibling[attribute];
  +		}
   		if (attribute != NULL) {
   		    final IntegerArray attributes = new IntegerArray(4);
   		    do {
  @@ -546,7 +550,11 @@
   	}
   
   	public boolean hasAttributes() {
  -	    return (_lengthOrAttr[_index] != NULL);
  +	    int attribute = _lengthOrAttr[_index];
  +	    while (_type[attribute] == NAMESPACE) {
  +		attribute = _nextSibling[attribute];
  +	    }
  +	    return (attribute != NULL);
   	}
   
       }
  @@ -826,7 +834,10 @@
   	public int next() {
   	    final int save = _attribute;
   	    int node = save;
  -	    _attribute = _nextSibling[_attribute];
  +	    do {
  +		_attribute = _nextSibling[_attribute];
  +	    } while(_type[_attribute] == NAMESPACE);
  +	    
   	    for (node = _lengthOrAttr[_startNode = node];
   		 node != NULL && getNamespaceType(node) != _nsType;
   		 node = _nextSibling[node]);
  @@ -907,9 +918,16 @@
   	// assumes caller will pass element nodes
   	public NodeIterator setStartNode(int node) {
   	    if (_isRestartable) {
  -		_attribute = isElement(node)
  -		    ? _lengthOrAttr[_startNode = node]
  -		    : NULL;
  +		if (isElement(node)) {
  +		    _attribute = _lengthOrAttr[_startNode = node];
  +		    // Skip namespace nodes
  +		    while ((_attribute != NULL) &&
  +			   (_type[_attribute] == NAMESPACE))
  +			_attribute = _nextSibling[_attribute];
  +		}
  +		else {
  +		    _attribute = NULL;
  +		}
   		return resetPosition();
   	    }
   	    return this;
  @@ -971,6 +989,92 @@
   
   
       /**************************************************************
  +     * Iterator that returns namespace nodes
  +     */
  +    private class NamespaceIterator extends NodeIteratorBase {
  +	
  +	protected int _node;
  +	protected int _ns;
  +         
  +	// assumes caller will pass element nodes
  +	public NodeIterator setStartNode(int node) {
  +	    if (_isRestartable) {
  +		if (isElement(node)) {
  +		    _startNode = _node = node;
  +		    _ns = _lengthOrAttr[_node];
  +		    while ((_ns != DOM.NULL) && (_type[_ns] != NAMESPACE)) {
  +			_ns = _nextSibling[_ns];
  +		    }
  +		}
  +		else {
  +		    _ns = DOM.NULL;
  +		}
  +		return resetPosition();
  +	    }
  +	    return this;
  +	}
  +                  
  +	public int next() {
  +	    while (_node != NULL) {
  +		final int node = _ns;
  +		_ns = _nextSibling[_ns];
  +
  +		while ((_ns == DOM.NULL) && (_node != DOM.NULL)) {
  +		    _node = _parent[_node];
  +		    _ns = _lengthOrAttr[_node];
  +		    while ((_ns != DOM.NULL) && (_type[_ns] != NAMESPACE)) {
  +			_ns = _nextSibling[_ns];
  +		    }
  +		}
  +		if (_type[node] == NAMESPACE)
  +		    return returnNode(node);
  +	    }
  +	    return NULL;
  +	}
  +
  +	public void setMark() {
  +	    _markedNode = _ns;
  +	}
  +
  +	public void gotoMark() {
  +	    _ns = _markedNode;
  +	}
  +	
  +    } // end of NamespaceIterator
  +
  +
  +    /**************************************************************
  +     * Iterator that returns namespace nodes
  +     */
  +    private final class TypedNamespaceIterator extends NamespaceIterator {
  +
  +	final int _uriType;
  +
  +	public TypedNamespaceIterator(int type) {
  +	    _uriType = type;
  +	}
  +
  +	public int next() {
  +	    int node;
  +
  +	    while ((node = _ns) != DOM.NULL) {
  +		_ns = _nextSibling[_ns];
  +		while ((_ns == DOM.NULL) && (_node != DOM.NULL)) {
  +		    _node = _parent[_node];
  +		    _ns = _lengthOrAttr[_node];
  +		    while ((_ns != DOM.NULL) && (_type[_ns] != NAMESPACE)) {
  +			_ns = _nextSibling[_ns];
  +		    }
  +		}
  +		if (_prefix[node] == _uriType) return returnNode(node);
  +	    }
  +	    return DOM.NULL;
  +	}
  +         
  +    } // end of AttributeIterator
  +
  +
  +    /**************************************************************
        * Iterator that returns preceding siblings of a given node
        */
       private class PrecedingSiblingIterator extends NodeIteratorBase {
  @@ -1775,6 +1879,7 @@
        * Returns the (String) value of any node in the tree
        */
       public String getNodeValue(final int node) {
  +	// NS prefix = _prefixArray[_prefix[node]]
   	if ((node == NULL) || (node > _treeNodeLimit)) return EMPTYSTRING;
   	switch(_type[node]) {
   	case ROOT:
  @@ -1861,7 +1966,8 @@
   		len = uri.length();
   		if (len > 0) len++;
   	    }
  -	    if (name.charAt(len) == '@')
  +
  +	    if ((name.length() > 0) && (name.charAt(len) == '@'))
   		result[i] = (short)ATTRIBUTE;
   	    else
   		result[i] = (short)ELEMENT;
  @@ -2054,11 +2160,12 @@
   	switch(type) {
   	case DOM.ROOT:
   	case DOM.TEXT:
  -	case DOM.UNUSED:
   	case DOM.ELEMENT:
   	case DOM.ATTRIBUTE:
   	case DOM.COMMENT:
   	    return EMPTYSTRING;
  +	case DOM.NAMESPACE:
  +	    return _prefixArray[_prefix[node]];
   	case DOM.PROCESSING_INSTRUCTION:
   	    final String pistr = makeStringValue(node);
   	    final int col = pistr.indexOf(' ');
  @@ -2215,7 +2322,8 @@
   	    iterator = new PrecedingSiblingIterator();
   	    break;
   	case Axis.NAMESPACE:
  -	    return(new TypedAttributeIterator(getGeneralizedType("xmlns")));
  +	    iterator = new NamespaceIterator();
  +	    break;
   	default:
   	    BasisLibrary.runTimeError("Error: iterator for axis '" + 
   				      Axis.names[axis] + "' not implemented");
  @@ -2239,7 +2347,7 @@
   	if (type == NO_TYPE) {
   	    return(EMPTYITERATOR);
   	}
  -        else if (type == ELEMENT) {
  +        else if ((type == ELEMENT) && (axis != Axis.NAMESPACE)) {
   	    iterator = new FilterIterator(getAxisIterator(axis),
   					  getElementFilter());
   	}
  @@ -2277,6 +2385,12 @@
   	    case Axis.PRECEDINGSIBLING:
   		iterator = new TypedPrecedingSiblingIterator(type);
   		break;
  +	    case Axis.NAMESPACE:
  +		if (type == ELEMENT)
  +		    iterator = new NamespaceIterator();
  +		else
  +		    iterator = new TypedNamespaceIterator(type);
  +		break;
   	    default:
   		BasisLibrary.runTimeError("Error: typed iterator for axis " + 
   					  Axis.names[axis]+"not implemented");
  @@ -2404,18 +2518,27 @@
   	case ATTRIBUTE:
   	    shallowCopy(node, handler);
   	    break;
  +	case NAMESPACE:
  +	    shallowCopy(node, handler);
  +	    break;
   	default:
   	    if (isElement(node)) {
   		// Start element definition
   		final String name = copyElement(node, type, handler);
   		// Copy element attribute
   		for (int a=_lengthOrAttr[node]; a!=NULL; a=_nextSibling[a]) {
  -		    final String uri = getNamespaceName(a);
  -		    if (uri != EMPTYSTRING) {
  -			final String prefix = _prefixArray[_prefix[a]];
  -			handler.namespace(prefix, uri);
  +		    if (_type[a] != NAMESPACE) {
  +			final String uri = getNamespaceName(a);
  +			if (uri != EMPTYSTRING) {
  +			    final String prefix = _prefixArray[_prefix[a]];
  +			    handler.namespace(prefix, uri);
  +			}
  +			handler.attribute(getNodeName(a), makeStringValue(a));
  +		    }
  +		    else {
  +			handler.namespace(_prefixArray[_prefix[a]],
  +					  makeStringValue(a));
   		    }
  -		    handler.attribute(getNodeName(a), makeStringValue(a));
   		}
   		// Copy element children
   		for (int c=_offsetOrChild[node]; c!=NULL; c=_nextSibling[c])
  @@ -2458,10 +2581,6 @@
   
       /**
        * Performs a shallow copy (ref. XSLs copy())
  -     *
  -     * TODO: Copy namespace declarations. Can't be done until we
  -     *       add namespace nodes and keep track of NS prefixes
  -     * TODO: Copy comment nodes
        */
       public String shallowCopy(final int node, TransletOutputHandler handler)
   	throws TransletException {
  @@ -2485,6 +2604,10 @@
   					      _lengthOrAttr[node]);
   	    handler.comment(comment);
   	    return null;
  +	case NAMESPACE:
  +	    handler.namespace(_prefixArray[_prefix[node]],
  +			      makeStringValue(node));
  +	    return null;
   	default:
   	    if (isElement(node)) {
   		return(copyElement(node, type, handler));
  @@ -2641,7 +2764,7 @@
   	private int       _currentNode          = 0;
   
   	// Temporary structures for attribute nodes
  -	private int       _currentAttributeNode = 0;
  +	private int       _currentAttributeNode = 1;
   	private short[]   _type2        = new short[ATTR_ARRAY_SIZE];
   	private short[]   _prefix2      = new short[ATTR_ARRAY_SIZE];
   	private int[]     _parent2      = new int[ATTR_ARRAY_SIZE];
  @@ -2653,6 +2776,9 @@
   	private Hashtable _nsPrefixes   = new Hashtable();
   	private int       _uriCount     = 0;
   	private int       _prefixCount  = 0;
  +
  +	private int       _nextNamespace = DOM.NULL;
  +	private int       _lastNamespace = DOM.NULL;
   	
   	// Stack used to keep track of what whitespace text nodes are protected
   	// by xml:space="preserve" attributes and which nodes that are not.
  @@ -2672,7 +2798,7 @@
   	}
   
   	/**
  -	 * Returns the namespace URI that a prefix currentl maps to
  +	 * Returns the namespace URI that a prefix currently maps to
   	 */
   	private String getNamespaceURI(String prefix) {
   	    // Get the stack associated with this namespace prefix
  @@ -2888,6 +3014,16 @@
   	    _length[attributeNode] = length;
   	}
   
  +	private int makeNamespaceNode(String prefix, String uri)
  +	    throws SAXException {
  +
  +    	    final int node = nextAttributeNode();
  +	    _type2[node] = NAMESPACE;
  +	    characters(uri);
  +	    storeAttrValRef(node);
  +	    return node;	    
  +	}
  +
   	/**
   	 * Creates an attribute node
   	 */
  @@ -2929,8 +3065,6 @@
   		_type2[node] = (short)obj.intValue();
   	    }
   
  -	    _parent2[node] = parent;
  -
   	    final int col = qname.lastIndexOf(':');
   	    if (col > 0) {
   		_prefix2[node] = registerPrefix(qname.substring(0, col));
  @@ -2959,13 +3093,13 @@
   	/**
   	 * SAX2: Receive notification of the beginning of a document.
   	 */
  -	public void startDocument() {
  +	public void startDocument() throws SAXException {
   	    _shortTexts     = new Hashtable();
   	    _names          = new Hashtable();
   	    _sp             = 0;
   	    _parentStack[0] = ROOTNODE;	// root
   	    _currentNode    = ROOTNODE + 1;
  -	    _currentAttributeNode = 0;
  +	    _currentAttributeNode = 1;
   	    startPrefixMapping(EMPTYSTRING, EMPTYSTRING);
   	}
   
  @@ -3009,8 +3143,10 @@
   		if ((!qname.startsWith(XML_STRING)) && (col > -1)) {
   		    final String uri = _namesArray[i].substring(0, col);
   		    final Integer idx = (Integer)_nsIndex.get(uri);
  -		    _namespace[i] = idx.shortValue();
  -		    _uriArray[idx.intValue()] = uri;
  +		    if (idx != null) {
  +			_namespace[i] = idx.shortValue();
  +			_uriArray[idx.intValue()] = uri;
  +		    }
   		}
   	    }
   
  @@ -3038,23 +3174,36 @@
   	    linkChildren(node);
   	    _parentStack[++_sp] = node;
   
  +	    _lengthOrAttr[node] = DOM.NULL;
  +
   	    final int count = attributes.getLength();
  +
  +	    // Append any namespace nodes
  +	    if (_nextNamespace != DOM.NULL) {
  +		_lengthOrAttr[node] = _nextNamespace;
  +		while (_nextNamespace != DOM.NULL) {
  +		    _parent2[_nextNamespace] = node;
  +		    int tail = _nextNamespace;
  +		    _nextNamespace = _nextSibling2[_nextNamespace];
  +		    // Chain last namespace node to following attribute node(s)
  +		    if ((_nextNamespace == DOM.NULL) && (count > 0))
  +			_nextSibling2[tail] = _currentAttributeNode;
  +		}
  +	    }
   
  -	    // Process attribute list and create attr nodes
  +	    // Append any attribute nodes
   	    if (count > 0) {
  -		int attr = _currentAttributeNode + 1;
  -		_lengthOrAttr[node] = attr;
  +		int attr = _currentAttributeNode;
  +		if (_lengthOrAttr[node] == DOM.NULL)
  +		    _lengthOrAttr[node] = attr;
   		for (int i = 0; i<count; i++) {
   		    attr = makeAttributeNode(node, attributes, i);
  +		    _parent2[attr] = node;;
   		    _nextSibling2[attr] = attr + 1;
   		}
   		_nextSibling2[attr] = DOM.NULL;
   	    }
  -	    // The element has no attributes
  -	    else {
  -		_lengthOrAttr[node] = DOM.NULL;
  -	    }	    
  -	    
  +
   	    final int col = qname.lastIndexOf(':');
   
   	    // Assign an internal type to this element (may exist)
  @@ -3129,7 +3278,9 @@
   	/**
   	 * SAX2: Begin the scope of a prefix-URI Namespace mapping.
   	 */
  -	public void startPrefixMapping(String prefix, String uri) {
  +	public void startPrefixMapping(String prefix, String uri) 
  +	    throws SAXException {
  +
   	    // Get the stack associated with this namespace prefix
   	    Stack stack = (Stack)_nsPrefixes.get(prefix);
   	    if (stack == null) {
  @@ -3139,10 +3290,22 @@
   	    }
   
   	    // Check if the URI already exists before pushing on stack
  -	    if (_nsIndex.get(uri) == null) {
  -		_nsIndex.put(uri, new Integer(_uriCount++));
  +	    Integer idx;
  +	    if ((idx = (Integer)_nsIndex.get(uri)) == null) {
  +		_nsIndex.put(uri, idx = new Integer(_uriCount++));
   	    }
   	    stack.push(uri);
  +
  +	    if (!prefix.equals(EMPTYSTRING) || !uri.equals(EMPTYSTRING)) {
  +		makeTextNode(false);
  +		int attr = makeNamespaceNode(prefix, uri);
  +		if (_nextNamespace == DOM.NULL)
  +		    _nextNamespace = attr;
  +		else
  +		    _nextSibling2[attr-1] = attr;
  +		_nextSibling2[attr] = DOM.NULL;
  +		_prefix2[attr] = idx.shortValue();
  +	    }
   	}
   
   	/**
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: xalan-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-cvs-help@xml.apache.org