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/04 00:12:08 UTC

[ws-axiom] branch master updated: Introduce a class to represent content transfer encodings

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 12b0cdc45 Introduce a class to represent content transfer encodings
12b0cdc45 is described below

commit 12b0cdc4517a12e1cfe4ae77e108f328aadd5cc4
Author: Andreas Veithen <an...@gmail.com>
AuthorDate: Fri Nov 4 00:11:52 2022 +0000

    Introduce a class to represent content transfer encodings
---
 .../apache/axiom/mime/ContentTransferEncoding.java | 78 ++++++++++++++++++++++
 .../org/apache/axiom/mime/MultipartBodyWriter.java | 24 +++----
 .../apache/axiom/om/impl/OMMultipartWriter.java    | 32 ++++++---
 .../apache/axiom/mime/MultipartBodyWriterTest.java |  8 +--
 4 files changed, 111 insertions(+), 31 deletions(-)

diff --git a/axiom-api/src/main/java/org/apache/axiom/mime/ContentTransferEncoding.java b/axiom-api/src/main/java/org/apache/axiom/mime/ContentTransferEncoding.java
new file mode 100644
index 000000000..bc393218f
--- /dev/null
+++ b/axiom-api/src/main/java/org/apache/axiom/mime/ContentTransferEncoding.java
@@ -0,0 +1,78 @@
+/*
+ * 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.mime;
+
+import java.io.OutputStream;
+
+import org.apache.axiom.util.base64.Base64EncodingOutputStream;
+
+/**
+ * Represents a MIME content transfer encoding.
+ */
+public abstract class ContentTransferEncoding {
+    private static class Identity extends ContentTransferEncoding {
+        Identity(String name) {
+            super(name);
+        }
+
+        @Override
+        public OutputStream encode(OutputStream out) {
+            return out;
+        }
+    }
+
+    /**
+     * The {@code 8bit} content transfer encoding.
+     */
+    public static final ContentTransferEncoding EIGHT_BIT = new Identity("8bit");
+
+    /**
+     * The {@code binary} content transfer encoding.
+     */
+    public static final ContentTransferEncoding BINARY = new Identity("binary");
+
+    /**
+     * The {@code base64} content transfer encoding.
+     */
+    public static final ContentTransferEncoding BASE64 = new ContentTransferEncoding("base64") {
+        @Override
+        public OutputStream encode(OutputStream out) {
+            return new Base64EncodingOutputStream(out);
+        }
+    };
+
+    private final String name;
+
+    public ContentTransferEncoding(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public final String toString() {
+        return name;
+    }
+
+    /**
+     * Wrap the given output stream to apply the content transfer encoding.
+     * 
+     * @param out the output stream to wrap
+     * @return the wrapped output stream
+     */
+    public abstract OutputStream encode(OutputStream out);
+}
diff --git a/axiom-api/src/main/java/org/apache/axiom/mime/MultipartBodyWriter.java b/axiom-api/src/main/java/org/apache/axiom/mime/MultipartBodyWriter.java
index 2564fe225..73ed4b746 100644
--- a/axiom-api/src/main/java/org/apache/axiom/mime/MultipartBodyWriter.java
+++ b/axiom-api/src/main/java/org/apache/axiom/mime/MultipartBodyWriter.java
@@ -25,12 +25,11 @@ import java.util.List;
 import javax.activation.DataHandler;
 
 import org.apache.axiom.util.UIDGenerator;
-import org.apache.axiom.util.base64.Base64EncodingOutputStream;
 
 /**
  * Writes a MIME multipart body as used by XOP/MTOM and SOAP with Attachments. MIME parts are
- * written using {@link #writePart(String, String, String, List)} or
- * {@link #writePart(DataHandler, String, String, List)}. Calls to both methods can be mixed, i.e.
+ * written using {@link #writePart(String, ContentTransferEncoding, String, List)} or
+ * {@link #writePart(DataHandler, ContentTransferEncoding, String, List)}. Calls to both methods can be mixed, i.e.
  * it is not required to use the same method for all MIME parts. Instead, the caller should choose
  * the most convenient method for each part (depending on the form in which the content is
  * available). After all parts have been written, {@link #complete()} must be called to write the
@@ -40,9 +39,8 @@ import org.apache.axiom.util.base64.Base64EncodingOutputStream;
  * arguments of the two write methods:
  * <ul>
  * <li>The content transfer encoding specified by the {@code contentTransferEncoding} argument is
- * applied by the write method; the caller only provides the unencoded data. At least {@code binary}
- * and {@code base64} are supported. If the specified encoding is not supported, the write methods
- * may use an alternative one. In any case, the implementation ensures that the MIME part has a
+ * applied by the write method; the caller only provides the unencoded data. The implementation
+ * ensures that the MIME part has a
  * {@code Content-Transfer-Encoding} header appropriate for the applied encoding.</li>
  * <li>The content ID passed as argument is always the raw ID (without the angle brackets). The
  * implementation translates this into a properly formatted {@code Content-ID} header.</li>
@@ -133,14 +131,8 @@ public final class MultipartBodyWriter {
      * @throws IOException
      *             if an I/O error occurs when writing to the underlying stream
      */
-    public OutputStream writePart(String contentType, String contentTransferEncoding,
+    public OutputStream writePart(String contentType, ContentTransferEncoding contentTransferEncoding,
             String contentID, List<Header> extraHeaders) throws IOException {
-        OutputStream partOut = new PartOutputStream(out);
-        // We support no content transfer encodings other than 8bit, binary and base64.
-        if (!contentTransferEncoding.equals("8bit") && !contentTransferEncoding.equals("binary")) {
-            partOut = new Base64EncodingOutputStream(partOut);
-            contentTransferEncoding = "base64";
-        }
         writeAscii("--");
         writeAscii(boundary);
         // RFC 2046 explicitly says that Content-Type is not mandatory (and defaults to
@@ -150,7 +142,7 @@ public final class MultipartBodyWriter {
             writeAscii(contentType);
         }
         writeAscii("\r\nContent-Transfer-Encoding: ");
-        writeAscii(contentTransferEncoding);
+        writeAscii(contentTransferEncoding.toString());
         if (contentID != null) {
             writeAscii("\r\nContent-ID: <");
             writeAscii(contentID);
@@ -165,7 +157,7 @@ public final class MultipartBodyWriter {
             }
         }
         writeAscii("\r\n\r\n");
-        return partOut;
+        return contentTransferEncoding.encode(new PartOutputStream(out));
     }
     
     /**
@@ -184,7 +176,7 @@ public final class MultipartBodyWriter {
      * @throws IOException
      *             if an I/O error occurs when writing the part to the underlying stream
      */
-    public void writePart(DataHandler dataHandler, String contentTransferEncoding, String contentID, List<Header> extraHeaders)
+    public void writePart(DataHandler dataHandler, ContentTransferEncoding contentTransferEncoding, String contentID, List<Header> extraHeaders)
             throws IOException {
         OutputStream partOutputStream = writePart(dataHandler.getContentType(), contentTransferEncoding, contentID, extraHeaders);
         dataHandler.writeTo(partOutputStream);
diff --git a/axiom-api/src/main/java/org/apache/axiom/om/impl/OMMultipartWriter.java b/axiom-api/src/main/java/org/apache/axiom/om/impl/OMMultipartWriter.java
index 61874ecba..f214de7a4 100644
--- a/axiom-api/src/main/java/org/apache/axiom/om/impl/OMMultipartWriter.java
+++ b/axiom-api/src/main/java/org/apache/axiom/om/impl/OMMultipartWriter.java
@@ -27,6 +27,7 @@ import java.util.List;
 import javax.activation.DataHandler;
 
 import org.apache.axiom.attachments.ConfigurableDataHandler;
+import org.apache.axiom.mime.ContentTransferEncoding;
 import org.apache.axiom.mime.ContentType;
 import org.apache.axiom.mime.Header;
 import org.apache.axiom.mime.MultipartBodyWriter;
@@ -75,11 +76,11 @@ public class OMMultipartWriter {
         }
     }
 
-    private String getContentTransferEncoding(String contentType) {
+    private ContentTransferEncoding getContentTransferEncoding(String contentType) {
         if (useCTEBase64 && !isTextual(contentType)) {
-            return "base64";
+            return ContentTransferEncoding.BASE64;
         } else {
-            return "binary";
+            return ContentTransferEncoding.BINARY;
         }
     }
     
@@ -95,7 +96,7 @@ public class OMMultipartWriter {
 
     /**
      * Start writing the root part of the MIME package. This method delegates to
-     * {@link MultipartBodyWriter#writePart(String, String, String, List)}, but computes the content type,
+     * {@link MultipartBodyWriter#writePart(String, ContentTransferEncoding, String, List)}, but computes the content type,
      * content transfer encoding and content ID from the {@link OMOutputFormat}.
      * 
      * @return an output stream to write the content of the MIME part
@@ -103,12 +104,12 @@ public class OMMultipartWriter {
      *             if an I/O error occurs when writing to the underlying stream
      */
     public OutputStream writeRootPart() throws IOException {
-        return writer.writePart(rootPartContentType, "binary", format.getRootContentId(), null);
+        return writer.writePart(rootPartContentType, ContentTransferEncoding.BINARY, format.getRootContentId(), null);
     }
 
     /**
      * Start writing an attachment part of the MIME package. This method delegates to
-     * {@link MultipartBodyWriter#writePart(String, String, String, List)}, but computes the content transfer
+     * {@link MultipartBodyWriter#writePart(String, ContentTransferEncoding, String, List)}, but computes the content transfer
      * encoding based on the content type and the {@link OMOutputFormat}.
      * 
      * @param contentType
@@ -125,7 +126,7 @@ public class OMMultipartWriter {
     
     /**
      * Start writing an attachment part of the MIME package. This method delegates to
-     * {@link MultipartBodyWriter#writePart(String, String, String, List)}, but computes the content
+     * {@link MultipartBodyWriter#writePart(String, ContentTransferEncoding, String, List)}, but computes the content
      * transfer encoding based on the content type and the {@link OMOutputFormat}.
      * 
      * @param contentType
@@ -144,7 +145,7 @@ public class OMMultipartWriter {
     
     /**
      * Write a MIME part. This method delegates to
-     * {@link MultipartBodyWriter#writePart(DataHandler, String, String, List)}, but computes the
+     * {@link MultipartBodyWriter#writePart(DataHandler, ContentTransferEncoding, String, List)}, but computes the
      * appropriate content transfer encoding from the {@link OMOutputFormat}.
      * 
      * @param dataHandler
@@ -157,9 +158,18 @@ public class OMMultipartWriter {
      *             if an I/O error occurs when writing the part to the underlying stream
      */
     public void writePart(DataHandler dataHandler, String contentID, List<Header> extraHeaders) throws IOException {
-        String contentTransferEncoding = null;
+        ContentTransferEncoding contentTransferEncoding = null;
         if (dataHandler instanceof ConfigurableDataHandler) {
-            contentTransferEncoding = ((ConfigurableDataHandler)dataHandler).getTransferEncoding();
+            switch (((ConfigurableDataHandler)dataHandler).getTransferEncoding()) {
+                case "8bit":
+                    contentTransferEncoding = ContentTransferEncoding.EIGHT_BIT;
+                    break;
+                case "binary":
+                    contentTransferEncoding = ContentTransferEncoding.BINARY;
+                    break;
+                default:
+                    contentTransferEncoding = ContentTransferEncoding.BASE64;
+            }
         }
         if (contentTransferEncoding == null) {
             contentTransferEncoding = getContentTransferEncoding(dataHandler.getContentType());
@@ -169,7 +179,7 @@ public class OMMultipartWriter {
     
     /**
      * Write a MIME part. This method delegates to
-     * {@link MultipartBodyWriter#writePart(DataHandler, String, String, List)}, but computes the appropriate
+     * {@link MultipartBodyWriter#writePart(DataHandler, ContentTransferEncoding, String, List)}, but computes the appropriate
      * content transfer encoding from the {@link OMOutputFormat}.
      * 
      * @param dataHandler
diff --git a/axiom-api/src/test/java/org/apache/axiom/mime/MultipartBodyWriterTest.java b/axiom-api/src/test/java/org/apache/axiom/mime/MultipartBodyWriterTest.java
index 6ce9ef2cb..7096df03d 100644
--- a/axiom-api/src/test/java/org/apache/axiom/mime/MultipartBodyWriterTest.java
+++ b/axiom-api/src/test/java/org/apache/axiom/mime/MultipartBodyWriterTest.java
@@ -32,7 +32,7 @@ import org.apache.axiom.util.UIDGenerator;
 import junit.framework.TestCase;
 
 public class MultipartBodyWriterTest extends TestCase {
-    private void test(String contentTransferEncoding) throws Exception {
+    private void test(ContentTransferEncoding contentTransferEncoding) throws Exception {
         Random random = new Random();
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         MultipartBodyWriter mpw = new MultipartBodyWriter(baos, UIDGenerator.generateMimeBoundary());
@@ -46,17 +46,17 @@ public class MultipartBodyWriterTest extends TestCase {
         MimeMultipart mp = new MimeMultipart(new ByteArrayDataSource(baos.toByteArray()));
         assertEquals(1, mp.getCount());
         MimeBodyPart bp = (MimeBodyPart)mp.getBodyPart(0);
-        assertEquals(contentTransferEncoding, bp.getHeader("Content-Transfer-Encoding")[0]);
+        assertEquals(contentTransferEncoding.toString(), bp.getHeader("Content-Transfer-Encoding")[0]);
         baos.reset(); 
         bp.getDataHandler().writeTo(baos);
         assertTrue(Arrays.equals(content, baos.toByteArray()));
     }
     
     public void testBinary() throws Exception {
-        test("binary");
+        test(ContentTransferEncoding.BINARY);
     }
     
     public void testBase64() throws Exception {
-        test("base64");
+        test(ContentTransferEncoding.BASE64);
     }
 }