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 <andreas.veit...@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 -> org.apache.axiom.util.activation.DataSourceUtils, - org.apache.axiom.util.base64.Base64Utils -> javax.activation.DataSource, - org.apache.axiom.util.base64.Base64Utils -> javax.activation.DataHandler, <!-- o.a.a.soap should be a layer on top of o.a.a.om --> org.apache.axiom.om.OMAbstractFactory -> org.apache.axiom.soap.SOAPFactory, org.apache.axiom.om.OMMetaFactory -> 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); }