You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by mi...@apache.org on 2006/01/18 21:04:00 UTC

svn commit: r370242 - in /xalan/java/trunk/src/org/apache/xml/serializer: SerializerBase.java ToHTMLStream.java ToStream.java

Author: minchau
Date: Wed Jan 18 12:03:53 2006
New Revision: 370242

URL: http://svn.apache.org/viewcvs?rev=370242&view=rev
Log:
Commiting patch CDATApatc.txt in issue XALANJ-2258
Some re-work/cleanup of the CDATA code.

Modified:
    xalan/java/trunk/src/org/apache/xml/serializer/SerializerBase.java
    xalan/java/trunk/src/org/apache/xml/serializer/ToHTMLStream.java
    xalan/java/trunk/src/org/apache/xml/serializer/ToStream.java

Modified: xalan/java/trunk/src/org/apache/xml/serializer/SerializerBase.java
URL: http://svn.apache.org/viewcvs/xalan/java/trunk/src/org/apache/xml/serializer/SerializerBase.java?rev=370242&r1=370241&r2=370242&view=diff
==============================================================================
--- xalan/java/trunk/src/org/apache/xml/serializer/SerializerBase.java (original)
+++ xalan/java/trunk/src/org/apache/xml/serializer/SerializerBase.java Wed Jan 18 12:03:53 2006
@@ -198,13 +198,6 @@
      */
     private Transformer m_transformer;
 
