You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2009/09/07 22:08:25 UTC
svn commit: r812265 - in /cxf/branches/2.2.x-fixes: ./
rt/core/src/main/java/org/apache/cxf/attachment/
rt/core/src/main/java/org/apache/cxf/interceptor/
rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/
rt/frontend/jaxrs/src/main/java/org/a...
Author: sergeyb
Date: Mon Sep 7 20:08:23 2009
New Revision: 812265
URL: http://svn.apache.org/viewvc?rev=812265&view=rev
Log:
Merged revisions 812232 via svnmerge from
https://svn.apache.org/repos/asf/cxf/trunk
........
r812232 | sergeyb | 2009-09-07 18:25:40 +0100 (Mon, 07 Sep 2009) | 1 line
[CXF-2270] : support for writing attachments for JAXRS
........
Added:
cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/AttachmentOutputInterceptor.java
- copied unchanged from r812232, cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/AttachmentOutputInterceptor.java
cxf/branches/2.2.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/resources/java.jpg
- copied unchanged from r812232, cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/resources/java.jpg
Modified:
cxf/branches/2.2.x-fixes/ (props changed)
cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/attachment/AttachmentSerializer.java
cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/attachment/AttachmentUtil.java
cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/AttachmentOutInterceptor.java
cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java
cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java
cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java
cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/Attachment.java
cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/ContentDisposition.java
cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/Multipart.java
cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/MultipartBody.java
cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java
cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/FormEncodingProvider.java
cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/Messages.properties
cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/MultipartProvider.java
cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
cxf/branches/2.2.x-fixes/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java
cxf/branches/2.2.x-fixes/rt/transports/http/src/test/java/org/apache/cxf/transport/http/HTTPConduitURLEasyMockTest.java
cxf/branches/2.2.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java
cxf/branches/2.2.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java
Propchange: cxf/branches/2.2.x-fixes/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Sep 7 20:08:23 2009
@@ -1 +1 @@
-/cxf/trunk:782728-782730,783097,783294,783396,784059,784181-784184,784893,784895,785279-785282,785468,785621,785624,785651,785734,785866,786142,786271-786272,786395,786512,786514,786582-786583,786638,786647,786850,787200,787269,787277-787279,787290-787291,787305,787323,787366,787849,788030,788060,788187,788444,788451,788703,788752,788774,788819-788820,789013,789371,789387,789420,789527-789530,789704-789705,789788,789811,789896-789901,790074,790094,790134,790188,790294,790553,790637-790644,790868,791301,791354,791538,791753,791947,792007,792096,792183,792261-792265,792271,792604,792683-792685,792975,792985,793059,793570,794297,794396,794680,794728,794771,794778-794780,794892,795044,795104,795160,795583,795907,796022-796023,796352,796593,796741,796780,796994-796997,797117,797159,797192,797194,797231-797233,797442,797505,797517,797534,797581-797583,797587,797640,797651,797699,797882-797883,798344-798346,798363,798461,798479,798533,798551,798557,798561-798562,798570,798573,79858
4,798654,798748-798749,798816,798891,798929-798930,799245,799267,799439,799448,799637,799723-799724,799792,800453,800497-800498,801380-801381,801447,801962,802892,803056,803129,803174,803419,803460,803493,803689,804002,804175,804276,805784,805907,805909,806020-806021,806023,806405-806406,806576,806602-806604,806620,806627,806631,806633,806638,806687,806876,806922,806979-806982,807181,807205,807295,807748,807807,808035,808069,808085,808107,808464,808488,808731,808885,808925,809082-809083,809162,809190,809417-809626,809631,809663,809706,809738,809962,810090,810143,810349,810376,810513,810526,810927,811013,811148-811149,811175,811183,811387,811467-811468,811680,811696
+/cxf/trunk:782728-782730,783097,783294,783396,784059,784181-784184,784893,784895,785279-785282,785468,785621,785624,785651,785734,785866,786142,786271-786272,786395,786512,786514,786582-786583,786638,786647,786850,787200,787269,787277-787279,787290-787291,787305,787323,787366,787849,788030,788060,788187,788444,788451,788703,788752,788774,788819-788820,789013,789371,789387,789420,789527-789530,789704-789705,789788,789811,789896-789901,790074,790094,790134,790188,790294,790553,790637-790644,790868,791301,791354,791538,791753,791947,792007,792096,792183,792261-792265,792271,792604,792683-792685,792975,792985,793059,793570,794297,794396,794680,794728,794771,794778-794780,794892,795044,795104,795160,795583,795907,796022-796023,796352,796593,796741,796780,796994-796997,797117,797159,797192,797194,797231-797233,797442,797505,797517,797534,797581-797583,797587,797640,797651,797699,797882-797883,798344-798346,798363,798461,798479,798533,798551,798557,798561-798562,798570,798573,79858
4,798654,798748-798749,798816,798891,798929-798930,799245,799267,799439,799448,799637,799723-799724,799792,800453,800497-800498,801380-801381,801447,801962,802892,803056,803129,803174,803419,803460,803493,803689,804002,804175,804276,805784,805907,805909,806020-806021,806023,806405-806406,806576,806602-806604,806620,806627,806631,806633,806638,806687,806876,806922,806979-806982,807181,807205,807295,807748,807807,808035,808069,808085,808107,808464,808488,808731,808885,808925,809082-809083,809162,809190,809417-809626,809631,809663,809706,809738,809962,810090,810143,810349,810376,810513,810526,810927,811013,811148-811149,811175,811183,811387,811467-811468,811680,811696,812232
Propchange: cxf/branches/2.2.x-fixes/
------------------------------------------------------------------------------
Binary property 'svnmerge-integrated' - no diff available.
Modified: cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/attachment/AttachmentSerializer.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/attachment/AttachmentSerializer.java?rev=812265&r1=812264&r2=812265&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/attachment/AttachmentSerializer.java (original)
+++ cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/attachment/AttachmentSerializer.java Mon Sep 7 20:08:23 2009
@@ -24,6 +24,11 @@
import java.io.StringWriter;
import java.io.Writer;
import java.net.URLDecoder;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
import org.apache.cxf.message.Attachment;
import org.apache.cxf.message.Message;
@@ -31,17 +36,26 @@
public class AttachmentSerializer {
- private static final String BODY_ATTACHMENT_ID = "root.message@cxf.apache.org";
private Message message;
private String bodyBoundary;
private OutputStream out;
private String encoding;
+
+ private String multipartType;
+ private Map<String, List<String>> rootHeaders = Collections.emptyMap();
private boolean xop = true;
public AttachmentSerializer(Message messageParam) {
message = messageParam;
}
+ public AttachmentSerializer(Message messageParam, String multipartType,
+ Map<String, List<String>> headers) {
+ message = messageParam;
+ this.multipartType = multipartType;
+ this.rootHeaders = headers;
+ }
+
/**
* Serialize the beginning of the attachment which includes the MIME
* beginning and headers for the root message.
@@ -73,19 +87,27 @@
}
// Set transport mime type
+ String requestMimeType = multipartType == null ? "multipart/related" : multipartType;
+
StringBuilder ct = new StringBuilder();
- ct.append("multipart/related; ");
- if (xop) {
- ct.append("type=\"application/xop+xml\"; ");
- } else {
- ct.append("type=\"").append(bodyCt).append("\"; ");
+ ct.append(requestMimeType);
+ if (requestMimeType.indexOf("type=") == -1) {
+ ct.append("; ");
+ if (xop) {
+ ct.append("type=\"application/xop+xml\"");
+ } else {
+ ct.append("type=\"").append(bodyCt).append("\"");
+ }
}
+ ct.append("; ");
+
+ String rootContentId = getHeaderValue("Content-ID", AttachmentUtil.BODY_ATTACHMENT_ID);
ct.append("boundary=\"")
.append(bodyBoundary)
.append("\"; ")
.append("start=\"<")
- .append(BODY_ATTACHMENT_ID)
+ .append(rootContentId)
.append(">\"; ")
.append("start-info=\"")
.append(bodyCt)
@@ -106,17 +128,38 @@
writer.write(bodyBoundary);
StringBuilder mimeBodyCt = new StringBuilder();
- mimeBodyCt.append("application/xop+xml; charset=")
- .append(encoding)
- .append("; type=\"")
- .append(bodyCt)
- .append("\";");
+ String bodyType = getHeaderValue("Content-Type", null);
+ if (bodyType == null) {
+ mimeBodyCt.append("application/xop+xml; charset=")
+ .append(encoding)
+ .append("; type=\"")
+ .append(bodyCt)
+ .append("\";");
+ } else {
+ mimeBodyCt.append(bodyType);
+ }
- writeHeaders(mimeBodyCt.toString(), BODY_ATTACHMENT_ID, writer);
+ writeHeaders(mimeBodyCt.toString(), rootContentId, rootHeaders, writer);
out.write(writer.getBuffer().toString().getBytes(encoding));
}
- private void writeHeaders(String contentType, String attachmentId, Writer writer) throws IOException {
+ private String getHeaderValue(String name, String defaultValue) {
+ List<String> value = rootHeaders.get(name);
+ if (value == null || value.isEmpty()) {
+ return defaultValue;
+ }
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < value.size(); i++) {
+ sb.append(value.get(i));
+ if (i + 1 < value.size()) {
+ sb.append(',');
+ }
+ }
+ return sb.toString();
+ }
+
+ private static void writeHeaders(String contentType, String attachmentId,
+ Map<String, List<String>> headers, Writer writer) throws IOException {
writer.write("\r\n");
writer.write("Content-Type: ");
writer.write(contentType);
@@ -133,6 +176,24 @@
writer.write(URLDecoder.decode(attachmentId, "UTF-8"));
writer.write(">\r\n");
}
+ // headers like Content-Disposition need to be serialized
+ for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
+ String name = entry.getKey();
+ if ("Content-Type".equalsIgnoreCase(name) || "Content-ID".equalsIgnoreCase(name)
+ || "Content-Transfer-Encoding".equalsIgnoreCase(name)) {
+ continue;
+ }
+ writer.write(name + ": ");
+ List<String> values = entry.getValue();
+ for (int i = 0; i < values.size(); i++) {
+ writer.write(values.get(i));
+ if (i + 1 < values.size()) {
+ writer.write(",");
+ }
+ }
+ writer.write("\r\n");
+ }
+
writer.write("\r\n");
}
@@ -147,7 +208,21 @@
writer.write("\r\n");
writer.write("--");
writer.write(bodyBoundary);
- writeHeaders(a.getDataHandler().getContentType(), a.getId(), writer);
+
+ Map<String, List<String>> headers = null;
+ Iterator<String> it = a.getHeaderNames();
+ if (it.hasNext()) {
+ headers = new LinkedHashMap<String, List<String>>();
+ while (it.hasNext()) {
+ String key = it.next();
+ headers.put(key, Collections.singletonList(a.getHeader(key)));
+ }
+ } else {
+ headers = Collections.emptyMap();
+ }
+
+ writeHeaders(a.getDataHandler().getContentType(), a.getId(),
+ headers, writer);
out.write(writer.getBuffer().toString().getBytes(encoding));
a.getDataHandler().writeTo(out);
Modified: cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/attachment/AttachmentUtil.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/attachment/AttachmentUtil.java?rev=812265&r1=812264&r2=812265&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/attachment/AttachmentUtil.java (original)
+++ cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/attachment/AttachmentUtil.java Mon Sep 7 20:08:23 2009
@@ -44,6 +44,9 @@
import org.apache.cxf.message.Attachment;
public final class AttachmentUtil {
+
+ public static final String BODY_ATTACHMENT_ID = "root.message@cxf.apache.org";
+
private static volatile int counter;
private static final String ATT_UUID = UUID.randomUUID().toString();
@@ -99,7 +102,7 @@
return "uuid:" + result.toString();
}
- public static String getAttchmentPartHeader(Attachment att) {
+ public static String getAttachmentPartHeader(Attachment att) {
StringBuffer buffer = new StringBuffer(200);
buffer.append(HttpHeaderHelper.getHeaderKey(HttpHeaderHelper.CONTENT_TYPE) + ": "
+ att.getDataHandler().getContentType() + ";\r\n");
Modified: cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/AttachmentOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/AttachmentOutInterceptor.java?rev=812265&r1=812264&r2=812265&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/AttachmentOutInterceptor.java (original)
+++ cxf/branches/2.2.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/AttachmentOutInterceptor.java Mon Sep 7 20:08:23 2009
@@ -20,6 +20,9 @@
package org.apache.cxf.interceptor;
import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
import java.util.ResourceBundle;
import org.apache.cxf.attachment.AttachmentSerializer;
@@ -54,7 +57,8 @@
return;
}
- AttachmentSerializer serializer = new AttachmentSerializer(message);
+ AttachmentSerializer serializer =
+ new AttachmentSerializer(message, getMultipartType(), getRootHeaders());
serializer.setXop(mtomEnabled);
try {
@@ -67,6 +71,14 @@
// Add a final interceptor to write attachements
message.getInterceptorChain().add(ending);
}
+
+ protected String getMultipartType() {
+ return "multipart/related";
+ }
+
+ protected Map<String, List<String>> getRootHeaders() {
+ return Collections.emptyMap();
+ }
public class AttachmentOutEndingInterceptor extends AbstractPhaseInterceptor<Message> {
public AttachmentOutEndingInterceptor() {
@@ -85,4 +97,6 @@
}
}
+
+
}
Modified: cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java?rev=812265&r1=812264&r2=812265&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java (original)
+++ cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java Mon Sep 7 20:08:23 2009
@@ -352,7 +352,7 @@
mbw.writeTo(o, cls, type, anns, contentType, headers, os);
os.flush();
} catch (Exception ex) {
- throw new WebApplicationException();
+ throw new WebApplicationException(ex);
}
} else {
@@ -395,7 +395,7 @@
return mbr.readFrom(cls, type, anns, contentType,
new MetadataMap<String, Object>(r.getMetadata(), true, true), inputStream);
} catch (Exception ex) {
- throw new WebApplicationException();
+ throw new WebApplicationException(ex);
}
} else if (cls == Response.class) {
Modified: cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java?rev=812265&r1=812264&r2=812265&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java (original)
+++ cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java Mon Sep 7 20:08:23 2009
@@ -21,8 +21,10 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
import java.net.HttpURLConnection;
import java.net.URI;
+import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
@@ -40,6 +42,7 @@
import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBusFactory;
+import org.apache.cxf.helpers.CastUtils;
import org.apache.cxf.interceptor.AbstractOutDatabindingInterceptor;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.jaxrs.ext.form.Form;
@@ -200,7 +203,7 @@
* error message if client or server error occured
*/
public Response invoke(String httpMethod, Object body) {
- return doInvoke(httpMethod, body, InputStream.class);
+ return doInvoke(httpMethod, body, InputStream.class, InputStream.class);
}
/**
@@ -260,7 +263,7 @@
*/
public Response form(Map<String, List<Object>> values) {
type(MediaType.APPLICATION_FORM_URLENCODED_TYPE);
- return doInvoke("POST", values, InputStream.class);
+ return doInvoke("POST", values, InputStream.class, InputStream.class);
}
/**
@@ -270,7 +273,7 @@
*/
public Response form(Form form) {
type(MediaType.APPLICATION_FORM_URLENCODED_TYPE);
- return doInvoke("POST", form.getData(), InputStream.class);
+ return doInvoke("POST", form.getData(), InputStream.class, InputStream.class);
}
/**
@@ -283,7 +286,7 @@
*/
public <T> T invoke(String httpMethod, Object body, Class<T> responseClass) {
- Response r = doInvoke(httpMethod, body, responseClass);
+ Response r = doInvoke(httpMethod, body, responseClass, responseClass);
if (r.getStatus() >= 400 && responseClass != null) {
throw new WebApplicationException(r);
@@ -293,6 +296,25 @@
}
/**
+ * Does HTTP invocation and returns a collection of typed objects
+ * @param httpMethod HTTP method
+ * @param body request body, can be null
+ * @param memberClass expected type of collection member class
+ * @return typed collection
+ */
+ public <T> Collection<T> invokeAndGetCollection(String httpMethod, Object body,
+ Class<T> memberClass) {
+
+ Response r = doInvoke(httpMethod, body, Collection.class, memberClass);
+
+ if (r.getStatus() >= 400) {
+ throw new WebApplicationException(r);
+ }
+
+ return CastUtils.cast((Collection)r.getEntity(), memberClass);
+ }
+
+ /**
* Does HTTP POST invocation and returns typed response object
* @param body request body, can be null
* @param responseClass expected type of response object
@@ -304,6 +326,26 @@
}
/**
+ * Does HTTP POST invocation and returns a collection of typed objects
+ * @param body request body, can be null
+ * @param memberClass expected type of collection member class
+ * @return typed collection
+ */
+ public <T> Collection<T> postAndGetCollection(Object body, Class<T> memberClass) {
+ return invokeAndGetCollection("POST", body, memberClass);
+ }
+
+ /**
+ * Does HTTP GET invocation and returns a collection of typed objects
+ * @param body request body, can be null
+ * @param memberClass expected type of collection member class
+ * @return typed collection
+ */
+ public <T> Collection<T> getCollection(Class<T> memberClass) {
+ return invokeAndGetCollection("GET", null, memberClass);
+ }
+
+ /**
* Does HTTP GET invocation and returns typed response object
* @param body request body, can be null
* @param responseClass expected type of response object
@@ -492,7 +534,7 @@
return (WebClient)super.reset();
}
- protected Response doInvoke(String httpMethod, Object body, Class<?> responseClass) {
+ protected Response doInvoke(String httpMethod, Object body, Class<?> responseClass, Type genericType) {
MultivaluedMap<String, String> headers = getHeaders();
if (body != null) {
@@ -507,7 +549,7 @@
}
resetResponse();
try {
- return doChainedInvocation(httpMethod, headers, body, responseClass);
+ return doChainedInvocation(httpMethod, headers, body, responseClass, genericType);
} finally {
clearTemplates();
}
@@ -515,7 +557,7 @@
}
protected Response doChainedInvocation(String httpMethod,
- MultivaluedMap<String, String> headers, Object body, Class<?> responseClass) {
+ MultivaluedMap<String, String> headers, Object body, Class<?> responseClass, Type genericType) {
Message m = createMessage(httpMethod, headers, getCurrentURI());
m.put(URITemplate.TEMPLATE_PARAMETERS, templates);
@@ -533,15 +575,16 @@
// TODO : this needs to be done in an inbound chain instead
HttpURLConnection connect = (HttpURLConnection)m.get(HTTPConduit.KEY_HTTP_CONNECTION);
- return handleResponse(connect, m, responseClass);
+ return handleResponse(connect, m, responseClass, genericType);
}
- protected Response handleResponse(HttpURLConnection conn, Message outMessage, Class<?> responseClass) {
+ protected Response handleResponse(HttpURLConnection conn, Message outMessage,
+ Class<?> responseClass, Type genericType) {
try {
ResponseBuilder rb = setResponseBuilder(conn, outMessage.getExchange()).clone();
Response currentResponse = rb.clone().build();
- Object entity = readBody(currentResponse, conn, outMessage, responseClass, responseClass,
+ Object entity = readBody(currentResponse, conn, outMessage, responseClass, genericType,
new Annotation[]{});
rb.entity(entity);
Modified: cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java?rev=812265&r1=812264&r2=812265&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java (original)
+++ cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java Mon Sep 7 20:08:23 2009
@@ -21,6 +21,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
@@ -39,10 +40,14 @@
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Providers;
+import org.apache.cxf.attachment.AttachmentImpl;
import org.apache.cxf.attachment.AttachmentUtil;
+import org.apache.cxf.endpoint.Endpoint;
+import org.apache.cxf.interceptor.AttachmentOutInterceptor;
import org.apache.cxf.jaxrs.ext.multipart.Attachment;
import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
import org.apache.cxf.jaxrs.interceptor.AttachmentInputInterceptor;
+import org.apache.cxf.jaxrs.interceptor.AttachmentOutputInterceptor;
import org.apache.cxf.jaxrs.utils.JAXRSUtils;
import org.apache.cxf.message.Message;
@@ -120,27 +125,69 @@
}
public void put(Object key, Object value) {
+ if (MultipartBody.OUTBOUND_MESSAGE_ATTACHMENTS.equals(key.toString())) {
+ convertToAttachments(value);
+ }
m.put(key.toString(), value);
}
+ private void convertToAttachments(Object value) {
+ List<?> handlers = (List)value;
+ List<org.apache.cxf.message.Attachment> atts =
+ new ArrayList<org.apache.cxf.message.Attachment>();
+
+ for (int i = 1; i < handlers.size(); i++) {
+ Attachment handler = (Attachment)handlers.get(i);
+ AttachmentImpl att = new AttachmentImpl(handler.getContentId(), handler.getDataHandler());
+ for (String key : handler.getHeaders().keySet()) {
+ att.setHeader(key, att.getHeader(key));
+ }
+ att.setXOP(false);
+ atts.add(att);
+ }
+ Message outMessage = getOutMessage();
+ outMessage.setAttachments(atts);
+ outMessage.put(AttachmentOutInterceptor.WRITE_ATTACHMENTS, "true");
+ Attachment root = (Attachment)handlers.get(0);
+ AttachmentOutputInterceptor attInterceptor =
+ new AttachmentOutputInterceptor(outMessage.get(Message.CONTENT_TYPE).toString(),
+ root.getHeaders());
+
+ outMessage.put(Message.CONTENT_TYPE, root.getContentType().toString());
+ attInterceptor.handleMessage(outMessage);
+ }
+
+ private Message getOutMessage() {
+
+ Message message = m.getExchange().getOutMessage();
+ if (message == null) {
+ Endpoint ep = m.getExchange().get(Endpoint.class);
+ message = ep.getBinding().createMessage();
+ m.getExchange().setOutMessage(message);
+ }
+
+ return message;
+ }
+
private MultipartBody createAttachments(String propertyName) {
- Object o = m.get(propertyName);
+ Message inMessage = m.getExchange().getInMessage();
+ Object o = inMessage.get(propertyName);
if (o != null) {
return (MultipartBody)o;
}
- new AttachmentInputInterceptor().handleMessage(m);
+ new AttachmentInputInterceptor().handleMessage(inMessage);
List<Attachment> newAttachments = new LinkedList<Attachment>();
try {
Attachment first = new Attachment(AttachmentUtil.createAttachment(
- m.getContent(InputStream.class),
- (InternetHeaders)m.get(InternetHeaders.class.getName())));
+ inMessage.getContent(InputStream.class),
+ (InternetHeaders)inMessage.get(InternetHeaders.class.getName())));
newAttachments.add(first);
} catch (IOException ex) {
throw new WebApplicationException(500);
}
- Collection<org.apache.cxf.message.Attachment> childAttachments = m.getAttachments();
+ Collection<org.apache.cxf.message.Attachment> childAttachments = inMessage.getAttachments();
if (childAttachments == null) {
childAttachments = Collections.emptyList();
}
@@ -149,7 +196,7 @@
newAttachments.add(new Attachment(a));
}
MultipartBody body = new MultipartBody(newAttachments, getHttpHeaders().getMediaType(), false);
- m.put(propertyName, body);
+ inMessage.put(propertyName, body);
return body;
}
Modified: cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/Attachment.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/Attachment.java?rev=812265&r1=812264&r2=812265&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/Attachment.java (original)
+++ cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/Attachment.java Mon Sep 7 20:08:23 2009
@@ -32,22 +32,26 @@
public class Attachment {
private DataHandler handler;
- private MultivaluedMap<String, String> headers = new MetadataMap<String, String>();
- private String contentId;
+ private MultivaluedMap<String, String> headers =
+ new MetadataMap<String, String>(false, true);
+ private Object object;
public Attachment(org.apache.cxf.message.Attachment a) {
handler = a.getDataHandler();
- contentId = a.getId();
for (Iterator<String> i = a.getHeaderNames(); i.hasNext();) {
String name = i.next();
+ if ("Content-ID".equalsIgnoreCase(name)) {
+ continue;
+ }
headers.add(name, a.getHeader(name));
}
+ headers.putSingle("Content-ID", a.getId());
}
public Attachment(String id, DataHandler dh, MultivaluedMap<String, String> headers) {
handler = dh;
- contentId = id;
- this.headers = new MetadataMap<String, String>(headers);
+ this.headers = new MetadataMap<String, String>(headers, false, true);
+ this.headers.putSingle("Content-ID", id);
}
public Attachment(String id, DataSource ds, MultivaluedMap<String, String> headers) {
@@ -60,6 +64,19 @@
headers);
}
+ public Attachment(String id, String mediaType, Object object) {
+ this.object = object;
+ headers.putSingle("Content-ID", id);
+ headers.putSingle("Content-Type", mediaType);
+ }
+
+ public Attachment(String id, InputStream is, ContentDisposition cd) {
+ handler = new DataHandler(new InputStreamDataSource(is, "application/octet-stream"));
+ headers.putSingle("Content-Disposition", cd.toString());
+ headers.putSingle("Content-ID", id);
+ headers.putSingle("Content-Type", "application/octet-stream");
+ }
+
public ContentDisposition getContentDisposition() {
String header = getHeader("Content-Disposition");
@@ -67,11 +84,11 @@
}
public String getContentId() {
- return contentId;
+ return headers.getFirst("Content-ID");
}
public MediaType getContentType() {
- String value = handler.getContentType();
+ String value = handler != null ? handler.getContentType() : headers.getFirst("Content-Type");
return value == null ? MediaType.TEXT_PLAIN_TYPE : MediaType.valueOf(value);
}
@@ -79,14 +96,27 @@
return handler;
}
+ public Object getObject() {
+ return object;
+ }
+
public String getHeader(String name) {
- String header = headers.getFirst(name);
- return header == null ? headers.getFirst(name.toLowerCase()) : header;
+ List<String> header = headers.get(name);
+ if (header == null || header.size() == 0) {
+ return null;
+ }
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < header.size(); i++) {
+ sb.append(header.get(i));
+ if (i + 1 < header.size()) {
+ sb.append(',');
+ }
+ }
+ return sb.toString();
}
public List<String> getHeaderAsList(String name) {
- List<String> header = headers.get(name);
- return header == null ? headers.get(name.toLowerCase()) : header;
+ return headers.get(name);
}
public MultivaluedMap<String, String> getHeaders() {
@@ -95,7 +125,7 @@
@Override
public int hashCode() {
- return contentId.hashCode() + 37 * headers.hashCode();
+ return headers.hashCode();
}
@Override
@@ -105,7 +135,7 @@
}
Attachment other = (Attachment)o;
- return contentId.equals(other.contentId) && headers.equals(other.headers);
+ return headers.equals(other.headers);
}
Modified: cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/ContentDisposition.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/ContentDisposition.java?rev=812265&r1=812264&r2=812265&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/ContentDisposition.java (original)
+++ cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/ContentDisposition.java Mon Sep 7 20:08:23 2009
@@ -56,4 +56,17 @@
return map;
}
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < values.size(); i++) {
+ if (values.get(i).length() == 0) {
+ continue;
+ }
+ sb.append(values.get(i));
+ if (i + 1 < values.size()) {
+ sb.append(';');
+ }
+ }
+ return sb.toString();
+ }
}
Modified: cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/Multipart.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/Multipart.java?rev=812265&r1=812264&r2=812265&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/Multipart.java (original)
+++ cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/Multipart.java Mon Sep 7 20:08:23 2009
@@ -24,7 +24,7 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
-@Target({ElementType.PARAMETER, ElementType.FIELD })
+@Target({ElementType.PARAMETER, ElementType.FIELD, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface Multipart {
String value() default "root";
Modified: cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/MultipartBody.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/MultipartBody.java?rev=812265&r1=812264&r2=812265&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/MultipartBody.java (original)
+++ cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/multipart/MultipartBody.java Mon Sep 7 20:08:23 2009
@@ -44,6 +44,13 @@
this(atts, MULTIPART_RELATED_TYPE, outbound);
}
+ public MultipartBody(Attachment att) {
+ atts = new ArrayList<Attachment>();
+ atts.add(att);
+ outbound = true;
+ this.mt = MULTIPART_RELATED_TYPE;
+ }
+
public MultipartBody(List<Attachment> atts) {
this(atts, MULTIPART_RELATED_TYPE, false);
}
Modified: cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java?rev=812265&r1=812264&r2=812265&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java (original)
+++ cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java Mon Sep 7 20:08:23 2009
@@ -173,6 +173,7 @@
ori = JAXRSUtils.findTargetMethod(resource, values.getFirst(URITemplate.FINAL_MATCH_GROUP),
httpMethod, values, requestContentType, acceptContentTypes);
message.getExchange().put(OperationResourceInfo.class, ori);
+ message.put(URITemplate.TEMPLATE_PARAMETERS, values);
} catch (WebApplicationException ex) {
if (ex.getResponse() != null && ex.getResponse().getStatus() == 405
&& "OPTIONS".equalsIgnoreCase(httpMethod)) {
Modified: cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/FormEncodingProvider.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/FormEncodingProvider.java?rev=812265&r1=812264&r2=812265&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/FormEncodingProvider.java (original)
+++ cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/FormEncodingProvider.java Mon Sep 7 20:08:23 2009
@@ -47,11 +47,11 @@
import org.apache.cxf.jaxrs.utils.HttpUtils;
import org.apache.cxf.jaxrs.utils.multipart.AttachmentUtils;
-@Produces("application/x-www-form-urlencoded")
+@Produces({"application/x-www-form-urlencoded", "multipart/form-data" })
@Consumes({"application/x-www-form-urlencoded", "multipart/form-data" })
@Provider
public class FormEncodingProvider implements
- MessageBodyReader<Object>, MessageBodyWriter<MultivaluedMap<String, String>> {
+ MessageBodyReader<Object>, MessageBodyWriter<Object> {
private FormValidator validator;
@Context private MessageContext mc;
@@ -72,9 +72,7 @@
public boolean isReadable(Class<?> type, Type genericType,
Annotation[] annotations, MediaType mt) {
- return MultivaluedMap.class.isAssignableFrom(type)
- || mt.isCompatible(MediaType.MULTIPART_FORM_DATA_TYPE)
- && MultipartBody.class.isAssignableFrom(type);
+ return isSupported(type, genericType, annotations, mt);
}
public Object readFrom(
@@ -133,7 +131,7 @@
}
}
- public long getSize(MultivaluedMap<String, String> t, Class<?> type,
+ public long getSize(Object t, Class<?> type,
Type genericType, Annotation[] annotations,
MediaType mediaType) {
return -1;
@@ -141,26 +139,43 @@
public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations,
MediaType mediaType) {
- return MultivaluedMap.class.isAssignableFrom(type);
+ return isSupported(type, genericType, annotations, mediaType);
}
- public void writeTo(MultivaluedMap<String, String> map, Class<?> c, Type t, Annotation[] anns,
+ private boolean isSupported(Class<?> type, Type genericType, Annotation[] annotations,
+ MediaType mt) {
+ return MultivaluedMap.class.isAssignableFrom(type)
+ || mt.isCompatible(MediaType.MULTIPART_FORM_DATA_TYPE)
+ && MultipartBody.class.isAssignableFrom(type);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void writeTo(Object obj, Class<?> c, Type t, Annotation[] anns,
MediaType mt, MultivaluedMap<String, Object> headers, OutputStream os)
throws IOException, WebApplicationException {
- boolean encoded = AnnotationUtils.getAnnotation(anns, Encoded.class) != null;
- for (Iterator<Map.Entry<String, List<String>>> it = map.entrySet().iterator(); it.hasNext();) {
- Map.Entry<String, List<String>> entry = it.next();
- for (Iterator<String> entryIterator = entry.getValue().iterator(); entryIterator.hasNext();) {
- String value = entryIterator.next();
- os.write(entry.getKey().getBytes("UTF-8"));
- os.write('=');
- String data = encoded ? value : HttpUtils.urlEncode(value);
- os.write(data.getBytes("UTF-8"));
- if (entryIterator.hasNext() || it.hasNext()) {
- os.write('&');
+
+ if (mt.isCompatible(MediaType.MULTIPART_FORM_DATA_TYPE)) {
+ MultipartBody body = (MultipartBody)obj;
+ MultipartProvider provider = new MultipartProvider();
+ provider.setMessageContext(mc);
+ provider.writeTo(body, body.getClass(), body.getClass(), anns, mt, headers, os);
+ } else {
+ MultivaluedMap<String, String> map = (MultivaluedMap<String, String>)obj;
+ boolean encoded = AnnotationUtils.getAnnotation(anns, Encoded.class) != null;
+ for (Iterator<Map.Entry<String, List<String>>> it = map.entrySet().iterator(); it.hasNext();) {
+ Map.Entry<String, List<String>> entry = it.next();
+ for (Iterator<String> entryIterator = entry.getValue().iterator(); entryIterator.hasNext();) {
+ String value = entryIterator.next();
+ os.write(entry.getKey().getBytes("UTF-8"));
+ os.write('=');
+ String data = encoded ? value : HttpUtils.urlEncode(value);
+ os.write(data.getBytes("UTF-8"));
+ if (entryIterator.hasNext() || it.hasNext()) {
+ os.write('&');
+ }
}
+
}
-
}
}
Modified: cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/Messages.properties
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/Messages.properties?rev=812265&r1=812264&r2=812265&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/Messages.properties (original)
+++ cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/Messages.properties Mon Sep 7 20:08:23 2009
@@ -21,4 +21,5 @@
JAXB_EXCEPTION=JAXBException occurred : {0}
UNSUPPORTED_ENCODING=Unsupported encoding : {0}, defaulting to UTF-8
NO_COLLECTION_ROOT=No collection name is provided
+NO_MSG_WRITER =.No message body writer found for class : {0}.
Modified: cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/MultipartProvider.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/MultipartProvider.java?rev=812265&r1=812264&r2=812265&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/MultipartProvider.java (original)
+++ cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/MultipartProvider.java Mon Sep 7 20:08:23 2009
@@ -21,36 +21,62 @@
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
import java.util.List;
+import java.util.Map;
+import java.util.ResourceBundle;
+import java.util.logging.Logger;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.ws.rs.Consumes;
+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.ext.MessageBodyReader;
+import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
+import org.apache.cxf.attachment.AttachmentUtil;
+import org.apache.cxf.attachment.ByteDataSource;
+import org.apache.cxf.common.i18n.BundleUtils;
+import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.jaxrs.ext.MessageContext;
import org.apache.cxf.jaxrs.ext.multipart.Attachment;
+import org.apache.cxf.jaxrs.ext.multipart.InputStreamDataSource;
+import org.apache.cxf.jaxrs.ext.multipart.Multipart;
import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
+import org.apache.cxf.jaxrs.impl.MetadataMap;
+import org.apache.cxf.jaxrs.utils.AnnotationUtils;
import org.apache.cxf.jaxrs.utils.InjectionUtils;
import org.apache.cxf.jaxrs.utils.multipart.AttachmentUtils;
@Provider
@Consumes({"multipart/related", "multipart/mixed", "multipart/alternative" })
-public class MultipartProvider implements MessageBodyReader<Object> {
+@Produces({"multipart/related", "multipart/mixed", "multipart/alternative" })
+public class MultipartProvider
+ implements MessageBodyReader<Object>, MessageBodyWriter<Object> {
+
+ private static final Logger LOG = LogUtils.getL7dLogger(MultipartProvider.class);
+ private static final ResourceBundle BUNDLE = BundleUtils.getBundle(MultipartProvider.class);
@Context
private MessageContext mc;
private String attachmentDir;
private String attachmentThreshold;
+ public void setMessageContext(MessageContext context) {
+ this.mc = context;
+ }
+
public void setAttachmentDirectory(String dir) {
attachmentDir = dir;
}
@@ -61,6 +87,11 @@
public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations,
MediaType mt) {
+ return isSupported(type, genericType, annotations, mt);
+ }
+
+ private boolean isSupported(Class<?> type, Type genericType, Annotation[] annotations,
+ MediaType mt) {
if (DataHandler.class.isAssignableFrom(type) || DataSource.class.isAssignableFrom(type)
|| Attachment.class.isAssignableFrom(type) || MultipartBody.class.isAssignableFrom(type)
|| mediaTypeSupported(mt)) {
@@ -76,12 +107,13 @@
List<Attachment> infos =
AttachmentUtils.getAttachments(mc, attachmentDir, attachmentThreshold);
- if (List.class.isAssignableFrom(c)) {
+ if (Collection.class.isAssignableFrom(c)) {
Class<?> actual = InjectionUtils.getActualType(t);
- if (actual.isAssignableFrom(Attachment.class)) {
+ actual = actual != null ? actual : Object.class;
+ if (Attachment.class.isAssignableFrom(actual)) {
return infos;
}
- List<Object> objects = new ArrayList<Object>();
+ Collection<Object> objects = new ArrayList<Object>();
for (Attachment a : infos) {
objects.add(fromAttachment(a, actual, actual, anns));
}
@@ -122,4 +154,182 @@
return mt.getType().equals("multipart") && (mt.getSubtype().equals("related")
|| mt.getSubtype().equals("mixed") || mt.getSubtype().equals("alternative"));
}
+
+ public long getSize(Object t, Class<?> type, Type genericType, Annotation[] annotations,
+ MediaType mediaType) {
+ return -1;
+ }
+
+ public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations,
+ MediaType mt) {
+ return isSupported(type, genericType, annotations, mt);
+ }
+
+
+ public void writeTo(Object obj, Class<?> type, Type genericType, Annotation[] anns, MediaType mt,
+ MultivaluedMap<String, Object> headers, OutputStream os)
+ throws IOException, WebApplicationException {
+
+ List<Attachment> handlers = convertToDataHandlers(obj, type, genericType, anns, mt);
+ mc.put(MultipartBody.OUTBOUND_MESSAGE_ATTACHMENTS, handlers);
+ handlers.get(0).getDataHandler().writeTo(os);
+ }
+
+ @SuppressWarnings("unchecked")
+ private List<Attachment> convertToDataHandlers(Object obj,
+ Class<?> type, Type genericType,
+ Annotation[] anns, MediaType mt) {
+ if (Map.class.isAssignableFrom(obj.getClass())) {
+ Map<Object, Object> objects = (Map)obj;
+ List<Attachment> handlers = new ArrayList<Attachment>(objects.size());
+ int i = 0;
+ for (Iterator<Map.Entry<Object, Object>> iter = objects.entrySet().iterator();
+ iter.hasNext();) {
+ Map.Entry entry = iter.next();
+ Object value = entry.getValue();
+ Attachment handler = createDataHandler(value, value.getClass(), value.getClass(),
+ new Annotation[]{},
+ entry.getKey().toString(),
+ i++);
+ handlers.add(handler);
+ }
+ return handlers;
+ } else {
+ String rootMediaType = getRootMediaType(anns, mt);
+ if (List.class.isAssignableFrom(obj.getClass())) {
+ return getAttachments((List)obj, rootMediaType);
+ } else {
+ if (MultipartBody.class.isAssignableFrom(type)) {
+ List<Attachment> atts = ((MultipartBody)obj).getAllAttachments();
+ // these attachments may have no DataHandlers, but objects only
+ return getAttachments(atts, rootMediaType);
+ }
+ Attachment handler = createDataHandler(obj,
+ type, genericType, anns,
+ rootMediaType, 1);
+ return Collections.singletonList(handler);
+ }
+ }
+ }
+
+ private List<Attachment> getAttachments(List<?> objects, String rootMediaType) {
+ List<Attachment> handlers = new ArrayList<Attachment>(objects.size());
+ for (int i = 0; i < objects.size(); i++) {
+ Object value = objects.get(i);
+ Attachment handler = createDataHandler(value,
+ value.getClass(), value.getClass(), new Annotation[]{},
+ rootMediaType, i);
+ handlers.add(handler);
+ }
+ return handlers;
+ }
+
+ private Attachment createDataHandler(Object obj,
+ Class<?> cls, Type genericType,
+ Annotation[] anns,
+ String mimeType, int id) {
+ DataHandler dh = null;
+ if (InputStream.class.isAssignableFrom(obj.getClass())) {
+ dh = createInputStreamDH((InputStream)obj, mimeType);
+ } else if (DataHandler.class.isAssignableFrom(obj.getClass())) {
+ dh = (DataHandler)obj;
+ } else if (DataSource.class.isAssignableFrom(obj.getClass())) {
+ dh = new DataHandler((DataSource)obj);
+ } else if (Attachment.class.isAssignableFrom(obj.getClass())) {
+ Attachment att = (Attachment)obj;
+ if (att.getObject() == null) {
+ return att;
+ }
+ dh = getHandlerForObject(att.getObject(), att.getObject().getClass(),
+ att.getObject().getClass(), new Annotation[]{},
+ att.getContentType().toString(), id);
+ return new Attachment(att.getContentId(), dh, att.getHeaders());
+ } else if (byte[].class.isAssignableFrom(obj.getClass())) {
+ ByteDataSource source = new ByteDataSource((byte[])obj);
+ source.setContentType(mimeType);
+ dh = new DataHandler(source);
+ } else {
+ dh = getHandlerForObject(obj, cls, genericType, anns, mimeType, id);
+ }
+ String contentId = id == 0 ? AttachmentUtil.BODY_ATTACHMENT_ID : Integer.toString(id);
+ return new Attachment(contentId, dh, new MetadataMap<String, String>());
+ }
+
+ @SuppressWarnings("unchecked")
+ private DataHandler getHandlerForObject(Object obj,
+ Class<?> cls, Type genericType,
+ Annotation[] anns,
+ String mimeType, int id) {
+ MediaType mt = MediaType.valueOf(mimeType);
+ MessageBodyWriter<Object> r =
+ (MessageBodyWriter)mc.getProviders().getMessageBodyWriter(cls, genericType, anns, mt);
+ if (r == null) {
+ org.apache.cxf.common.i18n.Message message =
+ new org.apache.cxf.common.i18n.Message("NO_MSG_WRITER",
+ BUNDLE,
+ cls);
+ LOG.severe(message.toString());
+ throw new WebApplicationException(500);
+ }
+ return new MessageBodyWriterDataHandler(r, obj, cls, genericType, anns, mt);
+ }
+
+ private DataHandler createInputStreamDH(InputStream is, String mimeType) {
+ return new DataHandler(new InputStreamDataSource(is, mimeType));
+ }
+
+ private String getRootMediaType(Annotation[] anns, MediaType mt) {
+ String mimeType = mt.getParameters().get("type");
+ if (mimeType != null) {
+ return mimeType;
+ }
+ Multipart id = AnnotationUtils.getAnnotation(anns, Multipart.class);
+ if (id != null && !MediaType.WILDCARD.equals(id.type())) {
+ mimeType = id.type();
+ }
+ if (mimeType == null) {
+ mimeType = MediaType.APPLICATION_OCTET_STREAM;
+ }
+ return mimeType;
+ }
+
+ private static class MessageBodyWriterDataHandler extends DataHandler {
+ private MessageBodyWriter<Object> writer;
+ private Object obj;
+ private Class<?> cls;
+ private Type genericType;
+ private Annotation[] anns;
+ private MediaType contentType;
+ public MessageBodyWriterDataHandler(MessageBodyWriter<Object> writer,
+ Object obj,
+ Class<?> cls,
+ Type genericType,
+ Annotation[] anns,
+ MediaType contentType) {
+ super(new ByteDataSource("1".getBytes()));
+ this.writer = writer;
+ this.obj = obj;
+ this.cls = cls;
+ this.genericType = genericType;
+ this.anns = anns;
+ this.contentType = contentType;
+ }
+
+ @Override
+ public void writeTo(OutputStream os) {
+ try {
+ writer.writeTo(obj, cls, genericType, anns, contentType,
+ new MetadataMap<String, Object>(), os);
+ } catch (IOException ex) {
+ throw new WebApplicationException();
+ }
+ }
+
+ @Override
+ public String getContentType() {
+ return contentType.toString();
+ }
+
+ // TODO : throw UnsupportedOperationException for all other DataHandler methods
+ }
}
Modified: cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java?rev=812265&r1=812264&r2=812265&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java (original)
+++ cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/InjectionUtils.java Mon Sep 7 20:08:23 2009
@@ -198,7 +198,7 @@
}
if (!ParameterizedType.class.isAssignableFrom(genericType.getClass())) {
Class<?> cls = (Class<?>)genericType;
- return cls.isArray() ? cls.getComponentType() : null;
+ return cls.isArray() ? cls.getComponentType() : cls;
}
ParameterizedType paramType = (ParameterizedType)genericType;
Type[] types = paramType.getActualTypeArguments();
Modified: cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java?rev=812265&r1=812264&r2=812265&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java (original)
+++ cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java Mon Sep 7 20:08:23 2009
@@ -699,7 +699,7 @@
if (UriInfo.class.isAssignableFrom(clazz)) {
o = createUriInfo(contextMessage);
} else if (HttpHeaders.class.isAssignableFrom(clazz)) {
- o = new HttpHeadersImpl(contextMessage);
+ o = createHttpHeaders(contextMessage);
} else if (Request.class.isAssignableFrom(clazz)) {
o = new RequestImpl(contextMessage);
} else if (SecurityContext.class.isAssignableFrom(clazz)) {
@@ -726,6 +726,14 @@
return new UriInfoImpl(m, templateParams);
}
+ @SuppressWarnings("unchecked")
+ private static HttpHeaders createHttpHeaders(Message m) {
+ if (MessageUtils.isRequestor(m)) {
+ m = m.getExchange() != null ? m.getExchange().getOutMessage() : m;
+ }
+ return new HttpHeadersImpl(m);
+ }
+
public static ContextResolver<?> createContextResolver(Type genericType, Message m) {
if (genericType instanceof ParameterizedType) {
return ProviderFactory.getInstance(m).createContextResolver(
Modified: cxf/branches/2.2.x-fixes/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java?rev=812265&r1=812264&r2=812265&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java (original)
+++ cxf/branches/2.2.x-fixes/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HTTPConduit.java Mon Sep 7 20:08:23 2009
@@ -857,6 +857,9 @@
Map<String, List<String>> headers = getSetProtocolHeaders(message);
for (String header : headers.keySet()) {
List<String> headerList = headers.get(header);
+ if (HttpHeaderHelper.CONTENT_TYPE.equalsIgnoreCase(header)) {
+ continue;
+ }
if (HttpHeaderHelper.COOKIE.equalsIgnoreCase(header)) {
for (String s : headerList) {
connection.addRequestProperty(HttpHeaderHelper.COOKIE, s);
Modified: cxf/branches/2.2.x-fixes/rt/transports/http/src/test/java/org/apache/cxf/transport/http/HTTPConduitURLEasyMockTest.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/transports/http/src/test/java/org/apache/cxf/transport/http/HTTPConduitURLEasyMockTest.java?rev=812265&r1=812264&r2=812265&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/transports/http/src/test/java/org/apache/cxf/transport/http/HTTPConduitURLEasyMockTest.java (original)
+++ cxf/branches/2.2.x-fixes/rt/transports/http/src/test/java/org/apache/cxf/transport/http/HTTPConduitURLEasyMockTest.java Mon Sep 7 20:08:23 2009
@@ -48,6 +48,7 @@
import org.apache.cxf.ws.addressing.EndpointReferenceType;
import org.easymock.classextension.EasyMock;
import org.easymock.classextension.IMocksControl;
+
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
@@ -138,6 +139,7 @@
control = EasyMock.createNiceControl();
HTTPConduit conduit = setUpConduit(true, false, false);
Message message = new MessageImpl();
+ message.put("Content-Type", "text/xml;charset=utf8");
setUpHeaders(message);
conduit.prepare(message);
verifySentMessage(conduit, message, true);
@@ -564,7 +566,7 @@
connection.setRequestProperty(EasyMock.eq("Authorization"),
EasyMock.eq("Basic Qko6dmFsdWU="));
EasyMock.expectLastCall();
- connection.setRequestProperty(EasyMock.eq("content-type"),
+ connection.setRequestProperty(EasyMock.eq("Content-Type"),
EasyMock.eq("text/xml;charset=utf8"));
EasyMock.expectLastCall();
connection.setRequestProperty(EasyMock.eq("Accept"),
Modified: cxf/branches/2.2.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java?rev=812265&r1=812264&r2=812265&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java (original)
+++ cxf/branches/2.2.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java Mon Sep 7 20:08:23 2009
@@ -20,6 +20,17 @@
package org.apache.cxf.systest.jaxrs;
import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.core.MediaType;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Unmarshaller;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
@@ -27,7 +38,13 @@
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.io.CachedOutputStream;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.cxf.jaxrs.ext.multipart.Attachment;
+import org.apache.cxf.jaxrs.ext.multipart.ContentDisposition;
+import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
+import org.apache.cxf.jaxrs.provider.JSONProvider;
import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
+import org.apache.cxf.transport.http.HTTPConduit;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -178,10 +195,147 @@
doAddBook(address, "attachmentData", 200);
}
+ @Test
+ public void testAddBookWebClient() {
+ InputStream is1 =
+ getClass().getResourceAsStream("/org/apache/cxf/systest/jaxrs/resources/add_book.txt");
+ String address = "http://localhost:9085/bookstore/books/jaxb";
+ WebClient client = WebClient.create(address);
+ client.type("multipart/related;type=text/xml").accept("text/xml");
+ Book book = client.post(is1, Book.class);
+ assertEquals("CXF in Action - 2", book.getName());
+ }
+
+ @Test
+ public void testAddBookJaxbJsonImageWebClient() throws Exception {
+ String address = "http://localhost:9085/bookstore/books/jaxbjsonimage";
+ WebClient client = WebClient.create(address);
+ client.type("multipart/mixed").accept("multipart/mixed");
+
+ Book jaxb = new Book("jaxb", 1L);
+ Book json = new Book("json", 2L);
+ InputStream is1 =
+ getClass().getResourceAsStream("/org/apache/cxf/systest/jaxrs/resources/java.jpg");
+ Map<String, Object> objects = new LinkedHashMap<String, Object>();
+ objects.put(MediaType.APPLICATION_XML, jaxb);
+ objects.put(MediaType.APPLICATION_JSON, json);
+ objects.put(MediaType.APPLICATION_OCTET_STREAM, is1);
+ Collection<Attachment> coll = client.postAndGetCollection(objects, Attachment.class);
+ List<Attachment> result = new ArrayList<Attachment>(coll);
+ Book jaxb2 = readBookFromInputStream(result.get(0).getDataHandler().getInputStream());
+ assertEquals("jaxb", jaxb2.getName());
+ assertEquals(1L, jaxb2.getId());
+ Book json2 = readJSONBookFromInputStream(result.get(1).getDataHandler().getInputStream());
+ assertEquals("json", json2.getName());
+ assertEquals(2L, json2.getId());
+ InputStream is2 = (InputStream)result.get(2).getDataHandler().getInputStream();
+ byte[] image1 = IOUtils.readBytesFromStream(
+ getClass().getResourceAsStream("/org/apache/cxf/systest/jaxrs/resources/java.jpg"));
+ byte[] image2 = IOUtils.readBytesFromStream(is2);
+ assertTrue(Arrays.equals(image1, image2));
+ }
+
+ @Test
+ public void testAddBookJaxbJsonImageAttachments() throws Exception {
+ String address = "http://localhost:9085/bookstore/books/jaxbimagejson";
+ WebClient client = WebClient.create(address);
+ client.type("multipart/mixed").accept("multipart/mixed");
+
+ Book jaxb = new Book("jaxb", 1L);
+ Book json = new Book("json", 2L);
+ InputStream is1 =
+ getClass().getResourceAsStream("/org/apache/cxf/systest/jaxrs/resources/java.jpg");
+ List<Attachment> objects = new ArrayList<Attachment>();
+ objects.add(new Attachment("theroot", MediaType.APPLICATION_XML, jaxb));
+ objects.add(new Attachment("thejson", MediaType.APPLICATION_JSON, json));
+ objects.add(new Attachment("theimage", MediaType.APPLICATION_OCTET_STREAM, is1));
+ Collection<Attachment> coll = client.postAndGetCollection(objects, Attachment.class);
+ List<Attachment> result = new ArrayList<Attachment>(coll);
+ Book jaxb2 = readBookFromInputStream(result.get(0).getDataHandler().getInputStream());
+ assertEquals("jaxb", jaxb2.getName());
+ assertEquals(1L, jaxb2.getId());
+ Book json2 = readJSONBookFromInputStream(result.get(1).getDataHandler().getInputStream());
+ assertEquals("json", json2.getName());
+ assertEquals(2L, json2.getId());
+ InputStream is2 = (InputStream)result.get(2).getDataHandler().getInputStream();
+ byte[] image1 = IOUtils.readBytesFromStream(
+ getClass().getResourceAsStream("/org/apache/cxf/systest/jaxrs/resources/java.jpg"));
+ byte[] image2 = IOUtils.readBytesFromStream(is2);
+ assertTrue(Arrays.equals(image1, image2));
+ }
+
+ @Test
+ public void testAddGetJaxbBooksWebClient() throws Exception {
+ String address = "http://localhost:9085/bookstore/books/jaxbonly";
+ WebClient client = WebClient.create(address);
+ HTTPConduit conduit = WebClient.getConfig(client).getHttpConduit();
+ conduit.getClient().setReceiveTimeout(1000000);
+ conduit.getClient().setConnectionTimeout(1000000);
+ client.type("multipart/mixed;type=application/xml").accept("multipart/mixed");
+
+ Book b = new Book("jaxb", 1L);
+ Book b2 = new Book("jaxb2", 2L);
+ List<Book> books = new ArrayList<Book>();
+ books.add(b);
+ books.add(b2);
+ Collection<Book> coll = client.postAndGetCollection(books, Book.class);
+ List<Book> result = new ArrayList<Book>(coll);
+ Book jaxb = result.get(0);
+ assertEquals("jaxb", jaxb.getName());
+ assertEquals(1L, jaxb.getId());
+ Book jaxb2 = result.get(1);
+ assertEquals("jaxb2", jaxb2.getName());
+ assertEquals(2L, jaxb2.getId());
+ }
+
+ @Test
+ public void testAddGetImageWebClient() throws Exception {
+ InputStream is1 =
+ getClass().getResourceAsStream("/org/apache/cxf/systest/jaxrs/resources/java.jpg");
+ String address = "http://localhost:9085/bookstore/books/image";
+ WebClient client = WebClient.create(address);
+ HTTPConduit conduit = WebClient.getConfig(client).getHttpConduit();
+ conduit.getClient().setReceiveTimeout(1000000);
+ conduit.getClient().setConnectionTimeout(1000000);
+ client.type("multipart/mixed").accept("multipart/mixed");
+ InputStream is2 = client.post(is1, InputStream.class);
+ byte[] image1 = IOUtils.readBytesFromStream(
+ getClass().getResourceAsStream("/org/apache/cxf/systest/jaxrs/resources/java.jpg"));
+ byte[] image2 = IOUtils.readBytesFromStream(is2);
+ assertTrue(Arrays.equals(image1, image2));
+
+ }
+
+ @Test
+ public void testUploadImageFromForm() throws Exception {
+ InputStream is1 =
+ getClass().getResourceAsStream("/org/apache/cxf/systest/jaxrs/resources/java.jpg");
+ String address = "http://localhost:9085/bookstore/books/formimage";
+ WebClient client = WebClient.create(address);
+ HTTPConduit conduit = WebClient.getConfig(client).getHttpConduit();
+ conduit.getClient().setReceiveTimeout(1000000);
+ conduit.getClient().setConnectionTimeout(1000000);
+ client.type("multipart/form-data").accept("multipart/form-data");
+
+ ContentDisposition cd = new ContentDisposition("attachment;filename=java.jpg");
+ Attachment att = new Attachment("image", is1, cd);
+
+ MultipartBody body = new MultipartBody(att);
+ MultipartBody body2 = client.post(body, MultipartBody.class);
+ InputStream is2 = body2.getRootAttachment().getDataHandler().getInputStream();
+ byte[] image1 = IOUtils.readBytesFromStream(
+ getClass().getResourceAsStream("/org/apache/cxf/systest/jaxrs/resources/java.jpg"));
+ byte[] image2 = IOUtils.readBytesFromStream(is2);
+ assertTrue(Arrays.equals(image1, image2));
+ ContentDisposition cd2 = body2.getRootAttachment().getContentDisposition();
+ assertEquals("attachment;filename=java.jpg", cd2.toString());
+ assertEquals("java.jpg", cd.getParameter("filename"));
+ }
+
private void doAddBook(String address, String resourceName, int status) throws Exception {
doAddBook("multipart/related", address, resourceName, status);
}
-
+
private void doAddBook(String type, String address, String resourceName, int status) throws Exception {
PostMethod post = new PostMethod(address);
@@ -215,4 +369,17 @@
return bos.getOut().toString();
}
+ private Book readBookFromInputStream(InputStream is) throws Exception {
+ JAXBContext c = JAXBContext.newInstance(new Class[]{Book.class});
+ Unmarshaller u = c.createUnmarshaller();
+ return (Book)u.unmarshal(is);
+ }
+
+ @SuppressWarnings("unchecked")
+ private Book readJSONBookFromInputStream(InputStream is) throws Exception {
+ JSONProvider provider = new JSONProvider();
+ return (Book)provider.readFrom((Class)Book.class, Book.class, new Annotation[]{},
+ MediaType.APPLICATION_JSON_TYPE, null, is);
+
+ }
}
Modified: cxf/branches/2.2.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java?rev=812265&r1=812264&r2=812265&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java (original)
+++ cxf/branches/2.2.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java Mon Sep 7 20:08:23 2009
@@ -20,8 +20,11 @@
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;
@@ -56,6 +59,52 @@
}
@POST
+ @Path("/books/image")
+ @Consumes("multipart/mixed")
+ @Produces("multipart/mixed")
+ public byte[] addBookImage(byte[] image) throws Exception {
+ return image;
+ }
+
+ @POST
+ @Path("/books/formimage")
+ @Consumes("multipart/form-data")
+ @Produces("multipart/form-data")
+ public MultipartBody addBookFormImage(MultipartBody image) throws Exception {
+ return image;
+ }
+
+ @POST
+ @Path("/books/jaxbjsonimage")
+ @Consumes("multipart/mixed")
+ @Produces("multipart/mixed")
+ 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;
+
+ }
+
+ @POST
@Path("/books/stream")
@Produces("text/xml")
public Response addBookFromStream(StreamSource source) throws Exception {
@@ -149,6 +198,16 @@
}
@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/jaxbjson")
@Produces("text/xml")
public Response addBookJaxbJson(