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/10/31 23:08:19 UTC
[ws-axiom] branch master updated: [AXIOM-506] Add code to convert between Blob and DataHandler
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 21210fa65 [AXIOM-506] Add code to convert between Blob and DataHandler
21210fa65 is described below
commit 21210fa65c0559051e08ecf887275830bbb5cd19
Author: Andreas Veithen <an...@gmail.com>
AuthorDate: Mon Oct 31 23:08:08 2022 +0000
[AXIOM-506] Add code to convert between Blob and DataHandler
---
.../axiom/util/activation/BlobDataSource.java | 5 ++
...OutputStream.java => CountingOutputStream.java} | 18 ++++--
.../axiom/util/activation/DataHandlerBlob.java | 72 ++++++++++++++++++++++
.../axiom/util/activation/DataHandlerUtils.java | 33 +++++++++-
.../activation/SizeLimitExceededException.java | 2 +-
5 files changed, 123 insertions(+), 7 deletions(-)
diff --git a/axiom-api/src/main/java/org/apache/axiom/util/activation/BlobDataSource.java b/axiom-api/src/main/java/org/apache/axiom/util/activation/BlobDataSource.java
index 7f6468480..52f176a1e 100644
--- a/axiom-api/src/main/java/org/apache/axiom/util/activation/BlobDataSource.java
+++ b/axiom-api/src/main/java/org/apache/axiom/util/activation/BlobDataSource.java
@@ -29,6 +29,7 @@ import org.apache.axiom.ext.activation.SizeAwareDataSource;
/**
* Data source backed by a {@link Blob}.
*/
+// TODO(AXIOM-506): this should not be public
public class BlobDataSource implements SizeAwareDataSource {
private final Blob blob;
private final String contentType;
@@ -38,6 +39,10 @@ public class BlobDataSource implements SizeAwareDataSource {
this.contentType = contentType;
}
+ Blob getBlob() {
+ return blob;
+ }
+
@Override
public InputStream getInputStream() throws IOException {
return blob.getInputStream();
diff --git a/axiom-api/src/main/java/org/apache/axiom/util/activation/SizeLimitedOutputStream.java b/axiom-api/src/main/java/org/apache/axiom/util/activation/CountingOutputStream.java
similarity index 83%
rename from axiom-api/src/main/java/org/apache/axiom/util/activation/SizeLimitedOutputStream.java
rename to axiom-api/src/main/java/org/apache/axiom/util/activation/CountingOutputStream.java
index 8ecfce415..91e15fcb2 100644
--- a/axiom-api/src/main/java/org/apache/axiom/util/activation/SizeLimitedOutputStream.java
+++ b/axiom-api/src/main/java/org/apache/axiom/util/activation/CountingOutputStream.java
@@ -22,17 +22,21 @@ import java.io.IOException;
import java.io.OutputStream;
/**
- * An output stream that counts the number of bytes written to it and throws an exception when the
- * size exceeds a given limit.
+ * An output stream that counts the number of bytes written to it and optionally throws an exception
+ * when the size exceeds a given limit.
*/
-final class SizeLimitedOutputStream extends OutputStream {
+final class CountingOutputStream extends OutputStream {
private final long maxSize;
private long size;
- SizeLimitedOutputStream(long maxSize) {
+ CountingOutputStream(long maxSize) {
this.maxSize = maxSize;
}
+ CountingOutputStream() {
+ this(-1);
+ }
+
@Override
public void write(byte[] b, int off, int len) throws IOException {
size += len;
@@ -52,10 +56,14 @@ final class SizeLimitedOutputStream extends OutputStream {
}
private void checkSize() throws SizeLimitExceededException {
- if (size > maxSize) {
+ if (maxSize != -1 && size > maxSize) {
// Throw a cached exception instance to avoid the overhead of building the
// stack trace.
throw SizeLimitExceededException.INSTANCE;
}
}
+
+ long getSize() {
+ return size;
+ }
}
\ No newline at end of file
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
new file mode 100644
index 000000000..ae6c48ced
--- /dev/null
+++ b/axiom-api/src/main/java/org/apache/axiom/util/activation/DataHandlerBlob.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axiom.util.activation;
+
+import java.io.IOException;
+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;
+
+final class DataHandlerBlob implements Blob {
+ private final DataHandler dataHandler;
+
+ DataHandlerBlob(DataHandler dataHandler) {
+ this.dataHandler = dataHandler;
+ }
+
+ DataHandler getDataHandler() {
+ return dataHandler;
+ }
+
+ @Override
+ public InputStream getInputStream() throws IOException {
+ return dataHandler.getInputStream();
+ }
+
+ @Override
+ public void writeTo(OutputStream out) throws StreamCopyException {
+ try {
+ dataHandler.writeTo(out);
+ } catch (IOException ex) {
+ // TODO(AXIOM-506): maybe we can do some wrapping to determine the operation that failed
+ throw new StreamCopyException(StreamCopyException.WRITE, ex);
+ }
+ }
+
+ @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();
+ }
+}
diff --git a/axiom-api/src/main/java/org/apache/axiom/util/activation/DataHandlerUtils.java b/axiom-api/src/main/java/org/apache/axiom/util/activation/DataHandlerUtils.java
index 88da0f7bb..4b7e809ee 100644
--- a/axiom-api/src/main/java/org/apache/axiom/util/activation/DataHandlerUtils.java
+++ b/axiom-api/src/main/java/org/apache/axiom/util/activation/DataHandlerUtils.java
@@ -24,6 +24,8 @@ import java.io.OutputStream;
import javax.activation.DataHandler;
import javax.activation.DataSource;
+import org.apache.axiom.blob.Blob;
+
/**
* Contains utility methods to work with {@link DataHandler} objects.
*/
@@ -57,11 +59,40 @@ public final class DataHandlerUtils {
// getInputStream method. Obviously starting a new thread just to check the size of
// the data is an overhead that we should avoid.
try {
- dh.writeTo(new SizeLimitedOutputStream(limit));
+ dh.writeTo(new CountingOutputStream(limit));
return false;
} catch (SizeLimitExceededException ex) {
return true;
}
}
}
+
+ /**
+ * Get a {@link DataHandler} for the given {@link Blob}. If the blob was obtained from {@link
+ * #toBlob(DataHandler)}, the original {@link DataHandler} is returned.
+ *
+ * @param blob the {@link Blob} to convert
+ * @return a {@link DataHandler} representing the {@link Blob}
+ */
+ public static DataHandler toDataHandler(Blob blob) {
+ if (blob instanceof DataHandlerBlob) {
+ return ((DataHandlerBlob)blob).getDataHandler();
+ }
+ return new DataHandler(new BlobDataSource(blob, "application/octet-stream"));
+ }
+
+ /**
+ * Get a {@link Blob} for the given {@link DataHandler}. If the {@link DataHandler} was obtained from {@link
+ * #toDataHandler(Blob)}, the original {@link Blob} is returned.
+ *
+ * @param dh the {@link DataHandler} to convert
+ * @return a {@link Blob} representing the {@link DataHandler}
+ */
+ public static Blob toBlob(DataHandler dh) {
+ DataSource ds = dh.getDataSource();
+ if (ds instanceof BlobDataSource) {
+ return ((BlobDataSource)ds).getBlob();
+ }
+ return new DataHandlerBlob(dh);
+ }
}
diff --git a/axiom-api/src/main/java/org/apache/axiom/util/activation/SizeLimitExceededException.java b/axiom-api/src/main/java/org/apache/axiom/util/activation/SizeLimitExceededException.java
index a49539e55..945bce647 100644
--- a/axiom-api/src/main/java/org/apache/axiom/util/activation/SizeLimitExceededException.java
+++ b/axiom-api/src/main/java/org/apache/axiom/util/activation/SizeLimitExceededException.java
@@ -21,7 +21,7 @@ package org.apache.axiom.util.activation;
import java.io.IOException;
/**
- * Exception used by {@link SizeLimitedOutputStream} if the size limit has been exceeded.
+ * Exception used by {@link CountingOutputStream} if the size limit has been exceeded.
*/
final class SizeLimitExceededException extends IOException {
private static final long serialVersionUID = 1L;