/**
* 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.cxf.systest.jaxrs;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.imageio.ImageIO;
import javax.mail.util.ByteArrayDataSource;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;
import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.jaxrs.ext.MessageContext;
import org.apache.cxf.jaxrs.ext.multipart.Attachment;
import org.apache.cxf.jaxrs.ext.multipart.Multipart;
import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
import org.apache.cxf.jaxrs.utils.multipart.AttachmentUtils;
@Path("/bookstore")
public class MultipartStore {
@Context
private MessageContext context;
public MultipartStore() {
}
@POST
@Path("/books/image")
@Consumes("multipart/mixed")
@Produces("multipart/mixed")
public byte[] addBookImage(byte[] image) throws Exception {
return image;
}
@POST
@Path("/xop")
@Consumes("multipart/related")
@Produces("multipart/related;type=text/xml")
public XopType addBookXop(XopType type) throws Exception {
if (!"xopName".equals(type.getName())) {
throw new RuntimeException("Wrong name property");
}
String bookXsd = IOUtils.readStringFromStream(type.getAttachinfo().getInputStream());
String bookXsd2 = IOUtils.readStringFromStream(
getClass().getResourceAsStream("/org/apache/cxf/systest/jaxrs/resources/book.xsd"));
if (!bookXsd.equals(bookXsd2)) {
throw new RuntimeException("Wrong attachinfo property");
}
String bookXsdRef = IOUtils.readStringFromStream(type.getAttachInfoRef().getInputStream());
if (!bookXsdRef.equals(bookXsd2)) {
throw new RuntimeException("Wrong attachinforef property");
}
if (!Boolean.getBoolean("java.awt.headless") && type.getImage() == null) {
throw new RuntimeException("Wrong image property");
}
context.put(org.apache.cxf.message.Message.MTOM_ENABLED,
(Object)"true");
XopType xop = new XopType();
xop.setName("xopName");
InputStream is =
getClass().getResourceAsStream("/org/apache/cxf/systest/jaxrs/resources/book.xsd");
byte[] data = IOUtils.readBytesFromStream(is);
xop.setAttachinfo(new DataHandler(new ByteArrayDataSource(data, "application/octet-stream")));
xop.setAttachInfoRef(new DataHandler(new ByteArrayDataSource(data, "application/octet-stream")));
xop.setAttachinfo2(bookXsd.getBytes());
if (Boolean.getBoolean("java.awt.headless")) {
System.out.println("Running headless. Ignoring an Image property.");
} else {
xop.setImage(ImageIO.read(getClass().getResource(
"/org/apache/cxf/systest/jaxrs/resources/java.jpg")));
}
return xop;
}
@POST
@Path("/books/formimage2")
@Consumes("multipart/form-data")
@Produces("multipart/form-data")
public MultipartBody addBookFormImage2(MultipartBody image) throws Exception {
image.getAllAttachments();
return image;
}
@POST
@Path("/books/formimage")
@Consumes("multipart/form-data")
@Produces("multipart/form-data")
public MultipartBody addBookFormImage(MultipartBody image) throws Exception {
List<Attachment> atts = image.getAllAttachments();
if (atts.size() != 1) {
throw new WebApplicationException();
}
List<Attachment> newAtts = new ArrayList<Attachment>();
Attachment at = atts.get(0);
MultivaluedMap<String, String> headers = at.getHeaders();
if (!"http://host/bar".equals(headers.getFirst("Content-Location"))) {
throw new WebApplicationException();
}
if (!"custom".equals(headers.getFirst("Custom-Header"))) {
throw new WebApplicationException();
}
headers.putSingle("Content-Location", "http://host/location");
newAtts.add(new Attachment(at.getContentId(), at.getDataHandler(), headers));
return new MultipartBody(newAtts);
}
@POST
@Path("/books/testnullpart")
@Consumes("multipart/form-data")
@Produces("text/plain")
public String testNullPart(@Multipart(value = "someid", required = false) String value) {
if (value != null) {
return value;
} else {
return "nobody home";
}
}
@POST
@Path("/books/testnullpartFormParam")
@Consumes("multipart/form-data")
@Produces("text/plain")
public String testNullPartFormParam(@FormParam(value = "someid") String value) {
return testNullPart(value);
}
@POST
@Path("/books/jaxbjsonimage")
@Consumes({"multipart/mixed", "multipart/related" })
@Produces({"multipart/mixed", "multipart/related" })
public Map<String, Object> addBookJaxbJsonImage(@Multipart("root.message@cxf.apache.org") Book jaxb,
@Multipart("1") Book json,
@Multipart("2") byte[] image) throws Exception {
Map<String, Object> objects = new LinkedHashMap<String, Object>();
objects.put("application/xml", jaxb);
objects.put("application/json", json);
objects.put("application/octet-stream", new ByteArrayInputStream(image));
return objects;
}
@POST
@Path("/books/jaxbimagejson")
@Consumes("multipart/mixed")
@Produces("multipart/mixed")
public Map<String, Object> addBookJaxbJsonImage2(@Multipart("theroot") Book jaxb,
@Multipart("thejson") Book json,
@Multipart("theimage") byte[] image) throws Exception {
Map<String, Object> objects = new LinkedHashMap<String, Object>();
objects.put("application/xml", jaxb);
objects.put("application/json", json);
objects.put("application/octet-stream", new ByteArrayInputStream(image));
return objects;
}
@GET
@Path("/books/jaxbjsonimage/read")
@Produces("multipart/mixed")
public Map<String, Book> getBookJaxbJson() throws Exception {
Book jaxb = new Book("jaxb", 1L);
Book json = new Book("json", 2L);
Map<String, Book> objects = new LinkedHashMap<String, Book>();
objects.put(MediaType.APPLICATION_XML, jaxb);
objects.put(MediaType.APPLICATION_JSON, json);
return objects;
}
@GET
@Path("/books/jaxbjsonimage/read2")
@Produces("multipart/mixed")
public Map<String, Book> getBookJson() throws Exception {
Book json = new Book("json", 1L);
Map<String, Book> objects = new LinkedHashMap<String, Book>();
objects.put(MediaType.APPLICATION_JSON, json);
return objects;
}
@GET
@Path("/books/jaxbjsonimage/read-object")
@Produces("multipart/mixed")
public Map<String, Object> getBookJaxbJsonObject() throws Exception {
Book jaxb = new Book("jaxb", 1L);
Book json = new Book("json", 2L);
Map<String, Object> objects = new LinkedHashMap<String, Object>();
objects.put(MediaType.APPLICATION_XML, jaxb);
objects.put(MediaType.APPLICATION_JSON, json);
return objects;
}
@POST
@Path("/books/stream")
@Produces("text/xml")
public Response addBookFromStream(StreamSource source) throws Exception {
JAXBContext c = JAXBContext.newInstance(new Class[]{Book.class});
Unmarshaller u = c.createUnmarshaller();
Book b = (Book)u.unmarshal(source);
b.setId(124);
return Response.ok(b).build();
}
@POST
@Path("/books/form")
@Consumes("multipart/form-data")
@Produces("text/xml")
public Response addBookFromForm(MultivaluedMap<String, String> data) throws Exception {
Book b = new Book();
b.setId(Long.valueOf(data.getFirst("id")));
b.setName(data.getFirst("name"));
return Response.ok(b).build();
}
@POST
@Path("/books/formbody")
@Consumes("multipart/form-data")
@Produces("text/xml")
public Response addBookFromFormBody(MultipartBody body) throws Exception {
MultivaluedMap<String, String> data = AttachmentUtils.populateFormMap(context);
Book b = new Book();
b.setId(Long.valueOf(data.getFirst("id")));
b.setName(data.getFirst("name"));
return Response.ok(b).build();
}
@POST
@Path("/books/formbody2")
@Consumes("multipart/form-data")
@Produces("text/xml")
public Response addBookFromFormBody2() throws Exception {
return addBookFromFormBody(AttachmentUtils.getMultipartBody(context));
}
@POST
@Path("/books/formparam")
@Produces("text/xml")
public Response addBookFromFormParam(@FormParam("name") String title,
@FormParam("id") Long id) throws Exception {
if (!"CXF in Action - 2".equals(title)) {
throw new RuntimeException();
}
Book b = new Book();
b.setId(id);
b.setName(title);
return Response.ok(b).build();
}
@POST
@Path("/books/formparambean")
@Produces("text/xml")
public Response addBookFromFormBean(@FormParam("") Book b) throws Exception {
return Response.ok(b).build();
}
@POST
@Path("/books/istream")
@Produces("text/xml")
public Response addBookFromInputStream(InputStream is) throws Exception {
return readBookFromInputStream(is);
}
@POST
@Path("/books/dsource")
@Produces("text/xml")
public Response addBookFromDataSource(DataSource ds) throws Exception {
return readBookFromInputStream(ds.getInputStream());
}
@POST
@Path("/books/jaxb2")
@Consumes("multipart/related;type=\"text/xml\"")
@Produces("text/xml")
public Response addBookParts(@Multipart("rootPart") Book b1,
@Multipart("book2") Book b2)
throws Exception {
if (b1.equals(b2)) {
throw new WebApplicationException();
}
if (!b1.getName().equals(b2.getName())) {
throw new WebApplicationException();
}
b1.setId(124);
return Response.ok(b1).build();
}
@POST
@Path("/books/jaxb-body")
@Consumes("multipart/related;type=\"text/xml\"")
@Produces("text/xml")
public Response addBookParts2(MultipartBody body)
throws Exception {
Book b1 = body.getAttachmentObject("rootPart", Book.class);
Book b2 = body.getAttachmentObject("book2", Book.class);
if (b1.equals(b2)) {
throw new WebApplicationException();
}
if (!b1.getName().equals(b2.getName())) {
throw new WebApplicationException();
}
b1.setId(124);
return Response.ok(b1).build();
}
@POST
@Path("/books/jaxbonly")
@Consumes("multipart/mixed")
@Produces("multipart/mixed;type=text/xml")
public List<Book> addBooks(List<Book> books) {
List<Book> books2 = new ArrayList<Book>();
books2.addAll(books);
return books2;
}
@POST
@Path("/books/jaxbonly")
@Consumes("multipart/mixed;type=text/xml")
@Produces("multipart/mixed;type=text/xml")
public List<Book> addBooksWithoutHeader(List<Book> books) {
return addBooks(books);
}
@POST
@Path("/books/jaxbjsonconsumes")
@Consumes("multipart/related")
@Produces("text/xml")
public Book addBookJaxbJsonWithConsumes(
@Multipart(value = "rootPart", type = "text/xml") Book2 b1,
@Multipart(value = "book2", type = "application/json") Book b2) throws Exception {
return addBookJaxbJson(b1, b2);
}
@POST
@Path("/books/jaxbandsimpleparts")
@Consumes("multipart/related")
@Produces("text/xml")
public Book testAddBookAndSimpleParts(
@Multipart(value = "rootPart", type = "text/xml") Book b1,
@Multipart(value = "simplePart1") String simplePart1,
@Multipart(value = "simplePart2") String simplePart2) throws Exception {
return new Book(b1.getName() + " - " + simplePart1 + simplePart2, b1.getId());
}
@POST
@Path("/books/jaxbonly")
@Consumes("multipart/related")
@Produces("text/xml")
public Book2 addBookJaxbOnlyWithConsumes(
@Multipart(value = "rootPart", type = "text/xml") Book2 b1) throws Exception {
if (!"CXF in Action".equals(b1.getName())) {
throw new WebApplicationException();
}
return b1;
}
@POST
@Path("/books/jaxbjson")
@Produces("text/xml")
public Book addBookJaxbJson(
@Multipart(value = "rootPart", type = "text/xml") Book2 b1,
@Multipart(value = "book2", type = "application/json") Book b2)
throws Exception {
if (!"CXF in Action".equals(b1.getName())
|| !"CXF in Action - 2".equals(b2.getName())) {
throw new WebApplicationException();
}
b2.setId(124);
return b2;
}
@POST
@Path("/books/jsonform")
@Produces("text/xml")
@Consumes("multipart/form-data")
public Response addBookJsonFromForm(Book b1)
throws Exception {
b1.setId(124);
return Response.ok(b1).build();
}
@POST
@Path("/books/filesform")
@Produces("text/xml")
@Consumes("multipart/form-data")
public Response addBookFilesForm(@Multipart("owner") String name,
@Multipart("files") List<Book> books)
throws Exception {
if (books.size() != 2) {
throw new WebApplicationException();
}
Book b1 = books.get(0);
Book b2 = books.get(1);
if (!"CXF in Action - 1".equals(b1.getName())
|| !"CXF in Action - 2%".equals(b2.getName())
|| !"Larry".equals(name)) {
throw new WebApplicationException();
}
b1.setId(124);
b1.setName("CXF in Action - 2");
return Response.ok(b1).build();
}
@POST
@Path("/books/filesform/singlefile")
@Produces("text/xml")
@Consumes("multipart/form-data")
public Response addBookFilesFormSingleFile(@Multipart("owner") String name,
@Multipart("file") List<Book> books)
throws Exception {
if (books.size() != 1) {
throw new WebApplicationException();
}
Book b = books.get(0);
if (!"CXF in Action - 1".equals(b.getName())
|| !"Larry".equals(name)) {
throw new WebApplicationException();
}
b.setId(124);
b.setName("CXF in Action - 2");
return Response.ok(b).build();
}
@POST
@Path("/books/filesform/mixup")
@Produces("text/xml")
@Consumes("multipart/form-data")
public Response addBookFilesFormMixUp(@FormParam("owner") String name,
@Multipart("files") List<Book> books)
throws Exception {
return addBookFilesForm(name, books);
}
@POST
@Path("/books/fileform")
@Produces("text/xml")
@Consumes("multipart/form-data")
public Response addBookFilesForm(MultipartBody body)
throws Exception {
String owner = body.getAttachmentObject("owner", String.class);
Book book = body.getAttachmentObject("file", Book.class);
if (!"CXF in Action - 1".equals(book.getName())
|| !"Larry".equals(owner)) {
throw new WebApplicationException();
}
book.setId(124);
book.setName("CXF in Action - 2");
return Response.ok(book).build();
}
@POST
@Path("/books/jaxbform")
@Produces("text/xml")
@Consumes("multipart/form-data")
public Response addBookJaxbFromForm(Book b1)
throws Exception {
b1.setId(124);
return Response.ok(b1).build();
}
@POST
@Path("/books/jsonjaxbform")
@Produces("text/xml")
@Consumes("multipart/form-data")
public Response addBookJaxbJsonForm(@Multipart("jsonPart") Book b1,
@Multipart("bookXML") Book b2)
throws Exception {
if (!"CXF in Action - 1".equals(b1.getName())
|| !"CXF in Action - 2".equals(b2.getName())) {
throw new WebApplicationException();
}
b2.setId(124);
return Response.ok(b2).build();
}
@POST
@Path("/books/jsonjaxbformencoded")
@Produces("text/xml")
@Consumes("multipart/form-data")
public Response addBookJaxbJsonFormEncoded(@Multipart("jsonPart") Book b1,
@Multipart("bookXML") Book b2)
throws Exception {
return addBookJaxbJsonForm(b1, b2);
}
@POST
@Path("/books/dsource2")
@Produces("text/xml")
public Response addBookFromDataSource2(@Multipart("rootPart") DataSource ds1,
@Multipart("book2") DataSource ds2)
throws Exception {
Response r1 = readBookFromInputStream(ds1.getInputStream());
Response r2 = readBookFromInputStream(ds2.getInputStream());
Book b1 = (Book)r1.getEntity();
Book b2 = (Book)r2.getEntity();
if (b1.equals(b2)) {
throw new WebApplicationException();
}
if (!b1.getName().equals(b2.getName())) {
throw new WebApplicationException();
}
return r1;
}
@POST
@Path("/books/listattachments")
@Produces("text/xml")
public Response addBookFromListOfAttachments(List<Attachment> atts)
throws Exception {
Response r1 = readBookFromInputStream(atts.get(0).getDataHandler().getInputStream());
Response r2 = readBookFromInputStream(atts.get(2).getDataHandler().getInputStream());
Book b1 = (Book)r1.getEntity();
Book b2 = (Book)r2.getEntity();
if (b1.equals(b2)) {
throw new WebApplicationException();
}
if (!b1.getName().equals(b2.getName())) {
throw new WebApplicationException();
}
return r1;
}
@POST
@Path("/books/body")
@Produces("text/xml")
public Response addBookFromListOfAttachments(MultipartBody body)
throws Exception {
return addBookFromListOfAttachments(body.getAllAttachments());
}
@POST
@Path("/books/lististreams")
@Produces("text/xml")
public Response addBookFromListOfStreams(List<InputStream> atts)
throws Exception {
Response r1 = readBookFromInputStream(atts.get(0));
Response r2 = readBookFromInputStream(atts.get(2));
Book b1 = (Book)r1.getEntity();
Book b2 = (Book)r2.getEntity();
if (b1.equals(b2)) {
throw new WebApplicationException();
}
if (!b1.getName().equals(b2.getName())) {
throw new WebApplicationException();
}
return r1;
}
@POST
@Path("/books/dhandler")
@Produces("text/xml")
public Response addBookFromDataHandler(DataHandler dh) throws Exception {
return readBookFromInputStream(dh.getInputStream());
}
@POST
@Path("/books/attachment")
@Produces("text/xml")
public Response addBookFromAttachment(Attachment a) throws Exception {
return readBookFromInputStream(a.getDataHandler().getInputStream());
}
@POST
@Path("/books/mchandlers")
@Produces("text/xml")
public Response addBookFromMessageContext() throws Exception {
Map<String, Attachment> handlers = AttachmentUtils.getAttachmentsMap(context);
for (Map.Entry<String, Attachment> entry : handlers.entrySet()) {
if (entry.getKey().equals("book2")) {
return readBookFromInputStream(entry.getValue().getDataHandler().getInputStream());
}
}
throw new WebApplicationException(500);
}
@POST
@Path("/books/attachments")
@Produces("text/xml")
public Response addBookFromAttachments() throws Exception {
Collection<Attachment> handlers = AttachmentUtils.getChildAttachments(context);
for (Attachment a : handlers) {
if (a.getContentId().equals("book2")) {
return readBookFromInputStream(a.getDataHandler().getInputStream());
}
}
throw new WebApplicationException(500);
}
@POST
@Path("/books/jaxb")
@Produces("text/xml")
public Response addBook(Book b) throws Exception {
b.setId(124);
return Response.ok(b).build();
}
@POST
@Path("/books/mismatch1")
@Consumes("multipart/related;type=\"bar/foo\"")
@Produces("text/xml")
public Response addBookMismatched(Book b) {
throw new WebApplicationException();
}
@POST
@Path("/books/mismatch2")
@Produces("text/xml")
public Response addBookMismatched2(@Multipart(value = "rootPart", type = "f/b") Book b) {
throw new WebApplicationException();
}
@POST
@Path("/books/mixedmultivaluedmap")
@Consumes("multipart/mixed")
@Produces("text/xml")
public Response addBookFromFormConsumesMixed(
@Multipart(value = "mapdata", type = MediaType.APPLICATION_FORM_URLENCODED)
MultivaluedMap<String, String> data,
@Multipart(value = "test-cid", type = MediaType.APPLICATION_XML)
String testXml) throws Exception {
if (!"Dreams".equals(data.get("id-name").get(0))) {
throw new Exception("Map entry 0 does not match");
}
if (!"True".equals(data.get("entity-name").get(0))) {
throw new Exception("Map entry 1 does not match");
}
if (!"NAT5\n".equals(data.get("native-id").get(0))) {
throw new Exception("Map entry 2 does not match");
}
if (data.size() != 3) {
throw new Exception("Map size does not match");
}
if ("<hello>World2</hello>".equals(testXml)) {
throw new Exception("testXml does not match");
}
Book b = new Book();
b.setId(124);
b.setName("CXF in Action - 2");
return Response.ok(b).build();
}
private Response readBookFromInputStream(InputStream is) throws Exception {
JAXBContext c = JAXBContext.newInstance(new Class[]{Book.class});
Unmarshaller u = c.createUnmarshaller();
Book b = (Book)u.unmarshal(is);
b.setId(124);
return Response.ok(b).build();
}
}