-    /** 
-     * Pairs of local names and corresponding URIs of CDATA sections. This list
-     * comes from the cdata-section-elements attribute. Every second one is a
-     * local name, and every other second one is the URI for the local name. 
-     */
-    protected Vector m_cdataSectionElements = null;
-
     /**
      * Namespace support, that keeps track of currently defined 
      * prefix/uri mappings. As processed elements come and go, so do
@@ -801,59 +794,6 @@
     }
 
     /**
-     * Push a boolean state based on if the name of the current element
-     * is found in the list of qnames.  A state is only pushed if
-     * there were some cdata-section-names were specified.
-     * <p>
-     * Hidden parameters are the vector of qualified elements specified in
-     * cdata-section-names attribute, and the m_cdataSectionStates stack
-     * onto which whether the current element is in the list is pushed (true or
-     * false). Other hidden parameters are the current elements namespaceURI,
-     * localName and qName
-     */
-    protected boolean isCdataSection()
-    {
-
-        boolean b = false;
-
-        if (null != m_cdataSectionElements)
-        {
-            if (m_elemContext.m_elementLocalName == null)
-                m_elemContext.m_elementLocalName = 
-                    getLocalName(m_elemContext.m_elementName);
-            if (m_elemContext.m_elementURI == null)
-            {
-                String prefix = getPrefixPart(m_elemContext.m_elementName);
-                if (prefix != null)
-                    m_elemContext.m_elementURI = 
-                        m_prefixMap.lookupNamespace(prefix);
-
-            }
-
-            if ((null != m_elemContext.m_elementURI) 
-                && m_elemContext.m_elementURI.length() == 0)
-                m_elemContext.m_elementURI = null;
-
-            int nElems = m_cdataSectionElements.size();
-
-            // loop through 2 at a time, as these are pairs of URI and localName
-            for (int i = 0; i < nElems; i += 2)
-            {
-                String uri = (String) m_cdataSectionElements.elementAt(i);
-                String loc = (String) m_cdataSectionElements.elementAt(i + 1);
-                if (loc.equals(m_elemContext.m_elementLocalName)
-                    && subPartMatch(m_elemContext.m_elementURI, uri))
-                {
-                    b = true;
-
-                    break;
-                }
-            }
-        }
-        return b;
-    }
-
-    /**
      * Tell if two strings are equal, without worry if the first string is null.
      *
      * @param p String reference, which may be null.
@@ -1308,7 +1248,7 @@
     private void resetSerializerBase()
     {
     	this.m_attributes.clear();
-    	this.m_cdataSectionElements = null;
+        this.m_StringOfCDATASections = null;
         this.m_elemContext = new ElemContext();
     	this.m_doctypePublic = null;
     	this.m_doctypeSystem = null;
@@ -1394,5 +1334,159 @@
         // This method just provides a definition to satisfy the interface
         // A particular sub-class of SerializerBase provides the implementation (if desired)        
     }
+ 
+
+    /** 
+     * The CDATA section names stored in a whitespace separateed list with
+     * each element being a word of the form "{uri}localName" This list
+     * comes from the cdata-section-elements attribute.
+     * 
+     * This field replaces m_cdataSectionElements Vector.
+     */
+    protected String m_StringOfCDATASections = null; 
+    
+    boolean m_docIsEmpty = true;
+    void initCdataElems(String s)
+    {
+        if (s != null)
+        {            
+            int max = s.length();
+
+            // true if we are in the middle of a pair of curly braces that delimit a URI
+            boolean inCurly = false;
+
+            // true if we found a URI but haven't yet processed the local name 
+            boolean foundURI = false;
+
+            StringBuffer buf = new StringBuffer();
+            String uri = null;
+            String localName = null;
+
+            // parse through string, breaking on whitespaces.  I do this instead
+            // of a tokenizer so I can track whitespace inside of curly brackets,
+            // which theoretically shouldn't happen if they contain legal URLs.
+
+
+            for (int i = 0; i < max; i++)
+            {
+
+                char c = s.charAt(i);
+
+                if (Character.isWhitespace(c))
+                {
+                    if (!inCurly)
+                    {
+                        if (buf.length() > 0)
+                        {
+                            localName = buf.toString();
+                            if (!foundURI)
+                                uri = "";
+                            addCDATAElement(uri,localName);
+                            buf.setLength(0);
+                            foundURI = false;
+                        }
+                        continue;
+                    }
+                    else
+                        buf.append(c); // add whitespace to the URI
+                }
+                else if ('{' == c) // starting a URI
+                    inCurly = true;
+                else if ('}' == c)
+                {
+                    // we just ended a URI, add the URI to the vector
+                    foundURI = true;
+                    uri = buf.toString();
+                    buf.setLength(0);
+                    inCurly = false;
+                }
+                else
+                {
+                    // append non-whitespace, non-curly to current URI or localName being gathered.                    
+                    buf.append(c);
+                }
+
+            }
+
+            if (buf.length() > 0)
+            {
+                // We have one last localName to process.
+                localName = buf.toString();
+                if (!foundURI)
+                    uri = "";
+                addCDATAElement(uri,localName);
+            }
+        }
+    }
+    protected java.util.Hashtable m_CdataElems = null;
+    private void addCDATAElement(String uri, String localName) 
+    {
+        if (m_CdataElems == null) {
+            m_CdataElems = new java.util.Hashtable();
+        }
+        
+        java.util.Hashtable h = (java.util.Hashtable) m_CdataElems.get(localName);
+        if (h == null) {
+            h = new java.util.Hashtable();
+            m_CdataElems.put(localName,h);
+        }
+        h.put(uri,uri);
+        
+    }
+    
+    /**
+     * Push a boolean state based on if the name of the current element
+     * is found in the list of qnames.  A state is only pushed if
+     * there were some cdata-section-names were specified.
+     * <p>
+     */
+    protected boolean isCdataSection()
+    {
+
+        boolean b = false;
+
+        if (null != m_StringOfCDATASections)
+        {
+            String localName = m_elemContext.m_elementLocalName;
+            if (localName == null) 
+            {
+                localName =  getLocalName(m_elemContext.m_elementName); 
+                m_elemContext.m_elementLocalName = localName;                   
+            }
+            
+            String uri = m_elemContext.m_elementURI; 
+            if ( uri == null)
+            {
+                String prefix = getPrefixPart(m_elemContext.m_elementName);
+                if (prefix != null) {
+                    uri = m_prefixMap.lookupNamespace(prefix);
+                    if (uri != null) 
+                        m_elemContext.m_elementURI = uri;
+                    else
+                        uri = "";                        
+                }
+                else {
+                    // no prefix so lookup the URI of the default namespace
+                    uri = m_prefixMap.lookupNamespace("");
+                    if (uri == null)  // If no URI then the empty string also means no URI
+                        uri = "";
+                }
+            }
+            else {
+                if (m_elemContext.m_elementURI.length() == 0)
+                m_elemContext.m_elementURI = null;
+            }             
+
+            java.util.Hashtable h = (java.util.Hashtable) m_CdataElems.get(m_elemContext.m_elementLocalName);
+            if (h != null) 
+            {
+                Object obj = h.get(uri);
+                if (obj != null)
+                    b = true; 
+            }
 
+        }
+        return b;
+    }
 }
