package org.jboss.resteasy.test.providers.multipart.resource; import org.jboss.logging.Logger; import org.jboss.resteasy.annotations.providers.multipart.MultipartForm; import org.jboss.resteasy.annotations.providers.multipart.PartType; import org.jboss.resteasy.annotations.providers.multipart.XopWithMultipartRelated; import org.jboss.resteasy.plugins.providers.multipart.InputPart; import org.jboss.resteasy.plugins.providers.multipart.MultipartConstants; import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput; import org.jboss.resteasy.plugins.providers.multipart.MultipartInput; import org.jboss.resteasy.plugins.providers.multipart.MultipartRelatedInput; import org.junit.Assert; import javax.activation.DataHandler; import javax.mail.MessagingException; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMultipart; import javax.ws.rs.Consumes; import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlMimeType; import javax.xml.bind.annotation.XmlRootElement; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.StringWriter; import java.util.Iterator; import java.util.List; import java.util.Map; @Path("/mime") public class MimeMultipartProviderResource { public static class Form { @FormParam("bill") @PartType("application/xml") private MimeMultipartProviderCustomer bill; @FormParam("monica") @PartType("application/xml") private MimeMultipartProviderCustomer monica; public Form() { } public Form(final MimeMultipartProviderCustomer bill, final MimeMultipartProviderCustomer monica) { this.bill = bill; this.monica = monica; } public MimeMultipartProviderCustomer getBill() { return bill; } public MimeMultipartProviderCustomer getMonica() { return monica; } } @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public static class Xop { private MimeMultipartProviderCustomer bill; private MimeMultipartProviderCustomer monica; @XmlMimeType(MediaType.APPLICATION_OCTET_STREAM) private byte[] myBinary; @XmlMimeType(MediaType.APPLICATION_OCTET_STREAM) private DataHandler myDataHandler; public Xop() { } public Xop(final MimeMultipartProviderCustomer bill, final MimeMultipartProviderCustomer monica, final byte[] myBinary, final DataHandler myDataHandler) { this.bill = bill; this.monica = monica; this.myBinary = myBinary; this.myDataHandler = myDataHandler; } public MimeMultipartProviderCustomer getBill() { return bill; } public MimeMultipartProviderCustomer getMonica() { return monica; } public byte[] getMyBinary() { return myBinary; } public DataHandler getMyDataHandler() { return myDataHandler; } } public static class Form2 { @FormParam("submit-name") public String name; @FormParam("files") public byte[] file; } private static Logger logger = Logger.getLogger(MimeMultipartProviderResource.class); private static final String ERR_MULTIPART_PROPERTY = "Property from multipart is not correct"; private static final String ERR_MULTIPART_FORM = "Multipart form value is incorrect"; private static final String ERR_NUMBER = "The number of enclosed bodypart objects doesn't match to the expectation"; private static final String ERR_CUST_NULL = "The customer entity is not expected to be null"; private static final String ERR_VALUE = "Unexpected value"; @POST @Path("file/test") @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces("text/html") public String post(@MultipartForm Form2 form) { Assert.assertEquals(ERR_MULTIPART_FORM, "Bill", form.name.trim()); Assert.assertEquals(ERR_MULTIPART_FORM, "hello world", new String(form.file).trim()); return "hello world"; } @PUT @Consumes("multipart/form-data") @Produces("text/plain") public String putData(MimeMultipart multipart) { StringBuilder b = new StringBuilder("Count: "); try { b.append(multipart.getCount()); for (int i = 0; i < multipart.getCount(); i++) { try { logger.debug(multipart.getBodyPart(i).getContent().toString()); logger.debug("bytes available {0}" + multipart.getBodyPart(i).getInputStream().available()); } catch (IOException e) { // TODO Auto-generated catch block logger.info(e.getCause()); } } } catch (MessagingException e) { // TODO Auto-generated catch block logger.info(e.getCause()); } return b.toString(); } @PUT @Path("form") @Consumes("multipart/form-data") public void putMultipartFormData(MultipartFormDataInput multipart) throws IOException { Assert.assertEquals(ERR_NUMBER, 2, multipart.getParts().size()); Assert.assertTrue(ERR_MULTIPART_FORM, multipart.getFormDataMap().containsKey("bill")); Assert.assertTrue(ERR_MULTIPART_FORM, multipart.getFormDataMap().containsKey("monica")); logger.info(multipart.getFormDataMap().get("bill").get(0).getBodyAsString()); MimeMultipartProviderCustomer cust = multipart.getFormDataPart("bill", MimeMultipartProviderCustomer.class, null); Assert.assertNotNull(ERR_CUST_NULL, cust); Assert.assertEquals(ERR_MULTIPART_FORM, "bill", cust.getName()); cust = multipart.getFormDataPart("monica", MimeMultipartProviderCustomer.class, null); Assert.assertNotNull(ERR_CUST_NULL, cust); Assert.assertEquals(ERR_VALUE, "monica", cust.getName()); } @PUT @Path("related") @Consumes(MultipartConstants.MULTIPART_RELATED) public void putMultipartRelated(MultipartRelatedInput multipart) throws IOException { Assert.assertEquals(ERR_MULTIPART_PROPERTY, MultipartConstants.APPLICATION_XOP_XML, multipart.getType()); Assert.assertEquals(ERR_MULTIPART_PROPERTY, "<mymessage.xml@example.org>", multipart.getStart()); Assert.assertEquals(ERR_MULTIPART_PROPERTY, "text/xml", multipart.getStartInfo()); Assert.assertEquals(ERR_NUMBER, 3, multipart.getParts().size()); Iterator<InputPart> inputParts = multipart.getParts().iterator(); Assert.assertEquals(ERR_MULTIPART_PROPERTY, inputParts.next(), multipart.getRootPart()); InputPart rootPart = multipart.getRootPart(); Assert.assertEquals(ERR_MULTIPART_PROPERTY, "application", rootPart.getMediaType().getType()); Assert.assertEquals(ERR_MULTIPART_PROPERTY, "xop+xml", rootPart.getMediaType().getSubtype()); Assert.assertEquals(ERR_MULTIPART_PROPERTY, "UTF-8", rootPart.getMediaType().getParameters().get("charset")); Assert.assertEquals(ERR_MULTIPART_PROPERTY, "text/xml", rootPart.getMediaType().getParameters().get("type")); Assert.assertEquals(ERR_MULTIPART_PROPERTY, "<mymessage.xml@example.org>", rootPart.getHeaders().getFirst("Content-ID")); Assert.assertEquals(ERR_MULTIPART_PROPERTY, "8bit", rootPart.getHeaders().getFirst("Content-Transfer-Encoding")); Assert.assertEquals(ERR_VALUE, "<m:data xmlns:m='http://example.org/stuff'>" + "<m:photo><xop:Include xmlns:xop='http://www.w3.org/2004/08/xop/include' href='cid:http://example.org/me.png'/></m:photo>" + "<m:sig><xop:Include xmlns:xop='http://www.w3.org/2004/08/xop/include' href='cid:http://example.org/my.hsh'/></m:sig>" + "</m:data>", rootPart.getBodyAsString()); InputPart relatedPart1 = inputParts.next(); Assert.assertEquals(ERR_MULTIPART_PROPERTY, "image", relatedPart1.getMediaType().getType()); Assert.assertEquals(ERR_MULTIPART_PROPERTY, "png", relatedPart1.getMediaType().getSubtype()); Assert.assertEquals(ERR_MULTIPART_PROPERTY, "<http://example.org/me.png>", relatedPart1 .getHeaders().getFirst("Content-ID")); Assert.assertEquals(ERR_MULTIPART_PROPERTY, "binary", relatedPart1.getHeaders().getFirst("Content-Transfer-Encoding")); Assert.assertEquals(ERR_VALUE, "// binary octets for png", relatedPart1.getBodyAsString()); InputPart relatedPart2 = inputParts.next(); Assert.assertEquals(ERR_MULTIPART_PROPERTY, "application", relatedPart2.getMediaType().getType()); Assert.assertEquals(ERR_MULTIPART_PROPERTY, "pkcs7-signature", relatedPart2.getMediaType().getSubtype()); Assert.assertEquals(ERR_MULTIPART_PROPERTY, "<http://example.org/me.hsh>", relatedPart2 .getHeaders().getFirst("Content-ID")); Assert.assertEquals(ERR_MULTIPART_PROPERTY, "binary", relatedPart2.getHeaders().getFirst("Content-Transfer-Encoding")); Assert.assertEquals(ERR_VALUE, "// binary octets for signature", relatedPart2.getBodyAsString()); } @PUT @Path("form/map") @Consumes("multipart/form-data") public void putMultipartMap(Map<String, MimeMultipartProviderCustomer> multipart) throws IOException { Assert.assertEquals(ERR_NUMBER, 2, multipart.size()); Assert.assertTrue(ERR_VALUE, multipart.containsKey("bill")); Assert.assertTrue(ERR_VALUE, multipart.containsKey("monica")); MimeMultipartProviderCustomer cust = multipart.get("bill"); Assert.assertNotNull(ERR_CUST_NULL, cust); Assert.assertEquals(ERR_VALUE, "bill", cust.getName()); cust = multipart.get("monica"); Assert.assertNotNull(ERR_CUST_NULL, cust); Assert.assertEquals(ERR_VALUE, "monica", cust.getName()); } @PUT @Path("multi") @Consumes("multipart/form-data") public void putMultipartData(MultipartInput multipart) throws IOException { Assert.assertEquals(ERR_NUMBER, 2, multipart.getParts().size()); MimeMultipartProviderCustomer cust = multipart.getParts().get(0).getBody(MimeMultipartProviderCustomer.class, null); Assert.assertNotNull(ERR_CUST_NULL, cust); Assert.assertEquals(ERR_VALUE, "bill", cust.getName()); cust = multipart.getParts().get(1).getBody(MimeMultipartProviderCustomer.class, null); Assert.assertNotNull(ERR_CUST_NULL, cust); Assert.assertEquals(ERR_VALUE, "monica", cust.getName()); } @PUT @Path("mixed") @Consumes("multipart/mixed") public void putMultipartMixed(MultipartInput multipart) throws IOException { Assert.assertEquals(ERR_NUMBER, 2, multipart.getParts().size()); MimeMultipartProviderCustomer cust = multipart.getParts().get(0).getBody(MimeMultipartProviderCustomer.class, null); Assert.assertNotNull(ERR_CUST_NULL, cust); Assert.assertEquals(ERR_VALUE, "bill", cust.getName()); cust = multipart.getParts().get(1).getBody(MimeMultipartProviderCustomer.class, null); Assert.assertNotNull(ERR_CUST_NULL, cust); Assert.assertEquals(ERR_VALUE, "monica", cust.getName()); } @PUT @Path("multi/list") @Consumes("multipart/form-data") public void putMultipartList(List<MimeMultipartProviderCustomer> multipart) throws IOException { Assert.assertEquals(ERR_NUMBER, 2, multipart.size()); MimeMultipartProviderCustomer cust = multipart.get(0); Assert.assertNotNull(ERR_CUST_NULL, cust); Assert.assertEquals(ERR_VALUE, "bill", cust.getName()); cust = multipart.get(1); Assert.assertNotNull(ERR_CUST_NULL, cust); Assert.assertEquals(ERR_VALUE, "monica", cust.getName()); } @PUT @Path("form/class") @Consumes("multipart/form-data") public void putMultipartForm(@MultipartForm Form form) throws IOException { Assert.assertNotNull(ERR_CUST_NULL, form.getBill()); Assert.assertEquals(ERR_VALUE, "bill", form.getBill().getName()); Assert.assertNotNull(ERR_CUST_NULL, form.getMonica()); Assert.assertEquals(ERR_VALUE, "monica", form.getMonica().getName()); } @PUT @Path("xop") @Consumes(MultipartConstants.MULTIPART_RELATED) public void putXopWithMultipartRelated(@XopWithMultipartRelated Xop xop) throws IOException { Assert.assertNotNull(ERR_CUST_NULL, xop.getBill()); Assert.assertEquals(ERR_VALUE, "bill\u00E9", xop.getBill().getName()); Assert.assertNotNull(ERR_CUST_NULL, xop.getMonica()); Assert.assertEquals(ERR_VALUE, "monica", xop.getMonica().getName()); Assert.assertNotNull(ERR_CUST_NULL, xop.getMyBinary()); Assert.assertNotNull(ERR_CUST_NULL, xop.getMyDataHandler()); Assert.assertEquals(ERR_VALUE, "Hello Xop World!", new String(xop.getMyBinary(), "UTF-8")); // lets do it twice to test that we get different InputStream-s each // time. for (int fi = 0; fi < 2; fi++) { InputStream inputStream = xop.getMyDataHandler().getInputStream(); InputStreamReader inputStreamReader = null; try { inputStreamReader = new InputStreamReader(inputStream, "UTF-8"); StringWriter writer = new StringWriter(); char[] buffer = new char[4048]; int n = 0; while ((n = inputStreamReader.read(buffer)) != -1) { writer.write(buffer, 0, n); } Assert.assertEquals(ERR_VALUE, "Hello Xop World!", writer.toString()); } finally { if (inputStreamReader != null) { inputStreamReader.close(); } inputStream.close(); } } } @PUT @Path("text") @Consumes("multipart/form-data") @Produces("text/plain") public void putData(String multipart) { logger.info(multipart); } @GET @Produces("multipart/mixed") public MimeMultipart getMimeMultipart() throws MessagingException { MimeMultipart multipart = new MimeMultipart("mixed"); multipart.addBodyPart(createPart("Body of part 1", "text/plain", "This is a description")); multipart.addBodyPart(createPart("Body of part 2", "text/plain", "This is another description")); return multipart; } private MimeBodyPart createPart(String value, String type, String description) throws MessagingException { MimeBodyPart part = new MimeBodyPart(); part.setDescription(description); part.setContent(value, type); return part; } }