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/11/15 23:07:09 UTC

svn commit: r475456 - in /xalan/java/trunk/src/org/apache/xml/serializer: DOM3Serializer.java dom3/DOM3SerializerImpl.java dom3/DOM3TreeWalker.java dom3/LSSerializerImpl.java

Author: minchau
Date: Wed Nov 15 14:07:08 2006
New Revision: 475456

URL: http://svn.apache.org/viewvc?view=rev&rev=475456
Log:
I have reviewed Michael G.'s patch in XALANJ-2323 and I approve it.
This fixes some DOM Level 3 serialization bugs.

Modified:
    xalan/java/trunk/src/org/apache/xml/serializer/DOM3Serializer.java
    xalan/java/trunk/src/org/apache/xml/serializer/dom3/DOM3SerializerImpl.java
    xalan/java/trunk/src/org/apache/xml/serializer/dom3/DOM3TreeWalker.java
    xalan/java/trunk/src/org/apache/xml/serializer/dom3/LSSerializerImpl.java

Modified: xalan/java/trunk/src/org/apache/xml/serializer/DOM3Serializer.java
URL: http://svn.apache.org/viewvc/xalan/java/trunk/src/org/apache/xml/serializer/DOM3Serializer.java?view=diff&rev=475456&r1=475455&r2=475456
==============================================================================
--- xalan/java/trunk/src/org/apache/xml/serializer/DOM3Serializer.java (original)
+++ xalan/java/trunk/src/org/apache/xml/serializer/DOM3Serializer.java Wed Nov 15 14:07:08 2006
@@ -256,8 +256,8 @@
     public LSSerializerFilter getNodeFilter();
 
     /**
-     * Sets the new line character to be used during serialization
-     * @param newLine A character array corresponding to the new line character to be used.
+     * Sets the end-of-line sequence of characters to be used during serialization
+     * @param newLine The end-of-line sequence of characters to be used during serialization
      */
     public void setNewLine(char[] newLine);
 }

Modified: xalan/java/trunk/src/org/apache/xml/serializer/dom3/DOM3SerializerImpl.java
URL: http://svn.apache.org/viewvc/xalan/java/trunk/src/org/apache/xml/serializer/dom3/DOM3SerializerImpl.java?view=diff&rev=475456&r1=475455&r2=475456
==============================================================================
--- xalan/java/trunk/src/org/apache/xml/serializer/dom3/DOM3SerializerImpl.java (original)
+++ xalan/java/trunk/src/org/apache/xml/serializer/dom3/DOM3SerializerImpl.java Wed Nov 15 14:07:08 2006
@@ -47,7 +47,7 @@
     private LSSerializerFilter fSerializerFilter;
 
     // A LSSerializerFilter
-    private char[] fNewLine;
+    private String fNewLine;
 
     // A SerializationHandler ex. an instance of ToXMLStream
     private SerializationHandler fSerializationHandler;
@@ -85,12 +85,12 @@
     public LSSerializerFilter getNodeFilter() {
         return fSerializerFilter;
     }
-
+    
     /**
-     * Gets the new line character to be used during serialization
+     * Gets the end-of-line sequence of characters to be used during serialization.
      */
     public char[] getNewLine() {
-        return fNewLine;
+        return (fNewLine != null) ? fNewLine.toCharArray() : null;
     }
 
     /**
@@ -149,10 +149,10 @@
     }
 
     /**
-     * Sets the new line character to be used during serialization
-     * @param newLine A character array corresponding to the new line character to be used.
+     * Sets the end-of-line sequence of characters to be used during serialization.
+     * @param newLine The end-of-line sequence of characters to be used during serialization.
      */
     public void setNewLine(char[] newLine) {
-        fNewLine = newLine;
+        fNewLine = (newLine != null) ? new String(newLine) : null;
     }
 }

Modified: xalan/java/trunk/src/org/apache/xml/serializer/dom3/DOM3TreeWalker.java
URL: http://svn.apache.org/viewvc/xalan/java/trunk/src/org/apache/xml/serializer/dom3/DOM3TreeWalker.java?view=diff&rev=475456&r1=475455&r2=475456
==============================================================================
--- xalan/java/trunk/src/org/apache/xml/serializer/dom3/DOM3TreeWalker.java (original)
+++ xalan/java/trunk/src/org/apache/xml/serializer/dom3/DOM3TreeWalker.java Wed Nov 15 14:07:08 2006
@@ -91,7 +91,7 @@
     private int fWhatToShowFilter;
 
     /** New Line character to use in serialization */