+

Modified: xalan/java/trunk/src/org/apache/xml/serializer/ToHTMLStream.java
URL: http://svn.apache.org/viewcvs/xalan/java/trunk/src/org/apache/xml/serializer/ToHTMLStream.java?rev=370242&r1=370241&r2=370242&view=diff
==============================================================================
--- xalan/java/trunk/src/org/apache/xml/serializer/ToHTMLStream.java (original)
+++ xalan/java/trunk/src/org/apache/xml/serializer/ToHTMLStream.java Wed Jan 18 12:03:53 2006
@@ -296,7 +296,7 @@
                     | ElemDesc.BLOCK
                     | ElemDesc.BLOCKFORM
                     | ElemDesc.BLOCKFORMFIELDSET));
-        m_elementFlags.put("HTML", new ElemDesc(0 | ElemDesc.BLOCK));
+        m_elementFlags.put("HTML", new ElemDesc(0 | ElemDesc.BLOCK | ElemDesc.HTMLELEM));
 
         // From "John Ky" <hand@syd.speednet.com.au
         // Transitional Document Type Definition ()
@@ -339,7 +339,6 @@
                     | ElemDesc.BLOCKFORM
                     | ElemDesc.BLOCKFORMFIELDSET));
 
-
         // NOW FOR ATTRIBUTE INFORMATION . . .
         ElemDesc elemDesc;
 
@@ -351,11 +350,13 @@
         
         // ----------------------------------------------
         elemDesc = (ElemDesc) m_elementFlags.get("AREA");
+
         elemDesc.setAttr("HREF", ElemDesc.ATTRURL);
         elemDesc.setAttr("NOHREF", ElemDesc.ATTREMPTY);
 
         // ----------------------------------------------
         elemDesc = (ElemDesc) m_elementFlags.get("BASE");
+
         elemDesc.setAttr("HREF", ElemDesc.ATTRURL);
 
         // ----------------------------------------------
@@ -364,12 +365,13 @@
 
         // ----------------------------------------------
         elemDesc = (ElemDesc) m_elementFlags.get("BLOCKQUOTE");
+
         elemDesc.setAttr("CITE", ElemDesc.ATTRURL);
 
         // ----------------------------------------------
         elemDesc = (ElemDesc) m_elementFlags.get("DEL");
         elemDesc.setAttr("CITE", ElemDesc.ATTRURL);
-     
+
         // ----------------------------------------------
         elemDesc = (ElemDesc) m_elementFlags.get("DIR");
         elemDesc.setAttr("COMPACT", ElemDesc.ATTREMPTY);
@@ -423,6 +425,7 @@
 
         // ----------------------------------------------
         elemDesc = (ElemDesc) m_elementFlags.get("INPUT");
+
         elemDesc.setAttr("SRC", ElemDesc.ATTRURL);
         elemDesc.setAttr("USEMAP", ElemDesc.ATTRURL);
         elemDesc.setAttr("CHECKED", ElemDesc.ATTREMPTY);
@@ -449,6 +452,7 @@
         
         // ----------------------------------------------
         elemDesc = (ElemDesc) m_elementFlags.get("OBJECT");
+
         elemDesc.setAttr("CLASSID", ElemDesc.ATTRURL);
         elemDesc.setAttr("CODEBASE", ElemDesc.ATTRURL);
         elemDesc.setAttr("DATA", ElemDesc.ATTRURL);
