You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by sa...@apache.org on 2002/06/03 19:14:22 UTC

cvs commit: xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output OutputBase.java SAXHTMLOutput.java SAXOutput.java SAXXMLOutput.java StreamOutput.java StreamXMLOutput.java

santiagopg    2002/06/03 10:14:22

  Modified:    java/src/org/apache/xalan/xsltc/runtime/output
                        OutputBase.java SAXHTMLOutput.java SAXOutput.java
                        SAXXMLOutput.java StreamOutput.java
                        StreamXMLOutput.java
  Log:
  Moved common methods to base classes.
  
  Revision  Changes    Path
  1.3       +196 -24   xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/OutputBase.java
  
  Index: OutputBase.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/OutputBase.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- OutputBase.java	21 May 2002 15:13:25 -0000	1.2
  +++ OutputBase.java	3 Jun 2002 17:14:22 -0000	1.3
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: OutputBase.java,v 1.2 2002/05/21 15:13:25 santiagopg Exp $
  + * @(#)$Id: OutputBase.java,v 1.3 2002/06/03 17:14:22 santiagopg Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -63,35 +63,207 @@
   
   package org.apache.xalan.xsltc.runtime.output;
   
  +import java.util.Stack;
  +
  +import org.apache.xalan.xsltc.*;
  +import org.apache.xalan.xsltc.runtime.*;
  +import org.apache.xalan.xsltc.runtime.Hashtable;
  +
   import org.apache.xalan.xsltc.TransletException;
   import org.apache.xalan.xsltc.TransletOutputHandler;
   import org.apache.xalan.xsltc.runtime.Hashtable;
   
  -public abstract class OutputBase implements TransletOutputHandler {
  +public abstract class OutputBase implements TransletOutputHandler, Constants {
  +
  +    /**
  +     * Document system identifier
  +     */
  +    protected String  _doctypeSystem = null;
  +
  +    /**
  +     * Document public identifier
  +     */
  +    protected String  _doctypePublic = null;
  +
  +    /**
  +     * Holds the current tree depth.
  +     */
  +    protected int _depth = 0;
  +
  +    /**
  +     * Each entry (prefix) in this hashtable points to a Stack of URIs
  +     */
  +    protected Hashtable _namespaces;
  +
  +    /** 
  +     * The top of this stack contains an id of the element that last declared
  +     * a namespace. Used to ensure prefix/uri map scopes are closed correctly
  +     */
  +    protected Stack _nodeStack;
  +
  +    /** 
  +     * The top of this stack is the prefix that was last mapped to an URI
  +     */
  +    protected Stack _prefixStack;
  +
  +    /**
  +     * Contains all elements that should be output as CDATA sections.
  +     */
  +    protected Hashtable _cdata = null;
  +
  +    /**
  +     * The top of this stack contains the element id of the last element whose
  +     * contents should be output as CDATA sections.
  +     */
  +    protected Stack _cdataStack;
  +
  +    /**
  +     * Set to true when a CDATA section is being output.
  +     */
  +    protected boolean _cdataTagOpen = false;
  +
  +    /**
  +     * Set to true when a start tag is being output.
  +     */
  +    protected boolean _startTagOpen  = false;
  + 
  +    /**
  +     * Initialize global variables
  +     */
  +    protected void initCDATA() {
  +	// CDATA stack
  +	_cdataStack = new Stack();
  +	_cdataStack.push(new Integer(-1)); 	// push dummy value
  +    }
  +
  +    protected void initNamespaces() {
  +	// Namespaces
  +	_namespaces = new Hashtable();
  +	_nodeStack = new Stack();
  +	_prefixStack = new Stack();
  +
  +	// Define the default namespace (initially maps to "" uri)
  +	Stack stack;
  +	_namespaces.put(EMPTYSTRING, stack = new Stack());
  +	stack.push(EMPTYSTRING);
  +	_prefixStack.push(EMPTYSTRING);
  +
  +	_namespaces.put(XML_PREFIX, stack = new Stack());
  +	stack.push("http://www.w3.org/XML/1998/namespace");
  +	_prefixStack.push(XML_PREFIX);
  +
  +	_nodeStack.push(new Integer(-1));
  +	_depth = 0;
  +    }
  +
  +    /**
  +     * Set the output document system/public identifiers
  +     */
  +    public void setDoctype(String system, String pub) {
  +        _doctypeSystem = system;
  +        _doctypePublic = pub;
  +
  +    }
  +
  +    public void setCdataElements(Hashtable elements) { 
  +	_cdata = elements;
  +    }
  +
  + 
  +   /**
  +     * TODO: This method is a HACK! Since XSLTC does not have access to the
  +     * XML file, it sometimes generates a NS prefix of the form "ns?" for
  +     * an attribute. If at runtime, when the qname of the attribute is
  +     * known, another prefix is specified for the attribute, then we can get
  +     * a qname of the form "ns?:otherprefix:name". This function patches the
  +     * qname by simply ignoring "otherprefix".
  +     */ 
  +    protected static String patchName(String qname) throws TransletException {
  +        final int lastColon = qname.lastIndexOf(':');
  +        if (lastColon > 0) {
  +            final int firstColon = qname.indexOf(':');
  +            if (firstColon != lastColon) {
  +                return qname.substring(0, firstColon) + 
  +		    qname.substring(lastColon);
  +            }
  +        }
  +        return qname;
  +    }
  +
  +    /**
  +     * Declare a prefix to point to a namespace URI
  +     */
  +    protected boolean pushNamespace(String prefix, String uri) {
  +	// Prefixes "xml" and "xmlns" cannot be redefined
  +	if (prefix.startsWith(XML_PREFIX)) {
  +	    return false;
  +	}
  +	
  +	Stack stack;
  +	// Get the stack that contains URIs for the specified prefix
  +	if ((stack = (Stack)_namespaces.get(prefix)) == null) {
  +	    _namespaces.put(prefix, stack = new Stack());
  +	}
   
  -    public void startDocument() throws TransletException{}
  -    public void endDocument() throws TransletException{}
  -    public void startElement(String elementName) throws TransletException{}
  -    public void endElement(String elementName) throws TransletException{}
  -    public void characters(String characters) throws TransletException{}
  +	if (!stack.empty() && uri.equals(stack.peek())) {
  +	    return false;
  +	}
  +
  +	stack.push(uri);
  +	_prefixStack.push(prefix);
  +	_nodeStack.push(new Integer(_depth));
  +	return true;
  +    }
  +
  +    /**
  +     * Undeclare the namespace that is currently pointed to by a given prefix
  +     */
  +    protected void popNamespace(String prefix) {
  +	// Prefixes "xml" and "xmlns" cannot be redefined
  +	if (prefix.startsWith(XML_PREFIX)) {
  +	    return;
  +	}
  +
  +	Stack stack;
  +	if ((stack = (Stack)_namespaces.get(prefix)) != null) {
  +	    stack.pop();
  +	}
  +    }
  +
  +    /**
  +     * Pop all namespace definitions that were delcared by the current element
  +     */
  +    protected void popNamespaces() {
  +	while (true) {
  +	    if (_nodeStack.isEmpty()) return;
  +	    Integer i = (Integer)(_nodeStack.peek());
  +	    if (i.intValue() != _depth) return;
  +	    _nodeStack.pop();
  +	    popNamespace((String)_prefixStack.pop());
  +	}
  +    }
  +
  +    // -- Temporary
  +    public void startDocument() throws TransletException { }
  +    public void endDocument() throws TransletException { }
  +    public void startElement(String elementName) throws TransletException { }
  +    public void endElement(String elementName) throws TransletException { }
  +    public void characters(String characters) throws TransletException { }
       public void characters(char[] characters, int offset, int length)
  -	throws TransletException{}
  +	throws TransletException { }
       public void attribute(String attributeName, String attributeValue)
  -	throws TransletException{}
  -    public void namespace(String prefix, String uri) throws TransletException{}
  -    public void comment(String comment) throws TransletException{}
  +	throws TransletException { }
  +    public void namespace(String prefix, String uri) throws TransletException { }
  +    public void comment(String comment) throws TransletException { }
       public void processingInstruction(String target, String data)
  -	throws TransletException{}
  -    public void setType(int type){}
  -    public void setIndent(boolean indent){}
  -    public void omitHeader(boolean value){}
  -    public boolean setEscaping(boolean escape) throws TransletException{
  -	return false;
  -    }
  -    public void setCdataElements(Hashtable elements){}
  -    public void setDoctype(String system, String pub) {}
  -    public void setMediaType(String mediaType) {}
  -    public void setStandalone(String standalone) {}
  -    public void setVersion(String version) {}
  -    public void close() {}
  +	throws TransletException { }
  +    public void setType(int type) { }
  +    public void setIndent(boolean indent) { }
  +    public void omitHeader(boolean value) { }
  +    public boolean setEscaping(boolean escape) throws TransletException { return true; }
  +    public void setMediaType(String mediaType) { }
  +    public void setStandalone(String standalone) { }
  +    public void setVersion(String version) { }
  +    public void close() { }
  +
   }
  
  
  
  1.5       +17 -43    xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/SAXHTMLOutput.java
  
  Index: SAXHTMLOutput.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/SAXHTMLOutput.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- SAXHTMLOutput.java	21 May 2002 18:55:10 -0000	1.4
  +++ SAXHTMLOutput.java	3 Jun 2002 17:14:22 -0000	1.5
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: SAXHTMLOutput.java,v 1.4 2002/05/21 18:55:10 tmiller Exp $
  + * @(#)$Id: SAXHTMLOutput.java,v 1.5 2002/06/03 17:14:22 santiagopg Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -63,48 +63,43 @@
   
   package org.apache.xalan.xsltc.runtime.output;
   
  +import java.util.Stack;
  +import java.io.IOException;
  +
   import org.xml.sax.SAXException;
   import org.xml.sax.ContentHandler;
   import org.xml.sax.ext.LexicalHandler;
   import org.apache.xalan.xsltc.TransletException;
   import org.apache.xalan.xsltc.runtime.BasisLibrary;
   import org.apache.xalan.xsltc.runtime.AttributeList;
  -import java.io.IOException;
  -import java.util.Stack;
   
  -public class SAXHTMLOutput extends SAXOutput  { 
  -    private boolean   _headTagOpen = false;
  -    private String _mediaType = "text/html";
  +public class SAXHTMLOutput extends SAXOutput { 
  +    private boolean _headTagOpen = false;
  +    private String  _mediaType   = "text/html";
   
  -    public SAXHTMLOutput(ContentHandler handler, String encoding) throws
  -	IOException 
  +    public SAXHTMLOutput(ContentHandler handler, String encoding) 
  +	throws IOException 
       {
   	super(handler, encoding);
  -	init();
       }
   
       public SAXHTMLOutput(ContentHandler handler, LexicalHandler lex, 
   	String encoding) throws IOException
       {
   	super(handler, lex, encoding);
  -	init();
       }
      
  -    private void init() throws IOException {
  -	_qnameStack = new Stack();
  -    }
  -
  -
       public void attribute(String name, final String value) 
   	throws TransletException
       {
  -	final String patchedName = patchQName(name);
  +	final String patchedName = patchName(name);
   	final String localName = getLocalName(patchedName);
   	final int index = _attributes.getIndex(name); 
   
   	if (!_startTagOpen) {
               BasisLibrary.runTimeError(BasisLibrary.STRAY_ATTRIBUTE_ERR,name);
           }
  +
           if (index >= 0) {
               _attributes.setAttribute(index, EMPTYSTRING, EMPTYSTRING,
                       name, "CDATA", value);
  @@ -187,7 +182,6 @@
               _elementName = elementName;
               _attributes.clear();
               _startTagOpen = true;
  -            _qnameStack.push(elementName);
   
               // Insert <META> tag directly after <HEAD> element in HTML doc
               if (elementName.toLowerCase().equals("head")) {
  @@ -198,19 +192,18 @@
           }
       }
   
  -
  -
  -   
       /**
        * End an element or CDATA section in the output document
        */
       public void endElement(String elementName) throws TransletException {
           try {
               // Close any open element
  -            if (_startTagOpen) closeStartTag();
  -            _saxHandler.endElement(EMPTYSTRING, EMPTYSTRING,
  -                (String)(_qnameStack.pop()));
  -        } catch (SAXException e) {
  +            if (_startTagOpen) {
  +		closeStartTag();
  +	    }
  +            _saxHandler.endElement(EMPTYSTRING, EMPTYSTRING, elementName);
  +        } 
  +	catch (SAXException e) {
               throw new TransletException(e);
           }
   
  @@ -241,23 +234,4 @@
               throw new TransletException(e);
           }
       }
  -
  -
  -    private void initNamespaces() { 
  -	//empty 
  -    }
  -
  -    private String lookupNamespace(String prefix) { 
  -	return null;	// no-op	
  -    }
  -
  -    private void popNamespace(String prefix) throws SAXException {
  -	//empty
  -    }
  -
  -    private String getNamespaceURI(String qname, boolean isElement)
  -        throws TransletException
  -    {
  -	return null;	// no-op	
  -    } 
   }
  
  
  
  1.6       +9 -45     xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/SAXOutput.java
  
  Index: SAXOutput.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/SAXOutput.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- SAXOutput.java	21 May 2002 18:55:10 -0000	1.5
  +++ SAXOutput.java	3 Jun 2002 17:14:22 -0000	1.6
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: SAXOutput.java,v 1.5 2002/05/21 18:55:10 tmiller Exp $
  + * @(#)$Id: SAXOutput.java,v 1.6 2002/06/03 17:14:22 santiagopg Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -72,23 +72,15 @@
   import org.apache.xalan.xsltc.runtime.Constants;
   
   public class SAXOutput extends OutputBase implements Constants { 
  +
       protected ContentHandler _saxHandler;
       protected LexicalHandler _lexHandler;
  -    protected boolean        _startTagOpen = false;
       protected AttributesImpl _attributes = new AttributesImpl();
  +    
       protected String	     _elementName = null;
   
  -    // parameters set by <xsl:output> element, or by set/getOutputProperty()
       protected String         _encoding = null; 
  -    protected String         _doctypeSystem = null;
  -    protected String         _doctypePublic = null;
    
  -    // The top of this stack contains the QName of the currently open element
  -    protected Stack          _qnameStack;
  -
  -    // Holds the current tree depth (see startElement() and endElement()).
  -    protected int            _depth = 0;
  -
   
       public SAXOutput(ContentHandler handler, String encoding) {
   	_saxHandler = handler;
  @@ -101,11 +93,11 @@
   	_encoding = encoding;
       }
   
  -
       public void startDocument() throws TransletException {
   	try {
   	    _saxHandler.startDocument();
  -	} catch (SAXException e) {
  +	} 
  +	catch (SAXException e) {
   	    throw new TransletException(e);
   	}
       }
  @@ -113,7 +105,8 @@
       public void endDocument() throws TransletException {
   	try {
   	    _saxHandler.endDocument();
  -	} catch (SAXException e) {
  +	} 
  +	catch (SAXException e) {
               throw new TransletException(e);
           }
       }
  @@ -125,39 +118,10 @@
   	try {
   	    _saxHandler.characters(characters.toCharArray(), 0, 
   		characters.length());	
  -	} catch (SAXException e) {
  +	} 
  +	catch (SAXException e) {
               throw new TransletException(e);
           }
  -    }
  -
  -    /**
  -     * Set the output document system/public identifiers
  -     */
  -    public void setDoctype(String system, String pub) {
  -        _doctypeSystem = system;
  -        _doctypePublic = pub;
  -    }
  -
  -
  -
  -   /**
  -     * TODO: This method is a HACK! Since XSLTC does not have access to the
  -     * XML file, it sometimes generates a NS prefix of the form "ns?" for
  -     * an attribute. If at runtime, when the qname of the attribute is
  -     * known, another prefix is specified for the attribute, then we can get
  -     * a qname of the form "ns?:otherprefix:name". This function patches the
  -     * qname by simply ignoring "otherprefix".
  -     */ 
  -    protected static String patchQName(String qname) throws TransletException {
  -        final int lastColon = qname.lastIndexOf(':');
  -        if (lastColon > 0) {
  -            final int firstColon = qname.indexOf(':');
  -            if (firstColon != lastColon) {
  -                return qname.substring(0, firstColon) + 
  -		    qname.substring(lastColon);
  -            }
  -        }
  -        return qname;
       }
   
       /**
  
  
  
  1.6       +133 -254  xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/SAXXMLOutput.java
  
  Index: SAXXMLOutput.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/SAXXMLOutput.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- SAXXMLOutput.java	29 May 2002 13:04:38 -0000	1.5
  +++ SAXXMLOutput.java	3 Jun 2002 17:14:22 -0000	1.6
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: SAXXMLOutput.java,v 1.5 2002/05/29 13:04:38 tmiller Exp $
  + * @(#)$Id: SAXXMLOutput.java,v 1.6 2002/06/03 17:14:22 santiagopg Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -72,121 +72,81 @@
   import org.xml.sax.SAXException;
   import org.apache.xalan.xsltc.runtime.BasisLibrary;
   
  -public class SAXXMLOutput extends SAXOutput  {
  -
  -    // Each entry (prefix) in this hashtable points to a Stack of URIs
  -    private Hashtable _namespaces;
  -    // The top of this stack contains an id of the element that last declared
  -    // a namespace. Used to ensure prefix/uri map scopes are closed correctly
  -    private Stack     _nodeStack;
  -    // The top of this stack is the prefix that was last mapped to an URI
  -    private Stack     _prefixStack;
  -
  -
  -    // Contains all elements that should be output as CDATA sections
  -    private Hashtable _cdata = null;
  -
  -    private boolean   _cdataTagOpen = false;
  -    // The top of this stack contains the element id of the last element whose
  -    // contents should be output as CDATA sections.
  -    private Stack     _cdataStack;
  -
  -    // The top of this stack contains the QName of the currently open element
  -    private Stack     _qnameStack;
  +public class SAXXMLOutput extends SAXOutput {
   
       private static final char[] BEGCDATA = "<![CDATA[".toCharArray();
       private static final char[] ENDCDATA = "]]>".toCharArray();
       private static final char[] CNTCDATA = "]]]]><![CDATA[>".toCharArray();
  -    
   
       public SAXXMLOutput(ContentHandler handler, String encoding) 
   	throws IOException 
       {
       	super(handler, encoding);
  -	init();
  +	initCDATA();
  +	initNamespaces();
       }
   
       public SAXXMLOutput(ContentHandler handler, LexicalHandler lex, 
           String encoding) throws IOException
       {
           super(handler, lex, encoding);
  -	init();
  -    }
  -
  -    private void init() throws IOException {
  -	_cdataTagOpen = false;
  -	_cdataStack = new Stack();
  -	_cdataStack.push(new Integer(-1)); // push dummy value
  -	_qnameStack = new Stack();
  -
  -	// Reset our internal namespace handling
  -        initNamespaces();
  +	initCDATA();
  +	initNamespaces();
       }
   
       public void endDocument() throws TransletException {
   	try {
   	    // Close any open start tag
  -            if (_startTagOpen) closeStartTag();
  -            if (_cdataTagOpen) closeCDATA();
  +            if (_startTagOpen) {
  +		closeStartTag();
  +	    }
  +            else if (_cdataTagOpen) {
  +		closeCDATA();
  +	    }
   
               // Close output document
               _saxHandler.endDocument();
  -        } catch (SAXException e) {
  +        } 
  +	catch (SAXException e) {
               throw new TransletException(e);
           }
       }
   
       /**
  -     * This method is called when all the data needed for a call to the
  -     * SAX handler's startElement() method has been gathered.
  -     */
  -    public void closeStartTag() throws TransletException {
  -        try {
  -            _startTagOpen = false;
  -
  -            // Now is time to send the startElement event
  -            _saxHandler.startElement(getNamespaceURI(_elementName, true),
  -                getLocalName(_elementName), _elementName, _attributes);
  -        }
  -        catch (SAXException e) {
  -            throw new TransletException(e);
  -        }
  -    }
  -
  -    /**
  -     * Returns the URI of an element or attribute. Note that default namespaces
  -     * do not apply directly to attributes.
  +     * Start an element in the output document. This might be an XML
  +     * element (<elem>data</elem> type) or a CDATA section.
        */
  -    private String getNamespaceURI(String qname, boolean isElement)
  -        throws TransletException
  -    {
  -        String uri = EMPTYSTRING;
  -        int col = qname.lastIndexOf(':');
  -        final String prefix = (col > 0) ? qname.substring(0, col) : EMPTYSTRING;
  +    public void startElement(String elementName) throws TransletException {
  +	try {
  +            // Close any open start tag
  +            if (_startTagOpen) {
  +		closeStartTag();
  +	    }
  +            else if (_cdataTagOpen) {
  +		closeCDATA();
  +	    }
   
  -        if (prefix != EMPTYSTRING || isElement) {
  -            uri = lookupNamespace(prefix);
  -            if (uri == null && !prefix.equals(XMLNS_PREFIX)) {
  -                BasisLibrary.runTimeError(BasisLibrary.NAMESPACE_PREFIX_ERR,
  -                                          qname.substring(0, col));
  +            // Handle document type declaration (for first element only)
  +            if (_lexHandler != null) {
  +                if (_doctypeSystem != null) {
  +                    _lexHandler.startDTD(elementName, _doctypePublic,
  +			_doctypeSystem);
  +		}
  +                _lexHandler = null;
               }
  -        }
  -        return uri;
  -    }
   
  -    /**
  -     * Use a namespace prefix to lookup a namespace URI
  -     */
  -    private String lookupNamespace(String prefix) {
  -        final Stack stack = (Stack)_namespaces.get(prefix);
  -        return stack != null && !stack.isEmpty() ? (String)stack.peek() : null;
  -    }
  +            _depth++;
  +            _elementName = elementName;
  +            _attributes.clear();
  +            _startTagOpen = true;
   
  -    
  -    private void closeCDATA() throws SAXException {
  -        // Output closing bracket - "]]>"
  -        _saxHandler.characters(ENDCDATA, 0, ENDCDATA.length);
  -        _cdataTagOpen = false;
  +            if (_cdata != null && _cdata.get(elementName) != null) {
  +                _cdataStack.push(new Integer(_depth));
  +	    }
  +	}
  +        catch (SAXException e) {
  +            throw new TransletException(e);
  +        }
       }
   
       /**
  @@ -196,31 +156,26 @@
       public void attribute(String name, final String value)
           throws TransletException 
       {
  -	final String patchedName = patchQName(name);
  +	final String patchedName = patchName(name);
           final String localName = getLocalName(patchedName);
           final String uri = getNamespaceURI(patchedName, false);
  +
           final int index = (localName == null) ?
                   _attributes.getIndex(name) :    /* don't use patchedName */
                   _attributes.getIndex(uri, localName);
  +
           if (!_startTagOpen) {
               BasisLibrary.runTimeError(BasisLibrary.STRAY_ATTRIBUTE_ERR,
                   patchedName);
           }
   
  -	// Output as namespace declaration
  -        if (name.startsWith(XMLNS_PREFIX)) {
  -            namespace(name.length() > 6 ? name.substring(6) : EMPTYSTRING,
  -                value);
  -        }
  -        else {
  -            if (index >= 0) {       // Duplicate attribute?
  -                _attributes.setAttribute(index, uri, localName,
  -                    patchedName, "CDATA", value);
  -            }
  -            else {
  -                _attributes.addAttribute(uri, localName, patchedName,
  -                    "CDATA", value);
  -            }
  +	if (index >= 0) {       // Duplicate attribute?
  +	    _attributes.setAttribute(index, uri, localName,
  +		patchedName, "CDATA", value);
  +	}
  +	else {
  +	    _attributes.addAttribute(uri, localName, patchedName,
  +		"CDATA", value);
           }
       }
   
  @@ -229,13 +184,10 @@
       {
   	try {
               // Close any open start tag
  -            if (_startTagOpen) closeStartTag();
  +            if (_startTagOpen) {
  +		closeStartTag();
  +	    }
   
  -            // Take special precautions if within a CDATA section. If we
  -            // encounter the sequence ']]>' within the CDATA, we need to
  -            // break the section in two and leave the ']]' at the end of
  -            // the first CDATA and '>' at the beginning of the next. Other
  -            // special characters/sequences are _NOT_ escaped within CDATA.
               Integer I = (Integer)_cdataStack.peek();
               if ((I.intValue() == _depth) && (!_cdataTagOpen)) {
                   startCDATA(ch, off, len);
  @@ -252,12 +204,15 @@
       public void endElement(String elementName) throws TransletException {
           try {
               // Close any open element
  -            if (_startTagOpen) closeStartTag();
  -            if (_cdataTagOpen) closeCDATA();
  +            if (_startTagOpen) {
  +		closeStartTag();
  +	    }
  +            else if (_cdataTagOpen) {
  +		closeCDATA();
  +	    }
   
  -            final String qname = (String) _qnameStack.pop();
  -            _saxHandler.endElement(getNamespaceURI(qname, true),
  -                getLocalName(qname), qname);
  +            _saxHandler.endElement(getNamespaceURI(elementName, true),
  +                getLocalName(elementName), elementName);
   
               popNamespaces();
               if (((Integer)_cdataStack.peek()).intValue() == _depth){
  @@ -265,140 +220,103 @@
   	    }
               _depth--;
   
  -    	} catch (SAXException e) {
  +    	} 
  +	catch (SAXException e) {
               throw new TransletException(e);
       	}
       }
   
       /**
  -     * The <xsl:output method="xml"/> instruction can specify that certain
  -     * XML elements should be output as CDATA sections. This methods allows
  -     * the translet to insert these elements into a hashtable of strings.
  -     * Every output element is looked up in this hashtable before it is
  -     * output.
  +     * Send a namespace declaration in the output document. The namespace
  +     * declaration will not be include if the namespace is already in scope
  +     * with the same prefix.
        */
  -    public void setCdataElements(Hashtable elements) {
  -        _cdata = elements;
  +    public void namespace(final String prefix, final String uri)
  +        throws TransletException 
  +    {
  +	if (_startTagOpen) {
  +	    pushNamespace(prefix, uri);
  +	}
  +	else {
  +	    if ((prefix == EMPTYSTRING) && (uri == EMPTYSTRING)) return;
  +	    BasisLibrary.runTimeError(BasisLibrary.STRAY_NAMESPACE_ERR,
  +				      prefix, uri);
  +	}
       }
   
  -
       /**
  -     * Start an element in the output document. This might be an XML
  -     * element (<elem>data</elem> type) or a CDATA section.
  +     * This method is called when all the data needed for a call to the
  +     * SAX handler's startElement() method has been gathered.
        */
  -    public void startElement(String elementName) throws TransletException {
  -	try {
  -            // Close any open start tag
  -            if (_startTagOpen) closeStartTag();
  -            if (_cdataTagOpen) closeCDATA();
  -
  -            // Handle document type declaration (for first element only)
  -            if (_lexHandler != null) {
  -                if (_doctypeSystem != null) {
  -                    _lexHandler.startDTD(elementName,
  -                         _doctypePublic,_doctypeSystem);
  -		}
  -                _lexHandler = null;
  -            }
  -
  -            _depth++;
  -            _elementName = elementName;
  -            _attributes.clear();
  -            _startTagOpen = true;
  -            _qnameStack.push(elementName);
  +    private void closeStartTag() throws TransletException {
  +        try {
  +            _startTagOpen = false;
   
  -            if ((_cdata != null) && (_cdata.get(elementName) != null)) {
  -                _cdataStack.push(new Integer(_depth));
  -	    }
  -	}
  +            // Now is time to send the startElement event
  +            _saxHandler.startElement(getNamespaceURI(_elementName, true),
  +                getLocalName(_elementName), _elementName, _attributes);
  +        }
           catch (SAXException e) {
               throw new TransletException(e);
           }
       }
   
       /**
  -     * Initialize namespace stacks
  -     */
  -    private void initNamespaces() {
  -        _namespaces = new Hashtable();
  -        _nodeStack = new Stack();
  -        _prefixStack = new Stack();
  -
  -        // Define the default namespace (initially maps to "" uri)
  -        Stack stack;
  -        _namespaces.put(EMPTYSTRING, stack = new Stack());
  -        stack.push(EMPTYSTRING);
  -        _prefixStack.push(EMPTYSTRING);
  -
  -        _namespaces.put(XML_PREFIX, stack = new Stack());
  -        stack.push("http://www.w3.org/XML/1998/namespace");
  -        _prefixStack.push(XML_PREFIX);
  -
  -        _nodeStack.push(new Integer(-1));
  -        _depth = 0;
  -    }
  -
  -    /**
  -     * Pop all namespace definitions that were delcared by the current element
  +     * Send a processing instruction to the output document
        */
  -    private void popNamespaces() throws TransletException {
  +    public void processingInstruction(String target, String data)
  +        throws TransletException {
           try {
  -            while (true) {
  -                if (_nodeStack.isEmpty()) return;
  -                Integer i = (Integer)(_nodeStack.peek());
  -                if (i.intValue() != _depth) return;
  -                _nodeStack.pop();
  -                popNamespace((String)_prefixStack.pop());
  -            }
  +            // Close any open element
  +            if (_startTagOpen) {
  +		closeStartTag();
  +	    }
  +            else if (_cdataTagOpen) {
  +		closeCDATA();
  +	    }
  +
  +            // Pass the processing instruction to the SAX handler
  +            _saxHandler.processingInstruction(target, data);
           }
           catch (SAXException e) {
               throw new TransletException(e);
           }
       }
   
  -
       /**
  -     * Undeclare the namespace that is currently pointed to by a given prefix
  +     * Returns the URI of an element or attribute. Note that default namespaces
  +     * do not apply directly to attributes.
        */
  -    private void popNamespace(String prefix) throws SAXException {
  -        // Prefixes "xml" and "xmlns" cannot be redefined
  -        if (prefix.equals(XML_PREFIX)) return;
  -
  -        Stack stack;
  -        if ((stack = (Stack)_namespaces.get(prefix)) != null) {
  -            stack.pop();
  -            _saxHandler.endPrefixMapping(prefix);
  +    private String getNamespaceURI(String qname, boolean isElement)
  +        throws TransletException
  +    {
  +        String uri = EMPTYSTRING;
  +        int col = qname.lastIndexOf(':');
  +        final String prefix = (col > 0) ? qname.substring(0, col) : EMPTYSTRING;
  +
  +        if (prefix != EMPTYSTRING || isElement) {
  +            uri = lookupNamespace(prefix);
  +            if (uri == null && !prefix.equals(XMLNS_PREFIX)) {
  +                BasisLibrary.runTimeError(BasisLibrary.NAMESPACE_PREFIX_ERR,
  +                                          qname.substring(0, col));
  +            }
           }
  +        return uri;
       }
   
  -
       /**
  -     * Declare a prefix to point to a namespace URI
  +     * Use a namespace prefix to lookup a namespace URI
        */
  -    private void pushNamespace(String prefix, String uri) throws SAXException {
  -        // Prefixes "xml" and "xmlns" cannot be redefined
  -        if (prefix.equals(XML_PREFIX)) return;
  -
  -        Stack stack;
  -        // Get the stack that contains URIs for the specified prefix
  -        if ((stack = (Stack)_namespaces.get(prefix)) == null) {
  -            stack = new Stack();
  -            _namespaces.put(prefix, stack);
  -        }
  -        // Quit now if the URI the prefix currently maps to is the same as this
  -        if (!stack.empty() && uri.equals(stack.peek())) return;
  -        // Put this URI on top of the stack for this prefix
  -        stack.push(uri);
  -
  -        _prefixStack.push(prefix);
  -        _nodeStack.push(new Integer(_depth));
  -
  -        // Inform the SAX handler
  -        _saxHandler.startPrefixMapping(prefix, uri);
  +    private String lookupNamespace(String prefix) {
  +        final Stack stack = (Stack)_namespaces.get(prefix);
  +        return stack != null && !stack.isEmpty() ? (String)stack.peek() : null;
       }
   
  -
  -
  +    private void closeCDATA() throws SAXException {
  +        // Output closing bracket - "]]>"
  +        _saxHandler.characters(ENDCDATA, 0, ENDCDATA.length);
  +        _cdataTagOpen = false;
  +    }
   
       /**
        * Utility method - pass a whole charactes as CDATA to SAX handler
  @@ -411,59 +329,20 @@
           _saxHandler.characters(BEGCDATA, 0, BEGCDATA.length);
   
           // Detect any occurence of "]]>" in the character array
  -        for (int i = offset; i < limit-2; i++) {
  -            if (ch[i] == ']' && ch[i+1] == ']' && ch[i+2] == '>') {
  +        for (int i = offset; i < limit - 2; i++) {
  +            if (ch[i] == ']' && ch[i + 1] == ']' && ch[i + 2] == '>') {
                   _saxHandler.characters(ch, offset, i - offset);
                   _saxHandler.characters(CNTCDATA, 0, CNTCDATA.length);
                   offset = i+3;
  -                i=i+2; // Skip next chars ']' and '>'.
  +                i += 2; 	// Skip next chars ']' and '>'
               }
           }
   
           // Output the remaining characters
  -        if (offset < limit) _saxHandler.characters(ch, offset, limit - offset);
  -
  +        if (offset < limit) {
  +	    _saxHandler.characters(ch, offset, limit - offset);
  +	}	    
           _cdataTagOpen = true;
  -    }
  -
  -    /**
  -     * Send a namespace declaration in the output document. The namespace
  -     * declaration will not be include if the namespace is already in scope
  -     * with the same prefix.
  -     */
  -    public void namespace(final String prefix, final String uri)
  -        throws TransletException {
  -        try {
  -            if (_startTagOpen)
  -                pushNamespace(prefix, uri);
  -            else {
  -                if ((prefix == EMPTYSTRING) && (uri == EMPTYSTRING)) return;
  -                BasisLibrary.runTimeError(BasisLibrary.STRAY_NAMESPACE_ERR,
  -                                          prefix, uri);
  -            }
  -        }
  -        catch (SAXException e) {
  -            throw new TransletException(e);
  -        }
  -    }
  -
  -
  -    /**
  -     * Send a processing instruction to the output document
  -     */
  -    public void processingInstruction(String target, String data)
  -        throws TransletException {
  -        try {
  -            // Close any open element
  -            if (_startTagOpen) closeStartTag();
  -            if (_cdataTagOpen) closeCDATA();
  -
  -            // Pass the processing instruction to the SAX handler
  -            _saxHandler.processingInstruction(target, data);
  -        }
  -        catch (SAXException e) {
  -            throw new TransletException(e);
  -        }
       }
   }
   
  
  
  
  1.9       +1 -6      xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/StreamOutput.java
  
  Index: StreamOutput.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/StreamOutput.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- StreamOutput.java	29 May 2002 20:25:15 -0000	1.8
  +++ StreamOutput.java	3 Jun 2002 17:14:22 -0000	1.9
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: StreamOutput.java,v 1.8 2002/05/29 20:25:15 santiagopg Exp $
  + * @(#)$Id: StreamOutput.java,v 1.9 2002/06/03 17:14:22 santiagopg Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -92,9 +92,7 @@
       protected Writer  _writer;
       protected StringBuffer _buffer;
   
  -    protected boolean _startTagOpen  = false;
       protected boolean _is8859Encoded = false;
  -
       protected boolean _indent     = false;
       protected boolean _omitHeader = false;
       protected String  _standalone = null;
  @@ -108,9 +106,6 @@
       protected boolean _escaping     = true;
       protected boolean _firstElement = true;
       protected String  _encoding     = "UTF-8";
  -
  -    protected String  _doctypeSystem = null;
  -    protected String  _doctypePublic = null;
   
       // protected HashSet _attributes = new HashSet();
       protected Vector _attributes = new Vector();
  
  
  
  1.9       +7 -143    xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/StreamXMLOutput.java
  
  Index: StreamXMLOutput.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/output/StreamXMLOutput.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- StreamXMLOutput.java	31 May 2002 18:22:14 -0000	1.8
  +++ StreamXMLOutput.java	3 Jun 2002 17:14:22 -0000	1.9
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: StreamXMLOutput.java,v 1.8 2002/05/31 18:22:14 santiagopg Exp $
  + * @(#)$Id: StreamXMLOutput.java,v 1.9 2002/06/03 17:14:22 santiagopg Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -76,7 +76,7 @@
   import org.apache.xalan.xsltc.runtime.*;
   import org.apache.xalan.xsltc.runtime.Hashtable;
   
  -public class StreamXMLOutput extends StreamOutput implements Constants {
  +public class StreamXMLOutput extends StreamOutput {
   
       private static final String BEGCDATA = "<![CDATA[";
       private static final String ENDCDATA = "]]>";
  @@ -86,77 +86,18 @@
       private static final String CDATA_ESC_START = "]]>&#";
       private static final String CDATA_ESC_END   = ";<![CDATA[";
   
  -    /**
  -     * Holds the current tree depth.
  -     */
  -    private int _depth = 0;
  -
  -    /**
  -     * Each entry (prefix) in this hashtable points to a Stack of URIs
  -     */
  -    private Hashtable _namespaces;
  -
  -    /** 
  -     * The top of this stack contains an id of the element that last declared
  -     * a namespace. Used to ensure prefix/uri map scopes are closed correctly
  -     */
  -    private Stack _nodeStack;
  -
  -    /** 
  -     * The top of this stack is the prefix that was last mapped to an URI
  -     */
  -    private Stack _prefixStack;
  -
  -    /**
  -     * Contains all elements that should be output as CDATA sections.
  -     */
  -    private Hashtable _cdata = null;
  -
  -    /**
  -     * The top of this stack contains the element id of the last element whose
  -     * contents should be output as CDATA sections.
  -     */
  -    private Stack _cdataStack;
  -
  -    private boolean _cdataTagOpen = false;
  -
       public StreamXMLOutput(Writer writer, String encoding) {
   	super(writer, encoding);
  -	init();
  +	initCDATA();
  +	initNamespaces();
       }
   
       public StreamXMLOutput(OutputStream out, String encoding) 
   	throws IOException
       {
   	super(out, encoding);
  -	init();
  -    }
  -
  -    /**
  -     * Initialize global variables
  -     */
  -    private void init() {
  -	// CDATA stack
  -	_cdataStack = new Stack();
  -	_cdataStack.push(new Integer(-1)); 	// push dummy value
  -
  -	// Namespaces
  -	_namespaces = new Hashtable();
  -	_nodeStack = new Stack();
  -	_prefixStack = new Stack();
  -
  -	// Define the default namespace (initially maps to "" uri)
  -	Stack stack;
  -	_namespaces.put(EMPTYSTRING, stack = new Stack());
  -	stack.push(EMPTYSTRING);
  -	_prefixStack.push(EMPTYSTRING);
  -
  -	_namespaces.put(XML_PREFIX, stack = new Stack());
  -	stack.push("http://www.w3.org/XML/1998/namespace");
  -	_prefixStack.push(XML_PREFIX);
  -
  -	_nodeStack.push(new Integer(-1));
  -	_depth = 0;
  +	initCDATA();
  +	initNamespaces();
       }
   
       public void startDocument() throws TransletException { 
  @@ -335,11 +276,7 @@
   	return temp; 
       }
   
  -    public void setCdataElements(Hashtable elements) { 
  -	_cdata = elements;
  -    }
  -
  -    public void namespace(final String prefix, final String uri)
  +   public void namespace(final String prefix, final String uri)
   	throws TransletException 
       {
   // System.out.println("namespace prefix = " + prefix + " uri = " + uri);
  @@ -360,59 +297,6 @@
       }
   
       /**
  -     * Declare a prefix to point to a namespace URI
  -     */
  -    private boolean pushNamespace(String prefix, String uri) {
  -	// Prefixes "xml" and "xmlns" cannot be redefined
  -	if (prefix.startsWith(XML_PREFIX)) {
  -	    return false;
  -	}
  -	
  -	Stack stack;
  -	// Get the stack that contains URIs for the specified prefix
  -	if ((stack = (Stack)_namespaces.get(prefix)) == null) {
  -	    _namespaces.put(prefix, stack = new Stack());
  -	}
  -
  -	if (!stack.empty() && uri.equals(stack.peek())) {
  -	    return false;
  -	}
  -
  -	stack.push(uri);
  -	_prefixStack.push(prefix);
  -	_nodeStack.push(new Integer(_depth));
  -	return true;
  -    }
  -
  -    /**
  -     * Undeclare the namespace that is currently pointed to by a given prefix
  -     */
  -    private void popNamespace(String prefix) {
  -	// Prefixes "xml" and "xmlns" cannot be redefined
  -	if (prefix.startsWith(XML_PREFIX)) {
  -	    return;
  -	}
  -
  -	Stack stack;
  -	if ((stack = (Stack)_namespaces.get(prefix)) != null) {
  -	    stack.pop();
  -	}
  -    }
  -
  -    /**
  -     * Pop all namespace definitions that were delcared by the current element
  -     */
  -    private void popNamespaces() {
  -	while (true) {
  -	    if (_nodeStack.isEmpty()) return;
  -	    Integer i = (Integer)(_nodeStack.peek());
  -	    if (i.intValue() != _depth) return;
  -	    _nodeStack.pop();
  -	    popNamespace((String)_prefixStack.pop());
  -	}
  -    }
  -
  -    /**
        * Utility method - pass a whole charactes as CDATA to SAX handler
        */
       private void startCDATA(char[] ch, int off, int len) {
  @@ -511,25 +395,5 @@
   	    result.append(ch, offset, limit - offset);
   	}
   	return result.toString();
  -    }
  -
  -    /**
  -     * TODO: This method is a HACK! Since XSLTC does not have access to the
  -     * XML file, it sometimes generates a NS prefix of the form "ns?" for
  -     * an attribute. If at runtime, when the qname of the attribute is
  -     * known, another prefix is specified for the attribute, then we can get 
  -     * a qname of the form "ns?:otherprefix:name". This function patches the 
  -     * name by simply ignoring "otherprefix".
  -     */
  -    private static String patchName(String qname) {
  -	final int lastColon = qname.lastIndexOf(':');
  -	if (lastColon > 0) {
  -	    final int firstColon = qname.indexOf(':');
  -	    if (firstColon != lastColon) {
  -		return qname.substring(0, firstColon) + 
  -		       qname.substring(lastColon);
  -	    }
  -	}
  -	return qname;
       }
   }
  
  
  

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