-    private char[] fNewLine = null;
+    private String fNewLine = null;
 
     /** DOMConfiguration Properties */
     private Properties fDOMConfigProperties = null;
@@ -205,7 +205,7 @@
         SerializationHandler serialHandler,
         DOMErrorHandler errHandler,
         LSSerializerFilter filter,
-        char[] newLine) {
+        String newLine) {
         fSerializer = serialHandler;
         //fErrorHandler = errHandler == null ? new DOMErrorHandlerImpl() : errHandler; // Should we be using the default?
         fErrorHandler = errHandler;
@@ -2139,8 +2139,7 @@
         }
         // Set the newLine character to use
         if (fNewLine != null) {
-            fSerializer.setOutputProperty(OutputPropertiesFactory.S_KEY_LINE_SEPARATOR,
-                    String.valueOf(fNewLine));
+            fSerializer.setOutputProperty(OutputPropertiesFactory.S_KEY_LINE_SEPARATOR, fNewLine);
         }
     }
 

Modified: xalan/java/trunk/src/org/apache/xml/serializer/dom3/LSSerializerImpl.java
URL: http://svn.apache.org/viewvc/xalan/java/trunk/src/org/apache/xml/serializer/dom3/LSSerializerImpl.java?view=diff&rev=475456&r1=475455&r2=475456
==============================================================================
--- xalan/java/trunk/src/org/apache/xml/serializer/dom3/LSSerializerImpl.java (original)
+++ xalan/java/trunk/src/org/apache/xml/serializer/dom3/LSSerializerImpl.java Wed Nov 15 14:07:08 2006
@@ -21,10 +21,8 @@
 
 package org.apache.xml.serializer.dom3;
 
-import java.io.File;
 import java.io.FileOutputStream;
 import java.io.OutputStream;
-import java.io.OutputStreamWriter;
 import java.io.StringWriter;
 import java.io.UnsupportedEncodingException;
 import java.io.Writer;
@@ -32,15 +30,16 @@
 import java.net.URL;
 import java.net.URLConnection;
 import java.util.Properties;
+import java.util.StringTokenizer;
 
 import org.apache.xml.serializer.DOM3Serializer;
 import org.apache.xml.serializer.Encodings;
-import org.apache.xml.serializer.Serializer;
 import org.apache.xml.serializer.OutputPropertiesFactory;
+import org.apache.xml.serializer.Serializer;
 import org.apache.xml.serializer.SerializerFactory;
 import org.apache.xml.serializer.utils.MsgKey;
-import org.apache.xml.serializer.utils.Utils;
 import org.apache.xml.serializer.utils.SystemIDResolver;
+import org.apache.xml.serializer.utils.Utils;
 import org.w3c.dom.DOMConfiguration;
 import org.w3c.dom.DOMError;
 import org.w3c.dom.DOMErrorHandler;
@@ -53,7 +52,6 @@
 import org.w3c.dom.ls.LSSerializer;
 import org.w3c.dom.ls.LSSerializerFilter;
 