@@ -561,16 +565,32 @@
      */
     public void setOutputFormat(Properties format)
     {
- 
-        m_specialEscapeURLs =
-            OutputPropertyUtils.getBooleanProperty(
-                OutputPropertiesFactory.S_USE_URL_ESCAPING,
-                format);
-
-        m_omitMetaTag =
-            OutputPropertyUtils.getBooleanProperty(
-                OutputPropertiesFactory.S_OMIT_META_TAG,
-                format);
+        /*
+         * If "format" does not contain the property
+         * S_USE_URL_ESCAPING, then don't set this value at all,
+         * just leave as-is rather than explicitly setting it.
+         */
+        String value; 
+        value = format.getProperty(OutputPropertiesFactory.S_USE_URL_ESCAPING);
+        if (value != null) {
+            m_specialEscapeURLs =
+                OutputPropertyUtils.getBooleanProperty(
+                    OutputPropertiesFactory.S_USE_URL_ESCAPING,
+                    format);
+        }
+
+        /*
+         * If "format" does not contain the property
+         * S_OMIT_META_TAG, then don't set this value at all,
+         * just leave as-is rather than explicitly setting it.
+         */
+        value = format.getProperty(OutputPropertiesFactory.S_OMIT_META_TAG);
+        if (value != null) {
+           m_omitMetaTag =
+                OutputPropertyUtils.getBooleanProperty(
+                    OutputPropertiesFactory.S_OMIT_META_TAG,
+                    format);
+        }
 
         super.setOutputFormat(format);
     }
@@ -614,6 +634,7 @@
         return m_dummy;
     }
     
+    
     /**
      * A Trie that is just a copy of the "static" one.
      * We need this one to be able to use the faster, but not thread-safe
@@ -639,6 +660,10 @@
     {
 
         super();
+        // we are just constructing this thing, no output properties
+        // have been used, so we will set the right default for
+        // indenting anyways
+        m_doIndent = true; 
         m_charInfo = m_htmlcharInfo;
         // initialize namespaces
         m_prefixMap = new NamespaceMappings();
@@ -1718,7 +1743,8 @@
 
     /**
      * For the enclosing elements starting tag write out out any attributes
-     * followed by ">"
+     * followed by ">". At this point we also mark if this element is
+     * a cdata-section-element.
      *
      *@throws org.xml.sax.SAXException
      */
@@ -1741,11 +1767,11 @@
 
             m_writer.write('>');
 
-            /* whether Xalan or XSLTC, we have the prefix mappings now, so
+            /* At this point we have the prefix mappings now, so
              * lets determine if the current element is specified in the cdata-
              * section-elements list.
              */
