Repository: sendgrid/sendgrid-java (java)

Issue:
attachments - Support for InputStream?
In version 3, any plans to update attachments to support InputStream instead of File?  Our system creates PDF on the fly, never saving to file system.  Works in your version 2...need this to upgrade.

Thanks!


Pull request:
Adds an attachment builder that supports InputStream content.
Fixes #134.

Adds an attachment builder class that helps creating content from InputStream as well as simple strings.  


Patch:
diff --git a/src/main/java/com/sendgrid/helpers/mail/objects/Attachments.java b/src/main/java/com/sendgrid/helpers/mail/objects/Attachments.java
index 46c779f..9323b83 100644
--- a/src/main/java/com/sendgrid/helpers/mail/objects/Attachments.java
+++ b/src/main/java/com/sendgrid/helpers/mail/objects/Attachments.java
@@ -1,8 +1,12 @@
 package com.sendgrid;
 
+import com.fasterxml.jackson.annotation.JsonIgnoreType;
 import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.annotation.JsonInclude.Include;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import org.apache.commons.codec.binary.Base64;
+
+import java.io.*;
 
 @JsonInclude(Include.NON_DEFAULT)
 public class Attachments {
@@ -56,4 +60,81 @@ public class Attachments {
   public void setContentId(String contentId) {
     this.contentId = contentId;
   }
+
+  @JsonIgnoreType
+  public static class Builder {
+
+    private static final int BYTE_BUFFER_SIZE = 4096;
+
+    private String fileName;
+    private String content;
+    private String type;
+    private String disposition;
+    private String contentId;
+
+    public Builder(String fileName, InputStream content) {
+      if (fileName == null) {
+        throw new IllegalArgumentException("File name mustn't be null");
+      }
+
+      if (content == null) {
+        throw new IllegalArgumentException("Content mustn't be null");
+      }
+
+      this.fileName = fileName;
+      this.content = encodeToBase64(content);
+    }
+
+    public Builder(String fileName, String content) {
+      if (fileName == null) {
+        throw new IllegalArgumentException("File name mustn't be null");
+      }
+
+      if (content == null) {
+        throw new IllegalArgumentException("Content mustn't be null");
+      }
+
+      this.fileName = fileName;
+      this.content = content;
+    }
+
+    private String encodeToBase64(InputStream content) {
+      int read = 0;
+      byte[] bytes = new byte[BYTE_BUFFER_SIZE];
+      try(ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
+        while ((read = content.read(bytes)) != -1) {
+          baos.write(bytes, 0, read);
+        }
+
+        return Base64.encodeBase64String(baos.toByteArray());
+      } catch (IOException e) {
+        throw new RuntimeException("Unable to convert content stream to base 64 encoded string", e);
+      }
+    }
+
+    public Builder withType(String type) {
+      this.type = type;
+      return this;
+    }
+
+    public Builder withDisposition(String disposition) {
+      this.disposition = disposition;
+      return this;
+    }
+
+    public Builder withContentId(String contentId) {
+      this.contentId = contentId;
+      return this;
+    }
+
+    public Attachments build() {
+      Attachments attachments = new Attachments();
+      attachments.setContent(content);
+      attachments.setFilename(fileName);
+      attachments.setDisposition(disposition);
+      attachments.setContentId(contentId);
+      attachments.setType(type);
+      return attachments;
+    }
+  }
 }


Test patch:
diff --git a/src/test/java/com/sendgrid/helpers/AttachmentBuilderTest.java b/src/test/java/com/sendgrid/helpers/AttachmentBuilderTest.java
new file mode 100644
index 0000000..824e814
--- /dev/null
+++ b/src/test/java/com/sendgrid/helpers/AttachmentBuilderTest.java
@@ -0,0 +1,49 @@
+package com.sendgrid.helpers;
+
+import com.sendgrid.Attachments;
+import org.apache.commons.codec.binary.Base64;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.nio.charset.Charset;
+
+public class AttachmentBuilderTest {
+
+    @Test
+    public void testCreateAttachments() {
+        String fileName = "book.txt";
+        String type = "text/plain";
+        String content = "This test checks if the builder works fine";
+        InputStream contentStream = new ByteArrayInputStream(content.getBytes(Charset.forName("UTF-8")));
+        String contentId = "someId";
+        String dispositon = "someDisposition";
+
+        Attachments attachments = new Attachments.Builder(fileName, contentStream)
+                .withType(type)
+                .withContentId(contentId)
+                .withDisposition(dispositon)
+                .build();
+
+        Assert.assertEquals(attachments.getType(), type);
+        Assert.assertEquals(attachments.getFilename(), fileName);
+        Assert.assertEquals(attachments.getContentId(), contentId);
+        Assert.assertEquals(attachments.getDisposition(), dispositon);
+        Assert.assertEquals(attachments.getContent(), Base64.encodeBase64String(content.getBytes(Charset.forName("UTF-8"))));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testCreateAttachmentsMissingRequiredFileNameParam() {
+        String content = "This test checks if the builder works fine";
+        InputStream contentStream = new ByteArrayInputStream(content.getBytes(Charset.forName("UTF-8")));
+        Attachments attachments = new Attachments.Builder(null, contentStream).build();
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testCreateAttachmentsMissingRequiredContentParam() {
+        String type = "text";
+        String content = null;
+        Attachments attachments = new Attachments.Builder(type, content).build();
+    }
+}