You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ws.apache.org by ve...@apache.org on 2022/11/12 17:51:40 UTC

[ws-axiom] branch master updated: [AXIOM-506] Migrate Base64Utils to Blob

This is an automated email from the ASF dual-hosted git repository.

veithen pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ws-axiom.git


The following commit(s) were added to refs/heads/master by this push:
     new 3c9b75ef4 [AXIOM-506] Migrate Base64Utils to Blob
3c9b75ef4 is described below

commit 3c9b75ef4765c9a00a3da729655ef65fca07ff19
Author: Andreas Veithen <an...@gmail.com>
AuthorDate: Sat Nov 12 17:51:31 2022 +0000

    [AXIOM-506] Migrate Base64Utils to Blob
    
    To make this work, refine the contract of the Blob.getSize() method.
---
 axiom-api/pom.xml                                  |  4 ---
 .../axiom/util/activation/DataHandlerBlob.java     | 14 +--------
 .../org/apache/axiom/util/base64/Base64Utils.java  | 36 ++++++++++------------
 .../src/main/java/org/apache/axiom/blob/Blob.java  | 14 +++++++--
 .../org/apache/axiom/om/impl/intf/TextContent.java |  6 ++--
 5 files changed, 31 insertions(+), 43 deletions(-)

diff --git a/axiom-api/pom.xml b/axiom-api/pom.xml
index 8fb397a48..52b9828f8 100644
--- a/axiom-api/pom.xml
+++ b/axiom-api/pom.xml
@@ -277,10 +277,6 @@
                                 </layer>
                             </layers>
                             <ignore>
-                                <!-- TODO(AXIOM-506) -->
-                                org.apache.axiom.util.base64.Base64Utils -&gt; org.apache.axiom.util.activation.DataSourceUtils,
-                                org.apache.axiom.util.base64.Base64Utils -&gt; javax.activation.DataSource,
-                                org.apache.axiom.util.base64.Base64Utils -&gt; javax.activation.DataHandler,
                                 <!-- o.a.a.soap should be a layer on top of o.a.a.om -->
                                 org.apache.axiom.om.OMAbstractFactory -&gt; org.apache.axiom.soap.SOAPFactory,
                                 org.apache.axiom.om.OMMetaFactory -&gt; org.apache.axiom.soap.SOAPFactory,
diff --git a/axiom-api/src/main/java/org/apache/axiom/util/activation/DataHandlerBlob.java b/axiom-api/src/main/java/org/apache/axiom/util/activation/DataHandlerBlob.java
index ae6c48ced..60edc401f 100644
--- a/axiom-api/src/main/java/org/apache/axiom/util/activation/DataHandlerBlob.java
+++ b/axiom-api/src/main/java/org/apache/axiom/util/activation/DataHandlerBlob.java
@@ -23,7 +23,6 @@ import java.io.InputStream;
 import java.io.OutputStream;
 
 import javax.activation.DataHandler;
-import javax.activation.DataSource;
 
 import org.apache.axiom.blob.Blob;
 import org.apache.axiom.ext.io.StreamCopyException;
@@ -56,17 +55,6 @@ final class DataHandlerBlob implements Blob {
 
     @Override
     public long getSize() {
-        DataSource ds = dataHandler.getDataSource();
-        long size = DataSourceUtils.getSize(ds);
-        if (size != -1) {
-            return size;
-        }
-        CountingOutputStream out = new CountingOutputStream();
-        try {
-            dataHandler.writeTo(out);
-        } catch (IOException ex) {
-            throw new RuntimeException(ex);
-        }
-        return out.getSize();
+        return DataSourceUtils.getSize(dataHandler.getDataSource());
     }
 }
diff --git a/axiom-api/src/main/java/org/apache/axiom/util/base64/Base64Utils.java b/axiom-api/src/main/java/org/apache/axiom/util/base64/Base64Utils.java
index 3f0af8e69..17ec7deb8 100644
--- a/axiom-api/src/main/java/org/apache/axiom/util/base64/Base64Utils.java
+++ b/axiom-api/src/main/java/org/apache/axiom/util/base64/Base64Utils.java
@@ -23,9 +23,7 @@ import java.io.IOException;
 import java.io.OutputStream;
 import java.io.Writer;
 
-import javax.activation.DataHandler;
-
-import org.apache.axiom.util.activation.DataSourceUtils;
+import org.apache.axiom.blob.Blob;
 
 /**
  * Contains utility methods to work with base64 encoded data.
@@ -35,48 +33,46 @@ public class Base64Utils {
         return (unencodedSize+2) / 3 * 4;
     }
     
-    private static int getBufferSize(DataHandler dh) {
-        long size = DataSourceUtils.getSize(dh.getDataSource());
+    private static int getBufferSize(Blob blob) {
+        long size = blob.getSize();
         if (size == -1) {
             // Use a reasonable default capacity.
             return 4096;
         } else if (size > Integer.MAX_VALUE) {
-            throw new IllegalArgumentException("DataHandler is too large to encode to string");
+            throw new IllegalArgumentException("Blob is too large to encode to string");
         } else {
             return getEncodedSize((int)size);
         }
     }
     
     /**
-     * Get a base64 representation of the content of a given {@link DataHandler} as a string.
+     * Get a base64 representation of the content of a given {@link Blob} as a string.
      * This method will try to carry out the encoding operation in the most efficient way.
      * 
-     * @param dh the data handler with the content to encode
+     * @param blob the blob with the content to encode
      * @return the base64 encoded content
-     * @throws IOException if an I/O error occurs when reading the content of the data handler
+     * @throws IOException if an I/O error occurs when reading the content of the blob
      */