-            if (m_cdataSectionElements != null) 
+            if (m_CdataElems != null) // if there are any cdata sections
                 m_elemContext.m_isCdataSection = isCdataSection();
             if (m_doIndent)
             {

Modified: xalan/java/trunk/src/org/apache/xml/serializer/ToStream.java
URL: http://svn.apache.org/viewcvs/xalan/java/trunk/src/org/apache/xml/serializer/ToStream.java?rev=370242&r1=370241&r2=370242&view=diff
==============================================================================
--- xalan/java/trunk/src/org/apache/xml/serializer/ToStream.java (original)
+++ xalan/java/trunk/src/org/apache/xml/serializer/ToStream.java Wed Jan 18 12:03:53 2006
@@ -22,6 +22,7 @@
 import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
 import java.io.Writer;
+import java.util.Enumeration;
 import java.util.Properties;
 import java.util.StringTokenizer;
 import java.util.Vector;
@@ -221,7 +222,7 @@
     /**
      * Taken from XSLTC 
      */
-    private boolean m_escaping = true;
+    protected boolean m_escaping = true;
 
     /**
      * Flush the formatter's result stream.
@@ -426,13 +427,21 @@
         else
             m_writer = writer;        
         
+        if (m_format == null)
+            m_format = new java.util.Properties();
+        if (format != null)
+        {
+            Enumeration propNames = format.propertyNames();
+            while (propNames.hasMoreElements())
+            {
+                String key = (String) propNames.nextElement();
+                String value = format.getProperty(key);
+                m_format.setProperty(key, value);
+            } 
+        }
 
-        m_format = format;
-        //        m_cdataSectionNames =
-        //            OutputProperties.getQNameProperties(
-        //                OutputKeys.CDATA_SECTION_ELEMENTS,
-        //                format);
-        setCdataSectionElements(OutputKeys.CDATA_SECTION_ELEMENTS, format);
+        String cdataSectionNames = format.getProperty(OutputKeys.CDATA_SECTION_ELEMENTS);
+        addCdataSectionElements(cdataSectionNames);
 
         setIndentAmount(
             OutputPropertyUtils.getIntProperty(
@@ -1851,17 +1860,6 @@
                 else
                     writer.write('\"');
             }
-            boolean dothis = false;
-            if (dothis)
-            {
-                // at one point this code seemed right,
-                // but not anymore - Brian M.
-                if (closeDecl)
-                {
-                    writer.write('>');
-                    writer.write(m_lineSep, 0, m_lineSepLen);
-                }
-            }
         }
         catch (IOException e)
         {
@@ -1934,15 +1932,7 @@
                 writer.write(ch);
             }
             else
-            { // I guess the parser doesn't normalize cr/lf in attributes. -sb
-//                if ((CharInfo.S_CARRIAGERETURN == ch)
-//                    && ((i + 1) < len)
-//                    && (CharInfo.S_LINEFEED == stringChars[i + 1]))
-//                {
-//                    i++;
-//                    ch = CharInfo.S_LINEFEED;
-//                }
-
+            {
                 accumDefaultEscape(writer, ch, i, stringChars, len, false, true);
             }
         }
@@ -2389,7 +2379,7 @@
              * lets determine if the current element is specified in the cdata-
              * section-elements list.
              */
-            if (m_cdataSectionElements != null)
+            if (m_CdataElems != null)
                 m_elemContext.m_isCdataSection = isCdataSection();
 
             if (m_doIndent)
@@ -2562,7 +2552,34 @@
      */
     public void setCdataSectionElements(Vector URI_and_localNames)
     {
-        m_cdataSectionElements = URI_and_localNames;
+        // convert to the new way.
+        if (URI_and_localNames != null)
+        {
+            final int len = URI_and_localNames.size() - 1;
+            if (len > 0)
+            {
+                final StringBuffer sb = new StringBuffer();
+                for (int i = 0; i < len; i += 2)
+                {
+                    // whitspace separated "{uri1}local1 {uri2}local2 ..."
+                    if (i != 0)
+                        sb.append(' ');
+                    final String uri = (String) URI_and_localNames.elementAt(i);
+                    final String localName =
+                        (String) URI_and_localNames.elementAt(i + 1);
+                    if (uri != null)
+                    {
+                        // If there is no URI don't put this in, just the localName then.
+                        sb.append('{');
+                        sb.append(uri);
+                        sb.append('}');
+                    }
+                    sb.append(localName);
+                }
+                m_StringOfCDATASections = sb.toString();
+            }
+        }
+        initCdataElems(m_StringOfCDATASections);
     }
 
     /**
@@ -3326,5 +3343,25 @@
     public void setNewLine (char[] eolChars) {
         m_lineSep = eolChars;
         m_lineSepLen = eolChars.length;
+    }
+
+    /**
+     * Remembers the cdata sections specified in the cdata-section-elements by appending the given
+     * cdata section elements to the list. This method can be called multiple times, but once an
+     * element is put in the list of cdata section elements it can not be removed.
+     * This method should be used by both Xalan and XSLTC.
+     * 
+     * @param URI_and_localNames a whitespace separated list of element names, each element
+     * is a URI in curly braces (optional) and a local name. An example of such a parameter is:
+     * "{http://company.com}price {myURI2}book chapter"
+     */
+    public void addCdataSectionElements(String URI_and_localNames)
+    {
+        if (URI_and_localNames != null)
+            initCdataElems(URI_and_localNames);
+        if (m_StringOfCDATASections == null)
+            m_StringOfCDATASections = URI_and_localNames;
+        else
+            m_StringOfCDATASections += (" " + URI_and_localNames);
     }
 }



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