You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by st...@apache.org on 2005/04/01 15:40:08 UTC

svn commit: r159686 - in incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core: util/Base64.java util/ValueHelper.java xml/DocViewSAXEventGenerator.java xml/SysViewImportHandler.java xml/SysViewSAXEventGenerator.java

Author: stefan
Date: Fri Apr  1 05:40:06 2005
New Revision: 159686

URL: http://svn.apache.org/viewcvs?view=rev&rev=159686
Log:
consolidated Value de-/serialization code in static methods of ValueHelper class

Modified:
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/util/Base64.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/util/ValueHelper.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/DocViewSAXEventGenerator.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/SysViewImportHandler.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/SysViewSAXEventGenerator.java

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/util/Base64.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/util/Base64.java?view=diff&r1=159685&r2=159686
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/util/Base64.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/util/Base64.java Fri Apr  1 05:40:06 2005
@@ -35,7 +35,8 @@
     private static final char[] BASE64CHARS =
             "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
 
-    // decoding table (used to lookup original 6-bit with base64 character as table index)
+    // decoding table (used to lookup original 6-bit with base64 character
+    // as table index)
     private static final byte[] DECODETABLE = new byte[128];
 
     static {
@@ -72,8 +73,9 @@
     }
 
     /**
-     * Pessimistically guesses the size (i.e. number of bytes) of the decoded output
-     * given the length (i.e. number of bytes) of the base64 encoded data.
+     * Pessimistically guesses the size (i.e. number of bytes) of the decoded
+     * output given the length (i.e. number of bytes) of the base64 encoded
+     * data.
      *
      * @param encLength length (i.e. number of bytes) of the base64 encoded data
      * @return size (i.e. number of bytes) of the decoded output
@@ -84,10 +86,12 @@
     }
 
     /**
-     * Outputs base64 representation of the specified stream data to an <code>OutputStream</code>.
+     * Outputs base64 representation of the specified stream data to a
+     * <code>Writer</code>.
      *
      * @param in     stream data to be encoded
      * @param writer writer to output the encoded data
+     * @throws IOException if an i/o error occurs
      */
     public static void encode(InputStream in, Writer writer)
             throws IOException {
@@ -95,17 +99,19 @@
         // chunksize must be a multiple of 3 in order
         // to avoid padding within output
         byte[] buffer = new byte[9 * 1024];
-        int read = 0;
+        int read;
         while ((read = in.read(buffer)) > 0) {
             encode(buffer, 0, read, writer);
         }
     }
 
     /**
-     * Outputs base64 representation of the specified stream data to an <code>OutputStream</code>.
+     * Outputs base64 representation of the specified stream data to an
+     * <code>OutputStream</code>.
      *
      * @param in  stream data to be encoded
      * @param out stream where the encoded data should be written to
+     * @throws IOException if an i/o error occurs
      */
     public static void encode(InputStream in, OutputStream out)
             throws IOException {
@@ -114,12 +120,14 @@
     }
 
     /**
-     * Outputs base64 representation of the specified data to an <code>OutputStream</code>.
+     * Outputs base64 representation of the specified data to a
+     * <code>Writer</code>.
      *
      * @param data   data to be encoded
      * @param off    offset within data at which to start encoding
      * @param len    length of data to encode
      * @param writer writer to output the encoded data
+     * @throws IOException if an i/o error occurs
      */
     public static void encode(byte[] data, int off, int len, Writer writer)
             throws IOException {
@@ -166,8 +174,10 @@
      *
      * @param reader reader for the base64 encoded data to be decoded
      * @param out    stream where the decoded data should be written to
+     * @throws IOException if an i/o error occurs
      */
-    public static void decode(Reader reader, OutputStream out) throws IOException {
+    public static void decode(Reader reader, OutputStream out)
+            throws IOException {
         char[] chunk = new char[8192];
         int read;
         while ((read = reader.read(chunk)) > -1) {
@@ -181,8 +191,10 @@
      *
      * @param in  inputstream of the base64 encoded data to be decoded
      * @param out stream where the decoded data should be written to
+     * @throws IOException if an i/o error occurs
      */
-    public static void decode(InputStream in, OutputStream out) throws IOException {
+    public static void decode(InputStream in, OutputStream out)
+            throws IOException {
         decode(new InputStreamReader(in, CHARSET), out);
     }
 
@@ -191,8 +203,10 @@
      *
      * @param data the base64 encoded data to be decoded
      * @param out  stream where the decoded data should be written to
+     * @throws IOException if an i/o error occurs
      */
-    public static void decode(String data, OutputStream out) throws IOException {
+    public static void decode(String data, OutputStream out)
+            throws IOException {
         char[] chars = data.toCharArray();
         decode(chars, 0, chars.length, out);
     }
@@ -202,8 +216,10 @@
      *
      * @param chars the base64 encoded data to be decoded
      * @param out   stream where the decoded data should be written to
+     * @throws IOException if an i/o error occurs
      */
-    public static void decode(char[] chars, OutputStream out) throws IOException {
+    public static void decode(char[] chars, OutputStream out)
+            throws IOException {
         decode(chars, 0, chars.length, out);
     }
 
@@ -214,8 +230,10 @@
      * @param off   offset within data at which to start decoding
      * @param len   length of data to decode
      * @param out   stream where the decoded data should be written to
+     * @throws IOException if an i/o error occurs
      */
-    public static void decode(char[] chars, int off, int len, OutputStream out) throws IOException {
+    public static void decode(char[] chars, int off, int len, OutputStream out)
+            throws IOException {
         if (len == 0) {
             return;
         }

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/util/ValueHelper.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/util/ValueHelper.java?view=diff&r1=159685&r2=159686
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/util/ValueHelper.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/util/ValueHelper.java Fri Apr  1 05:40:06 2005
@@ -34,6 +34,12 @@
 import javax.jcr.StringValue;
 import javax.jcr.Value;
 import javax.jcr.ValueFormatException;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.io.Writer;
 
 /**
  * The <code>ValueHelper</code> class provides several <code>Value</code>
@@ -52,11 +58,10 @@
      * @param targetType
      * @return
      * @throws ValueFormatException
-     * @throws IllegalStateException
      * @throws IllegalArgumentException
      */
     public static Value convert(String srcValue, int targetType)
-            throws ValueFormatException, IllegalStateException, IllegalArgumentException {
+            throws ValueFormatException, IllegalArgumentException {
         return convert(new StringValue(srcValue), targetType);
     }
 
@@ -69,7 +74,8 @@
      * @throws IllegalArgumentException
      */
     public static Value convert(Value srcValue, int targetType)
-            throws ValueFormatException, IllegalStateException, IllegalArgumentException {
+            throws ValueFormatException, IllegalStateException,
+            IllegalArgumentException {
         Value val;
         int srcType = srcValue.getType();
 
@@ -163,13 +169,15 @@
                             path = srcValue.getString();
                         } catch (RepositoryException re) {
                             // should never happen
-                            throw new ValueFormatException("failed to convert source value to PATH value", re);
+                            throw new ValueFormatException("failed to convert source value to PATH value",
+                                    re);
                         }
                         try {
                             // check path format
                             Path.checkFormat(path);
                         } catch (MalformedPathException mpe) {
-                            throw new ValueFormatException("source value " + path + " does not represent a valid path", mpe);
+                            throw new ValueFormatException("source value " + path
+                                    + " does not represent a valid path", mpe);
                         }
                         val = PathValue.valueOf(path);
                         break;
@@ -198,7 +206,7 @@
 
                     case PropertyType.BINARY:
                     case PropertyType.STRING:
-                    case PropertyType.PATH:	// path might be a name (relative, onle element long path)
+                    case PropertyType.PATH:	// path might be a name (relative path of length 1)
                         // try conversion via string
                         String name;
                         try {
@@ -206,13 +214,16 @@
                             name = srcValue.getString();
                         } catch (RepositoryException re) {
                             // should never happen
-                            throw new ValueFormatException("failed to convert source value to NAME value", re);
+                            throw new ValueFormatException("failed to convert source value to NAME value",
+                                    re);
                         }
                         try {
                             // check name format
                             QName.checkFormat(name);
                         } catch (IllegalNameException ine) {
-                            throw new ValueFormatException("source value " + name + " does not represent a valid name", ine);
+                            throw new ValueFormatException("source value "
+                                    + name
+                                    + " does not represent a valid name", ine);
                         }
                         val = NameValue.valueOf(name);
                         break;
@@ -248,7 +259,8 @@
                             uuid = srcValue.getString();
                         } catch (RepositoryException re) {
                             // should never happen
-                            throw new ValueFormatException("failed to convert source value to REFERENCE value", re);
+                            throw new ValueFormatException("failed to convert source value to REFERENCE value",
+                                    re);
                         }
                         val = ReferenceValue.valueOf(uuid);
                         break;
@@ -340,5 +352,159 @@
             newVal[i] = copy(srcVal[i]);
         }
         return newVal;
+    }
+
+    /**
+     * Serializes the given value to a <code>String</code>. The serialization
+     * format is the same as used by Document & System View XML, i.e.
+     * binary values will be Base64-encoded whereas for all others
+     * <code>{@link javax.jcr.Value#getString()}</code> will be used.
+     *
+     * @param value        the value to be serialized
+     * @param encodeBlanks if <code>true</code> space characters will be encoded
+     *                     as <code>"_x0020_"</code> within he output string.
+     * @return a string representation of the given value.
+     * @throws IllegalStateException if the given value is in an illegal state
+     * @throws RepositoryException   if an error occured during the serialization.
+     */
+    public static String serialize(Value value, boolean encodeBlanks)
+            throws IllegalStateException, RepositoryException {
+        StringWriter writer = new StringWriter();
+        try {
+            serialize(value, encodeBlanks, writer);
+        } catch (IOException ioe) {
+            throw new RepositoryException("failed to serialize value",
+                    ioe);
+        }
+        return writer.toString();
+    }
+
+    /**
+     * Outputs the serialized value to a <code>Writer</code>. The serialization
+     * format is the same as used by Document & System View XML, i.e.
+     * binary values will be Base64-encoded whereas for all others
+     * <code>{@link javax.jcr.Value#getString()}</code> will be used for
+     * serialization.
+     *
+     * @param value        the value to be serialized
+     * @param encodeBlanks if <code>true</code> space characters will be encoded
+     *                     as <code>"_x0020_"</code> within he output string.
+     * @param writer       writer to output the encoded data
+     * @throws IllegalStateException if the given value is in an illegal state
+     * @throws IOException           if an i/o error occured during the
+     *                               serialization
+     * @throws RepositoryException   if an error occured during the serialization.
+     */
+    public static void serialize(Value value, boolean encodeBlanks,
+                                 Writer writer)
+            throws IllegalStateException, IOException, RepositoryException {
+        if (value.getType() == PropertyType.BINARY) {
+            // binary data, base64 encoding required;
+            // the encodeBlanks flag can be ignored since base64-encoded
+            // data cannot contain space characters
+            InputStream in = value.getStream();
+            try {
+                Base64.encode(in, writer);
+                // no need to close StringWriter
+                //writer.close();
+            } finally {
+                try {
+                    in.close();
+                } catch (IOException e) {
+                    // ignore
+                }
+            }
+        } else {
+            String textVal = value.getString();
+            if (encodeBlanks) {
+                // enocde blanks in string
+                textVal = Text.replace(textVal, " ", "_x0020_");
+            }
+            writer.write(textVal);
+        }
+    }
+
+    /**
+     * Deserializes the given string to a <code>Value</code> of the given type.
+     *
+     * @param value        string to be deserialized
+     * @param type         type of value
+     * @param decodeBlanks if <code>true</code> <code>"_x0020_"</code>
+     *                     character sequences will be decoded to single space
+     *                     characters each.
+     * @return the deserialized <code>Value</code>
+     * @throws ValueFormatException if the string data is not of the required
+     *                              format
+     * @throws RepositoryException  if an error occured during the
+     *                              deserialization.
+     */
+    public static Value deserialize(String value, int type,
+                                    boolean decodeBlanks)
+            throws RepositoryException {
+        if (type == PropertyType.BINARY) {
+            // base64 encoded binary value;
+            // the encodeBlanks flag can be ignored since base64-encoded
+            // data cannot contain encoded space characters
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            try {
+                Base64.decode(value, baos);
+                // no need to close ByteArrayOutputStream
+                //baos.close();
+            } catch (IOException ioe) {
+                throw new RepositoryException("failed to decode binary value",
+                        ioe);
+            }
+            return new BinaryValue(baos.toByteArray());
+        } else {
+            if (decodeBlanks) {
+                // decode encoded blanks in value
+                value = Text.replace(value, "_x0020_", " ");
+            }
+            return convert(value, type);
+        }
+    }
+
+    /**
+     * Deserializes the string data read from the given reader to a
+     * <code>Value</code> of the given type.
+     *
+     * @param reader       reader for the string data to be deserialized
+     * @param type         type of value
+     * @param decodeBlanks if <code>true</code> <code>"_x0020_"</code>
+     *                     character sequences will be decoded to single space characters each.
+     * @return the deserialized <code>Value</code>
+     * @throws IOException          if an i/o error occured during the
+     *                              serialization
+     * @throws ValueFormatException if the string data is not of the required
+     *                              format
+     * @throws RepositoryException  if an error occured during the
+     *                              deserialization.
+     */
+    public static Value deserialize(Reader reader, int type,
+                                    boolean decodeBlanks)
+            throws IOException, ValueFormatException, RepositoryException {
+        if (type == PropertyType.BINARY) {
+            // base64 encoded binary value;
+            // the encodeBlanks flag can be ignored since base64-encoded
+            // data cannot contain encoded space characters
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            Base64.decode(reader, baos);
+            // no need to close ByteArrayOutputStream
+            //baos.close();
+            return new BinaryValue(baos.toByteArray());
+        } else {
+            char[] chunk = new char[8192];
+            int read;
+            StringBuffer buf = new StringBuffer();
+            while ((read = reader.read(chunk)) > -1) {
+                buf.append(chunk, 0, read);
+            }
+            String value = buf.toString();
+            if (decodeBlanks) {
+                // decode encoded blanks in value
+                value = Text.replace(value, "_x0020_", " ");
+            }
+            return convert(value, type);
+        }
     }
 }

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/DocViewSAXEventGenerator.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/DocViewSAXEventGenerator.java?view=diff&r1=159685&r2=159686
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/DocViewSAXEventGenerator.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/DocViewSAXEventGenerator.java Fri Apr  1 05:40:06 2005
@@ -21,9 +21,8 @@
 import org.apache.jackrabbit.core.PropertyImpl;
 import org.apache.jackrabbit.core.QName;
 import org.apache.jackrabbit.core.SessionImpl;
-import org.apache.jackrabbit.core.util.Base64;
 import org.apache.jackrabbit.core.util.ISO9075;
-import org.apache.jackrabbit.core.util.Text;
+import org.apache.jackrabbit.core.util.ValueHelper;
 import org.apache.log4j.Logger;
 import org.xml.sax.ContentHandler;
 import org.xml.sax.SAXException;
@@ -32,9 +31,6 @@
 import javax.jcr.PropertyType;
 import javax.jcr.RepositoryException;
 import javax.jcr.Value;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -56,11 +52,13 @@
      * Constructor
      *
      * @param node           the node state which should be serialized
-     * @param noRecurse      if true, only <code>node</code> and its properties will
-     *                       be serialized; otherwise the entire hierarchy starting with
-     *                       <code>node</code> will be serialized.
-     * @param skipBinary     flag governing whether binary properties are to be serialized.
-     * @param session        the session to be used for resolving namespace mappings
+     * @param noRecurse      if true, only <code>node</code> and its properties
+     *                       will be serialized; otherwise the entire hierarchy
+     *                       starting with <code>node</code> will be serialized.
+     * @param skipBinary     flag governing whether binary properties are to be
+     *                       serialized.
+     * @param session        the session to be used for resolving namespace
+     *                       mappings
      * @param contentHandler the content handler to feed the SAX events to
      */
     public DocViewSAXEventGenerator(NodeImpl node, boolean noRecurse,
@@ -145,7 +143,8 @@
                     attrName = propName.toJCRName(session.getNamespaceResolver());
                 } catch (NoPrefixDeclaredException npde) {
                     // should never get here...
-                    String msg = "internal error: encountered unregistered namespace";
+                    String msg =
+                            "internal error: encountered unregistered namespace";
                     log.debug(msg);
                     throw new RepositoryException(msg, npde);
                 }
@@ -164,43 +163,15 @@
                         // use space as delimiter for multi-valued properties
                         attrValue.append(" ");
                     }
-                    Value val = vals[i];
-                    String textVal;
-                    if (prop.getType() == PropertyType.BINARY) {
-                        // binary data, base64 encoding required
-                        InputStream in = val.getStream();
-                        StringWriter writer = new StringWriter();
-                        try {
-                            Base64.encode(in, writer);
-                            // no need to close StringWriter
-                            //writer.close();
-                        } catch (IOException ioe) {
-                            // check if the exception wraps a SAXException
-                            Throwable t = ioe.getCause();
-                            if (t != null && t instanceof SAXException) {
-                                throw (SAXException) t;
-                            } else {
-                                throw new SAXException(ioe);
-                            }
-                        } finally {
-                            try {
-                                in.close();
-                            } catch (IOException e) {
-                                // ignore
-                            }
-                        }
-                        textVal = writer.toString();
-                    } else {
-                        textVal = val.getString();
-                    }
-                    // enocde blanks in value
-                    textVal = Text.replace(textVal, " ", "_x0020_");
-                    attrValue.append(textVal);
+                    attrValue.append(ValueHelper.serialize(vals[i], true));
                 }
-                attrs.addAttribute(propName.getNamespaceURI(), propName.getLocalName(), attrName, CDATA_TYPE, attrValue.toString());
+                attrs.addAttribute(propName.getNamespaceURI(),
+                        propName.getLocalName(), attrName, CDATA_TYPE,
+                        attrValue.toString());
             }
             // start element (node)
-            contentHandler.startElement(name.getNamespaceURI(), name.getLocalName(), elemName, attrs);
+            contentHandler.startElement(name.getNamespaceURI(),
+                    name.getLocalName(), elemName, attrs);
         }
     }
 
@@ -232,7 +203,8 @@
         }
 
         // end element (node)
-        contentHandler.endElement(name.getNamespaceURI(), name.getLocalName(), elemName);
+        contentHandler.endElement(name.getNamespaceURI(), name.getLocalName(),
+                elemName);
     }
 
     /**

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/SysViewImportHandler.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/SysViewImportHandler.java?view=diff&r1=159685&r2=159686
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/SysViewImportHandler.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/SysViewImportHandler.java Fri Apr  1 05:40:06 2005
@@ -23,7 +23,7 @@
 import org.apache.jackrabbit.core.NamespaceResolver;
 import org.apache.jackrabbit.core.QName;
 import org.apache.jackrabbit.core.UnknownPrefixException;
-import org.apache.jackrabbit.core.util.Base64;
+import org.apache.jackrabbit.core.util.ValueHelper;
 import org.apache.log4j.Logger;
 import org.xml.sax.Attributes;
 import org.xml.sax.SAXException;
@@ -32,9 +32,6 @@
 import javax.jcr.InvalidSerializedDataException;
 import javax.jcr.PropertyType;
 import javax.jcr.RepositoryException;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Stack;
 
@@ -285,20 +282,9 @@
                     InternalValue[] vals = new InternalValue[currentPropValues.size()];
                     for (int i = 0; i < currentPropValues.size(); i++) {
                         String value = (String) currentPropValues.get(i);
-                        if (currentPropType == PropertyType.BINARY) {
-                            // base64 encoded binary value
-                            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-                            try {
-                                Base64.decode(value, baos);
-                                baos.close();
-                                vals[i] = InternalValue.create(new ByteArrayInputStream(baos.toByteArray()));
-                            } catch (IOException ioe) {
-                                throw new SAXException("failed to decode binary value", ioe);
-                            }
-                        } else {
-                            vals[i] = InternalValue.create(value,
-                                    currentPropType, nsContext);
-                        }
+                        vals[i] = InternalValue.create(
+                                ValueHelper.deserialize(value, currentPropType,
+                                        false), nsContext);
                     }
                     Importer.PropInfo prop = new Importer.PropInfo();
                     prop.setName(currentPropName);

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/SysViewSAXEventGenerator.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/SysViewSAXEventGenerator.java?view=diff&r1=159685&r2=159686
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/SysViewSAXEventGenerator.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/SysViewSAXEventGenerator.java Fri Apr  1 05:40:06 2005
@@ -21,7 +21,7 @@
 import org.apache.jackrabbit.core.PropertyImpl;
 import org.apache.jackrabbit.core.QName;
 import org.apache.jackrabbit.core.SessionImpl;
-import org.apache.jackrabbit.core.util.Base64;
+import org.apache.jackrabbit.core.util.ValueHelper;
 import org.apache.log4j.Logger;
 import org.xml.sax.ContentHandler;
 import org.xml.sax.SAXException;
@@ -31,7 +31,6 @@
 import javax.jcr.RepositoryException;
 import javax.jcr.Value;
 import java.io.IOException;
-import java.io.InputStream;
 import java.io.Writer;
 
 /**
@@ -197,47 +196,36 @@
                     PREFIXED_VALUE_ELEMENT, new AttributesImpl());
 
             // characters
-            if (prop.getType() == PropertyType.BINARY) {
-                // binary data, base64 encoding required
-                InputStream in = val.getStream();
-                Writer writer = new Writer() {
-                    public void close() /*throws IOException*/ {
-                    }
+            Writer writer = new Writer() {
+                public void close() /*throws IOException*/ {
+                }
 
-                    public void flush() /*throws IOException*/ {
-                    }
+                public void flush() /*throws IOException*/ {
+                }
 
-                    public void write(char[] cbuf, int off, int len) throws IOException {
-                        try {
-                            contentHandler.characters(cbuf, off, len);
-                        } catch (SAXException se) {
-                            throw new IOException(se.toString());
-                        }
-                    }
-                };
-                try {
-                    Base64.encode(in, writer);
-                    // no need to close our Writer implementation
-                    //writer.close();
-                } catch (IOException ioe) {
-                    // check if the exception wraps a SAXException
-                    Throwable t = ioe.getCause();
-                    if (t != null && t instanceof SAXException) {
-                        throw (SAXException) t;
-                    } else {
-                        throw new SAXException(ioe);
-                    }
-                } finally {
+                public void write(char[] cbuf, int off, int len) throws IOException {
                     try {
-                        in.close();
-                    } catch (IOException e) {
-                        // ignore
+                        contentHandler.characters(cbuf, off, len);
+                    } catch (SAXException se) {
+                        throw new IOException(se.toString());
                     }
                 }
-            } else {
-                char[] chars = val.getString().toCharArray();
-                contentHandler.characters(chars, 0, chars.length);
+            };
+            try {
+                ValueHelper.serialize(val, false, writer);
+                // no need to close our Writer implementation
+                //writer.close();
+            } catch (IOException ioe) {
+                // check if the exception wraps a SAXException
+                // (see Writer.write(char[], int, int) above)
+                Throwable t = ioe.getCause();
+                if (t != null && t instanceof SAXException) {
+                    throw (SAXException) t;
+                } else {
+                    throw new SAXException(ioe);
+                }
             }
+
             // end value element
             contentHandler.endElement(NS_SV_URI, VALUE_ELEMENT,
                     PREFIXED_VALUE_ELEMENT);