-    public static String encode(DataHandler dh) throws IOException {
-        StringBuilder buffer = new StringBuilder(getBufferSize(dh));
+    public static String encode(Blob blob) throws IOException {
+        StringBuilder buffer = new StringBuilder(getBufferSize(blob));
         Base64EncodingStringBufferOutputStream out = new Base64EncodingStringBufferOutputStream(buffer);
-        // Always prefer writeTo, because getInputStream will create a thread and a pipe if
-        // the DataHandler was constructed using an object instead of a DataSource
-        dh.writeTo(out);
+        blob.writeTo(out);
         out.complete();
         return buffer.toString();
     }
 
     /**
-     * Get a base64 representation of the content of a given {@link DataHandler} as a char array.
+     * Get a base64 representation of the content of a given {@link Blob} as a char array.
      * This method will try to carry out the encoding operation in the most efficient way.
      * 
-     * @param dh the data handler with the content to encode
+     * @param blob the blob with the content to encode
      * @return the base64 encoded content
-     * @throws IOException if an I/O error occurs when reading the content of the data handler
+     * @throws IOException if an I/O error occurs when reading the content of the blob
      */
-    public static char[] encodeToCharArray(DataHandler dh) throws IOException {
-        NoCopyCharArrayWriter buffer = new NoCopyCharArrayWriter(getBufferSize(dh));
+    public static char[] encodeToCharArray(Blob blob) throws IOException {
+        NoCopyCharArrayWriter buffer = new NoCopyCharArrayWriter(getBufferSize(blob));
         Base64EncodingWriterOutputStream out = new Base64EncodingWriterOutputStream(buffer);
-        dh.writeTo(out);
+        blob.writeTo(out);
         out.complete();
         return buffer.toCharArray();
     }
diff --git a/components/blob/src/main/java/org/apache/axiom/blob/Blob.java b/components/blob/src/main/java/org/apache/axiom/blob/Blob.java
index 825a5a69f..5b3213a38 100644
--- a/components/blob/src/main/java/org/apache/axiom/blob/Blob.java
+++ b/components/blob/src/main/java/org/apache/axiom/blob/Blob.java
@@ -58,9 +58,19 @@ public interface Blob {
     void writeTo(OutputStream out) throws StreamCopyException;
 
     /**
-     * Get the size of the blob.
+     * Get the (approximate) size of the blob. Returns -1 if the size can't be determined without
+     * reading the entire blob (in which case the caller may want to use {@link
+     * #writeTo(OutputStream)} with an {@link OutputStream} that counts the number of bytes to
+     * determine the size). The method may choose to return a value based on an estimation. This may
+     * be the case e.g. if reading the data involves a decoding operation, and the length of the
+     * resulting stream can't be determined precisely without performing the decoding operation.
      *
-     * @return the number of bytes in the blob
+     * <p>When reading the actual data, the code should always read until the end of the stream is
+     * reached (as indicated by the return value of the {@code read} methods of the {@link
+     * InputStream} class). It must be prepared to reach the end of the stream after a number of
+     * bytes that is lower or higher than the value returned by this method.
+     *
+     * @return the number of bytes in the blob, or -1 if the size is not known
      */
     long getSize();
 }
diff --git a/mixins/om-mixins/src/main/java/org/apache/axiom/om/impl/intf/TextContent.java b/mixins/om-mixins/src/main/java/org/apache/axiom/om/impl/intf/TextContent.java
index 07c9542e4..e572f5e02 100644
--- a/mixins/om-mixins/src/main/java/org/apache/axiom/om/impl/intf/TextContent.java
+++ b/mixins/om-mixins/src/main/java/org/apache/axiom/om/impl/intf/TextContent.java
@@ -137,8 +137,7 @@ public final class TextContent implements CloneableCharacterData {
     public String toString() {
         if (blobObject != null) {
             try {
-                // TODO(AXIOM-506): avoid conversion here
-                return Base64Utils.encode(DataHandlerUtils.toDataHandler(getBlob()));
+                return Base64Utils.encode(getBlob());
             } catch (Exception e) {
                 throw new OMException(e);
             }
@@ -150,8 +149,7 @@ public final class TextContent implements CloneableCharacterData {
     public char[] toCharArray() {
         if (blobObject != null) {
             try {
-                // TODO(AXIOM-506): avoid conversion here
-                return Base64Utils.encodeToCharArray(DataHandlerUtils.toDataHandler(getBlob()));
+                return Base64Utils.encodeToCharArray(getBlob());
             } catch (IOException ex) {
                 throw new OMException(ex);
             }