-
 /**
  * Implemenatation of DOM Level 3 org.w3c.ls.LSSerializer and 
  * org.w3c.dom.ls.DOMConfiguration.  Serialization is achieved by delegating 
@@ -69,6 +67,17 @@
  */
 final public class LSSerializerImpl implements DOMConfiguration, LSSerializer {
     
+    // The default end-of-line character sequence used in serialization.
+    private static final String DEFAULT_END_OF_LINE;
+    static {
+        String lineSeparator = System.getProperty("line.separator");
+        // The DOM Level 3 Load and Save specification requires that implementations choose a default
+        // sequence which matches one allowed by XML 1.0 (or XML 1.1). If the value of "line.separator" 
+        // isn't one of the XML 1.0 end-of-line sequences then we select "\n" as the default value.
+        DEFAULT_END_OF_LINE = lineSeparator != null && 
+            (lineSeparator.equals("\r\n") || lineSeparator.equals("\r")) ? lineSeparator : "\n";
+    }
+    
     /** private data members */
     private Serializer fXMLSerializer = null;
     
@@ -84,8 +93,8 @@
     // Stores the nodeArg parameter to speed up multiple writes of the same node.
     private Node fVisitedNode = null;
     
-    // The end-of-line character sequence used in serialization.  "\n" is whats used on the web.
-    private String fEndOfLine = System.getProperty("line.separator") != null ? System.getProperty("line.separator"): "\n";
+    // The end-of-line character sequence used in serialization. "\n" is whats used on the web.
+    private String fEndOfLine = DEFAULT_END_OF_LINE;
     
     // The DOMErrorhandler.
     private DOMErrorHandler fDOMErrorHandler = null;
@@ -596,8 +605,15 @@
             } else if (name.equalsIgnoreCase(DOMConstants.DOM_FORMAT_PRETTY_PRINT)) {
                 fFeatures = state ? fFeatures | PRETTY_PRINT : fFeatures
                         & ~PRETTY_PRINT;
-                fDOMConfigProperties.setProperty(DOMConstants.S_XSL_OUTPUT_INDENT,DOMConstants.DOM3_EXPLICIT_TRUE);
-                fDOMConfigProperties.setProperty(OutputPropertiesFactory.S_KEY_INDENT_AMOUNT, Integer.toString(3));                
+                // format-pretty-print
+                if (state) {
+                    fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                            + DOMConstants.DOM_FORMAT_PRETTY_PRINT, DOMConstants.DOM3_EXPLICIT_TRUE);
+                }
+                else {
+                    fDOMConfigProperties.setProperty(DOMConstants.S_DOM3_PROPERTIES_NS 
+                            + DOMConstants.DOM_FORMAT_PRETTY_PRINT, DOMConstants.DOM3_EXPLICIT_FALSE);
+                }
             } else if (name.equalsIgnoreCase(DOMConstants.DOM_XMLDECL)) {
                 fFeatures = state ? fFeatures | XMLDECL : fFeatures
                         & ~XMLDECL;
@@ -793,7 +809,7 @@
      * serialization.
      */
     public void setNewLine(String newLine) {
-        fEndOfLine = newLine !=null? newLine: fEndOfLine;
+        fEndOfLine = (newLine != null) ? newLine : DEFAULT_END_OF_LINE;
     }
     
     /** 
@@ -934,7 +950,7 @@
                         if (protocol.equalsIgnoreCase("file") 
                                 && (host == null || host.length() == 0 || host.equals("localhost"))) {
                             // do we also need to check for host.equals(hostname)
-                            urlOutStream = new FileOutputStream(new File(url.getPath()));
+                            urlOutStream = new FileOutputStream(getPathWithoutEscapes(url.getPath()));
                            
                         } else {
                             // This should support URL's whose schemes are mentioned in 
@@ -954,11 +970,11 @@
                             urlOutStream = urlCon.getOutputStream();
                         }
                         // set the OutputStream to that obtained from the systemId
-                        serializer.setWriter(new OutputStreamWriter(urlOutStream));
+                        serializer.setOutputStream(urlOutStream);
                     }
                 } else {
                     // 2.LSOutput.byteStream
-                    serializer.setWriter(new OutputStreamWriter(outputStream, fEncoding));                     
+                    serializer.setOutputStream(outputStream);     
                 }
             } else {
                 // 1.LSOutput.characterStream
@@ -1002,21 +1018,19 @@
                         DOMError.SEVERITY_FATAL_ERROR, msg,
                         MsgKey.ER_UNSUPPORTED_ENCODING, ue));
             }
-            throw new LSException(LSException.SERIALIZE_ERR, ue.getMessage());
+            throw (LSException) createLSException(LSException.SERIALIZE_ERR, ue).fillInStackTrace();
         } catch (LSException lse) {
             // Rethrow LSException.
             throw lse;
         } catch (RuntimeException e) {
-            e.printStackTrace();
-            throw new LSException(LSException.SERIALIZE_ERR, e!=null?e.getMessage():"NULL Exception") ;
+            throw (LSException) createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace();
         }  catch (Exception e) {
             if (fDOMErrorHandler != null) {
                 fDOMErrorHandler.handleError(new DOMErrorImpl(
                         DOMError.SEVERITY_FATAL_ERROR, e.getMessage(),
                         null, e));
-            } 
-            e.printStackTrace();
-            throw new LSException(LSException.SERIALIZE_ERR, e.toString());
+            }
+            throw (LSException) createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace();
         }        
         return true;
     }
@@ -1105,16 +1119,14 @@
             // Rethrow LSException.
             throw lse;
         } catch (RuntimeException e) {
-            e.printStackTrace();
-            throw new LSException(LSException.SERIALIZE_ERR, e.toString());
+            throw (LSException) createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace();
         }  catch (Exception e) {
             if (fDOMErrorHandler != null) {
                 fDOMErrorHandler.handleError(new DOMErrorImpl(
                         DOMError.SEVERITY_FATAL_ERROR, e.getMessage(),
                         null, e));
-            } 
-            e.printStackTrace();
-            throw new LSException(LSException.SERIALIZE_ERR, e.toString());
+            }
+            throw (LSException) createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace();
         }        
         
         // return the serialized string
@@ -1214,7 +1226,7 @@
                         && (host == null || host.length() == 0 || host
                                 .equals("localhost"))) {
                     // do we also need to check for host.equals(hostname)
-                    urlOutStream = new FileOutputStream(new File(url.getPath()));
+                    urlOutStream = new FileOutputStream(getPathWithoutEscapes(url.getPath()));
                     
                 } else {
                     // This should support URL's whose schemes are mentioned in
@@ -1234,7 +1246,7 @@
                     urlOutStream = urlCon.getOutputStream();
                 }
                 // set the OutputStream to that obtained from the systemId
-                serializer.setWriter(new OutputStreamWriter(urlOutStream, fEncoding));
+                serializer.setOutputStream(urlOutStream);
             }
             
             // Get a reference to the serializer then lets you serilize a DOM
@@ -1265,16 +1277,14 @@
             // Rethrow LSException.
             throw lse;
         } catch (RuntimeException e) {
-            e.printStackTrace();
-            throw new LSException(LSException.SERIALIZE_ERR, e.toString());
+            throw (LSException) createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace();
         }  catch (Exception e) {
             if (fDOMErrorHandler != null) {
                 fDOMErrorHandler.handleError(new DOMErrorImpl(
                         DOMError.SEVERITY_FATAL_ERROR, e.getMessage(),
                         null, e));
-            } 
-            e.printStackTrace();
-            throw new LSException(LSException.SERIALIZE_ERR, e.toString());
+            }
+            throw (LSException) createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace();
         }        
         
         return true;
@@ -1387,4 +1397,80 @@
         return fDOMErrorHandler;
     }
     
+    /**
+     * Replaces all escape sequences in the given path with their literal characters.
+     */
+    private static String getPathWithoutEscapes(String origPath) {
+        if (origPath != null && origPath.length() != 0 && origPath.indexOf('%') != -1) {
+            // Locate the escape characters
+            StringTokenizer tokenizer = new StringTokenizer(origPath, "%");
+            StringBuffer result = new StringBuffer(origPath.length());
+            int size = tokenizer.countTokens();
+            result.append(tokenizer.nextToken());
+            for(int i = 1; i < size; ++i) {
+                String token = tokenizer.nextToken();
+                if (token.length() >= 2 && isHexDigit(token.charAt(0)) && 
+                        isHexDigit(token.charAt(1))) {
+                    // Decode the 2 digit hexadecimal number following % in '%nn'
+                    result.append((char)Integer.valueOf(token.substring(0, 2), 16).intValue());
+                    token = token.substring(2);
+                }
+                result.append(token);
+            }
+            return result.toString();
+        }
+        return origPath;
+    }
+
+    /** 
+     * Returns true if the given character is a valid hex character.
+     */
+    private static boolean isHexDigit(char c) {
+        return (c >= '0' && c <= '9' || 
+                c >= 'a' && c <= 'f' || 
+                c >= 'A' && c <= 'F');
+    }
+    
+    /**
+     * Creates an LSException. On J2SE 1.4 and above the cause for the exception will be set.
+     */
+    private static LSException createLSException(short code, Throwable cause) {
+        LSException lse = new LSException(code, cause != null ? cause.getMessage() : null);
+        if (cause != null && ThrowableMethods.fgThrowableMethodsAvailable) {
+            try {
+                ThrowableMethods.fgThrowableInitCauseMethod.invoke(lse, new Object [] {cause});
+            }
+            // Something went wrong. There's not much we can do about it.
+            catch (Exception e) {}
+        }
+        return lse;
+    }
+    
+    /**
+     * Holder of methods from java.lang.Throwable.
+     */
+    static class ThrowableMethods {
+        
+        // Method: java.lang.Throwable.initCause(java.lang.Throwable)
+        private static java.lang.reflect.Method fgThrowableInitCauseMethod = null;
+        
+        // Flag indicating whether or not Throwable methods available.
+        private static boolean fgThrowableMethodsAvailable = false;
+        
+        private ThrowableMethods() {}
+        
+        // Attempt to get methods for java.lang.Throwable on class initialization.
+        static {
+            try {
+                fgThrowableInitCauseMethod = Throwable.class.getMethod("initCause", new Class [] {Throwable.class});
+                fgThrowableMethodsAvailable = true;
+            }
+            // ClassNotFoundException, NoSuchMethodException or SecurityException
+            // Whatever the case, we cannot use java.lang.Throwable.initCause(java.lang.Throwable).
+            catch (Exception exc) {
+                fgThrowableInitCauseMethod = null;
+                fgThrowableMethodsAvailable = false;
+            }
+        }
+    }
 }



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