Author: sergeyb
Date: Wed Jan 21 10:17:31 2009
New Revision: 736358

URL: http://svn.apache.org/viewvc?rev=736358&view=rev
Log:
JAXRS : support for multipart/related

Added:
    
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MultipartID.java
   (with props)
    
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ActivationProvider.java
   (with props)
    
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/AttachmentUtils.java
   (with props)
    
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java
   (with props)
    
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/MultipartServer.java
   (with props)
    
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java
   (with props)
    cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/attachmentData
Modified:
    
cxf/trunk/rt/core/src/main/java/org/apache/cxf/attachment/AttachmentUtil.java
    
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSBindingFactory.java
    
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContext.java
    
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java
    
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/tl/ThreadLocalMessageContext.java
    
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ProviderInfo.java
    
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java
    
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java
    
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java
    
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
    
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
    
cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/context/WrappedMessageContext.java
    
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java

Modified: 
cxf/trunk/rt/core/src/main/java/org/apache/cxf/attachment/AttachmentUtil.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/main/java/org/apache/cxf/attachment/AttachmentUtil.java?rev=736358&r1=736357&r2=736358&view=diff
==============================================================================
--- 
cxf/trunk/rt/core/src/main/java/org/apache/cxf/attachment/AttachmentUtil.java 
(original)
+++ 
cxf/trunk/rt/core/src/main/java/org/apache/cxf/attachment/AttachmentUtil.java 
Wed Jan 21 10:17:31 2009
@@ -24,8 +24,13 @@
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URLEncoder;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Map;
 import java.util.UUID;
 
+import javax.activation.DataHandler;
+
 import org.apache.cxf.helpers.HttpHeaderHelper;
 import org.apache.cxf.message.Attachment;
 
@@ -79,4 +84,19 @@
         return buffer.toString();
     }
 
+    public static Map<String, DataHandler> getDHMap(Collection<Attachment> 
attachments) {
+        Map<String, DataHandler> dataHandlers = null;
+        if (attachments != null) {
+            if (attachments instanceof LazyAttachmentCollection) {
+                dataHandlers = 
((LazyAttachmentCollection)attachments).createDataHandlerMap();
+            } else {
+                //preserve the order of iteration
+                dataHandlers = new LinkedHashMap<String, DataHandler>();
+                for (Attachment attachment : attachments) {
+                    dataHandlers.put(attachment.getId(), 
attachment.getDataHandler());
+                }
+            }
+        }
+        return dataHandlers == null ? new LinkedHashMap<String, DataHandler>() 
: dataHandlers;
+    }
 }

Modified: 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSBindingFactory.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSBindingFactory.java?rev=736358&r1=736357&r2=736358&view=diff
==============================================================================
--- 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSBindingFactory.java
 (original)
+++ 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSBindingFactory.java
 Wed Jan 21 10:17:31 2009
@@ -21,9 +21,9 @@
 
 import org.apache.cxf.binding.AbstractBindingFactory;
 import org.apache.cxf.binding.Binding;
-
 import org.apache.cxf.binding.xml.XMLBinding;
 import org.apache.cxf.binding.xml.interceptor.XMLFaultOutInterceptor;
+import org.apache.cxf.interceptor.AttachmentInInterceptor;
 import org.apache.cxf.interceptor.StaxOutInterceptor;
 import org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor;
 import org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor;
@@ -40,7 +40,10 @@
     public Binding createBinding(BindingInfo bi) {
         XMLBinding binding = new XMLBinding(bi);
 
+        
+        binding.getInInterceptors().add(new AttachmentInInterceptor());
         binding.getInInterceptors().add(new JAXRSInInterceptor());
+        
         binding.getOutInterceptors().add(new JAXRSOutInterceptor());
         
         binding.getOutFaultInterceptors().add(new XMLFaultOutInterceptor());

Modified: 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContext.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContext.java?rev=736358&r1=736357&r2=736358&view=diff
==============================================================================
--- 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContext.java
 (original)
+++ 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContext.java
 Wed Jan 21 10:17:31 2009
@@ -19,6 +19,9 @@
 
 package org.apache.cxf.jaxrs.ext;
 
+import java.util.Map;
+
+import javax.activation.DataHandler;
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
@@ -30,11 +33,18 @@
 import javax.ws.rs.ext.Providers;
 
 /**
- * Represents an inbound internal message
+ * Represents an invocation context
  *
  */
 public interface MessageContext {
+    
+    String INBOUND_MESSAGE_ATTACHMENTS = 
"org.apache.cxf.jaxrs.attachments.inbound";
+    String OUTBOUND_MESSAGE_ATTACHMENTS = 
"org.apache.cxf.jaxrs.attachments.outbound";
+    
     Object get(Object key);
+    void put(Object key, Object value);
+    
+    Map<String, DataHandler> getAttachments();
     
     UriInfo getUriInfo();
     Request getRequest();

Modified: 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java?rev=736358&r1=736357&r2=736358&view=diff
==============================================================================
--- 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java
 (original)
+++ 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContextImpl.java
 Wed Jan 21 10:17:31 2009
@@ -19,7 +19,10 @@
 package org.apache.cxf.jaxrs.ext;
 
 import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.Map;
 
+import javax.activation.DataHandler;
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
@@ -31,7 +34,10 @@
 import javax.ws.rs.ext.ContextResolver;
 import javax.ws.rs.ext.Providers;
 
+import org.apache.cxf.attachment.AttachmentUtil;
+import org.apache.cxf.helpers.CastUtils;
 import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.message.Attachment;
 import org.apache.cxf.message.Message;
 
 public class MessageContextImpl implements MessageContext {
@@ -43,9 +49,16 @@
     }
     
     public Object get(Object key) {
+        if (MessageContext.INBOUND_MESSAGE_ATTACHMENTS.equals(key.toString())) 
{
+            return 
createAttachments(MessageContext.INBOUND_MESSAGE_ATTACHMENTS);
+        }
         return m.get(key);
     }
 
+    public Map<String, DataHandler> getAttachments() {
+        return createAttachments(MessageContext.INBOUND_MESSAGE_ATTACHMENTS);
+    } 
+    
     public <T> T getContext(Class<T> contextClass) {
         return getContext(contextClass, contextClass);
     }
@@ -95,4 +108,20 @@
         return JAXRSUtils.createServletResourceValue(m, ServletContext.class);
     }
 
+    public void put(Object key, Object value) {
+        throw new UnsupportedOperationException("MessageContext.put() is not 
supported yet");
+    }
+
+    private Map<String, DataHandler> createAttachments(String propertyName) {
+        Object o = m.get(propertyName);
+        if (o != null) {
+            return CastUtils.cast((Map)o);
+        }
+        Collection<Attachment> attachments = m.getAttachments();
+        attachments.size();
+        Map<String, DataHandler> dataHandlers = 
AttachmentUtil.getDHMap(attachments);
+        m.put(propertyName, dataHandlers);
+        return dataHandlers;
+    }
+       
 }

Added: 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MultipartID.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MultipartID.java?rev=736358&view=auto
==============================================================================
--- 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MultipartID.java
 (added)
+++ 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MultipartID.java
 Wed Jan 21 10:17:31 2009
@@ -0,0 +1,31 @@
+/**
+ * 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.jaxrs.ext;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+...@target({ElementType.PARAMETER, ElementType.FIELD })
+...@retention(RetentionPolicy.RUNTIME)
+public @interface MultipartID {
+    String value();
+}

Propchange: 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MultipartID.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MultipartID.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/tl/ThreadLocalMessageContext.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/tl/ThreadLocalMessageContext.java?rev=736358&r1=736357&r2=736358&view=diff
==============================================================================
--- 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/tl/ThreadLocalMessageContext.java
 (original)
+++ 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/tl/ThreadLocalMessageContext.java
 Wed Jan 21 10:17:31 2009
@@ -19,6 +19,9 @@
 
 package org.apache.cxf.jaxrs.impl.tl;
 
+import java.util.Map;
+
+import javax.activation.DataHandler;
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
@@ -78,4 +81,16 @@
         return get() != null ? get().getRequest() : null;
     }
 
+    public Map<String, DataHandler> getAttachments() {
+        return get() != null ? get().getAttachments() : null;
+    }
+
+    public void put(Object key, Object value) {
+        if (get() != null) {
+            get().put(key, value);
+        }
+        throw new IllegalStateException("MessageContext is not set");
+        
+    }
+
 }

Modified: 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ProviderInfo.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ProviderInfo.java?rev=736358&r1=736357&r2=736358&view=diff
==============================================================================
--- 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ProviderInfo.java
 (original)
+++ 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ProviderInfo.java
 Wed Jan 21 10:17:31 2009
@@ -36,4 +36,16 @@
     public T getProvider() {
         return provider;
     }
+    
+    public boolean equals(Object obj) {
+        if (!(obj instanceof ProviderInfo)) {
+            return false;
+        }
+        return provider.equals(((ProviderInfo)obj).getProvider());
+    }
+
+    public int hashCode() {
+        return provider.hashCode();
+    }
+
 }

Modified: 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java?rev=736358&r1=736357&r2=736358&view=diff
==============================================================================
--- 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java
 (original)
+++ 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java
 Wed Jan 21 10:17:31 2009
@@ -28,10 +28,8 @@
 import java.util.logging.Logger;
 
 import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
-import javax.ws.rs.ext.ContextResolver;
 import javax.ws.rs.ext.MessageBodyReader;
 import javax.ws.rs.ext.MessageBodyWriter;
 import javax.xml.bind.JAXBContext;
@@ -47,6 +45,7 @@
 import org.apache.cxf.common.i18n.BundleUtils;
 import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.common.util.PackageUtils;
+import org.apache.cxf.jaxrs.ext.MessageContext;
 import org.apache.cxf.jaxrs.utils.AnnotationUtils;
 import org.apache.cxf.jaxrs.utils.InjectionUtils;
 import org.apache.cxf.jaxrs.utils.schemas.SchemaHandler;
@@ -63,10 +62,8 @@
     private static Map<String, JAXBContext> packageContexts = new 
WeakHashMap<String, JAXBContext>();
     private static Map<Class<?>, JAXBContext> classContexts = new 
WeakHashMap<Class<?>, JAXBContext>();
         
-    @Context protected ContextResolver<JAXBContext> resolver;
     private Schema schema;
-    
-        
+            
     public boolean isWriteable(Class<?> type, Type genericType, Annotation[] 
anns, MediaType mt) {
         return isSupported(type, genericType, anns)
                || AnnotationUtils.getAnnotation(anns, 
XmlJavaTypeAdapter.class) != null;
@@ -88,13 +85,15 @@
         return -1;
     }
 
+    // TODO : no contexts can be inhected in superclasses
+    protected abstract MessageContext getContext(); 
+    
     protected JAXBContext getJAXBContext(Class<?> type, Type genericType) 
throws JAXBException {
-        
-        if (resolver != null) {
-            JAXBContext context = resolver.getContext(type);
-            // it's up to the resolver to keep its contexts in a map
-            if (context != null) {
-                return context;
+        MessageContext mc = getContext();
+        if (mc != null) {
+            JAXBContext customContext = mc.getContext(JAXBContext.class);
+            if (customContext != null) {
+                return customContext;
             }
         }
         

Added: 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ActivationProvider.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ActivationProvider.java?rev=736358&view=auto
==============================================================================
--- 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ActivationProvider.java
 (added)
+++ 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ActivationProvider.java
 Wed Jan 21 10:17:31 2009
@@ -0,0 +1,64 @@
+/**
+ * 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.jaxrs.provider;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import javax.activation.DataHandler;
+import javax.activation.DataSource;
+import javax.ws.rs.Consumes;
+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.Provider;
+
+import org.apache.cxf.jaxrs.ext.MessageContext;
+import org.apache.cxf.jaxrs.utils.AttachmentUtils;
+
+...@provider
+...@consumes("multipart/related")
+public class ActivationProvider implements MessageBodyReader<Object> {
+
+    @Context
+    private MessageContext mc;
+    
+    public boolean isReadable(Class<?> type, Type genericType, Annotation[] 
annotations, 
+                              MediaType mediaType) {
+        return DataSource.class.isAssignableFrom(type)
+               || DataHandler.class.isAssignableFrom(type);
+    }
+
+    public Object readFrom(Class<Object> c, Type t, Annotation[] anns, 
MediaType mt, 
+                           MultivaluedMap<String, String> headers, InputStream 
is) 
+        throws IOException, WebApplicationException {
+        
+        Object multipart = AttachmentUtils.getMultipart(c, anns, mt, mc, is);
+        if (multipart != null) {
+            return multipart;
+        }
+        throw new WebApplicationException(404);
+    }
+    
+}

Propchange: 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ActivationProvider.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ActivationProvider.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java?rev=736358&r1=736357&r2=736358&view=diff
==============================================================================
--- 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java
 (original)
+++ 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java
 Wed Jan 21 10:17:31 2009
@@ -31,6 +31,7 @@
 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.Provider;
@@ -40,14 +41,26 @@
 import javax.xml.bind.Unmarshaller;
 import javax.xml.transform.stream.StreamSource;
 
+import org.apache.cxf.jaxrs.ext.MessageContext;
+import org.apache.cxf.jaxrs.utils.AttachmentUtils;
 import org.apache.cxf.jaxrs.utils.schemas.SchemaHandler;
 
 @Produces({"application/xml", "text/xml" })
-...@consumes({"application/xml", "text/xml" })
+...@consumes({"application/xml", "text/xml", 
+           "multipart/related;type=\"text/xml\"",
+           "multipart/related;type=\"application/xml\"" })
 @Provider
 public class JAXBElementProvider extends AbstractJAXBProvider  {
     
+    private static final MediaType MULTIPART_RELATED_TYPE = 
+        MediaType.valueOf("multipart/related");
+    
     private Map<String, Object> mProperties = new HashMap<String, Object>();
+    @Context private MessageContext mc;
+    
+    protected MessageContext getContext() {
+        return mc;
+    }
     
     public void setConsumeMediaTypes(List<String> types) {
         super.setConsumeMediaTypes(types);
@@ -73,10 +86,16 @@
         mProperties.put(Marshaller.JAXB_SCHEMA_LOCATION, schemaLocation);
     }
     
-    public Object readFrom(Class<Object> type, Type genericType, Annotation[] 
annotations, MediaType m, 
+    public Object readFrom(Class<Object> type, Type genericType, Annotation[] 
anns, MediaType mt, 
         MultivaluedMap<String, String> headers, InputStream is) 
         throws IOException {
         try {
+            if (mt.isCompatible(MULTIPART_RELATED_TYPE)) {
+                is = (InputStream)AttachmentUtils.getMultipart(type, anns, mt, 
mc, is);
+                if (is == null) {
+                    throw new WebApplicationException(404);
+                }
+            }
             Class<?> theType = getActualType(type, genericType);
             Unmarshaller unmarshaller = createUnmarshaller(theType, 
genericType);
             

Modified: 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java?rev=736358&r1=736357&r2=736358&view=diff
==============================================================================
--- 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java
 (original)
+++ 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java
 Wed Jan 21 10:17:31 2009
@@ -33,6 +33,7 @@
 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.Provider;
@@ -44,6 +45,7 @@
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
 
+import org.apache.cxf.jaxrs.ext.MessageContext;
 import org.apache.cxf.jaxrs.utils.schemas.SchemaHandler;
 import org.codehaus.jettison.AbstractXMLStreamWriter;
 import org.codehaus.jettison.mapped.Configuration;
@@ -52,7 +54,8 @@
 import org.codehaus.jettison.mapped.MappedXMLStreamWriter;
 
 @Produces("application/json")
-...@consumes("application/json")
+...@consumes({"application/json",
+           "multipart/related;type=\"application/json\"" })
 @Provider
 public class JSONProvider extends AbstractJAXBProvider  {
     
@@ -62,6 +65,11 @@
     private Map<String, String> namespaceMap = new HashMap<String, String>();
     private boolean serializeAsArray;
     private List<String> arrayKeys;
+    @Context private MessageContext mc;
+    
+    protected MessageContext getContext() {
+        return mc;
+    }
     
     public void setConsumeMediaTypes(List<String> types) {
         super.setConsumeMediaTypes(types);

Modified: 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java?rev=736358&r1=736357&r2=736358&view=diff
==============================================================================
--- 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
 (original)
+++ 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
 Wed Jan 21 10:17:31 2009
@@ -98,6 +98,7 @@
                      new SourceProvider(),
                      new FormEncodingReaderProvider(),
                      new PrimitiveTextProvider(),
+                     new ActivationProvider(),
                      new WebApplicationExceptionMapper(),
                      new MappingsHandler());
     }
@@ -403,8 +404,7 @@
         List<MediaType> supportedMediaTypes = 
JAXRSUtils.getProviderConsumeTypes(ep);
         
         List<MediaType> availableMimeTypes = 
-            JAXRSUtils.intersectMimeTypes(Collections.singletonList(mediaType),
-                                          supportedMediaTypes);
+            
JAXRSUtils.intersectMimeTypes(Collections.singletonList(mediaType), 
supportedMediaTypes);
 
         return availableMimeTypes.size() != 0 ? true : false;
         

Added: 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/AttachmentUtils.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/AttachmentUtils.java?rev=736358&view=auto
==============================================================================
--- 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/AttachmentUtils.java
 (added)
+++ 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/AttachmentUtils.java
 Wed Jan 21 10:17:31 2009
@@ -0,0 +1,75 @@
+/**
+ * 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.jaxrs.utils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.util.Map;
+
+import javax.activation.DataHandler;
+import javax.activation.DataSource;
+import javax.mail.util.ByteArrayDataSource;
+import javax.ws.rs.core.MediaType;
+
+import org.apache.cxf.jaxrs.ext.MessageContext;
+import org.apache.cxf.jaxrs.ext.MultipartID;
+
+public final class AttachmentUtils {
+    private AttachmentUtils() {
+    }
+    
+    public static Object getMultipart(Class<Object> c, Annotation[] anns, 
+         MediaType mt, MessageContext mc, InputStream is) throws IOException {
+        InputStream stream = null;
+        MultipartID id = AnnotationUtils.getAnnotation(anns, 
MultipartID.class);
+        if (id != null) {
+            String contentId = id.value();
+            String rootId = mt.getParameters().get("start");
+            if (rootId != null) {
+                rootId = rootId.replace("\"", "").replace("'", "");
+                if (rootId.equalsIgnoreCase(contentId)) {
+                    stream = is;
+                }
+            }
+            if (stream == null) {
+                // TODO: looks like the lazy attachments collection can only 
be accessed this way
+                for (Map.Entry<String, DataHandler> entry : 
mc.getAttachments().entrySet()) {
+                    if (entry.getKey().equals(contentId)) {
+                        DataHandler dh = entry.getValue();
+                        return DataHandler.class.isAssignableFrom(c) ? dh 
+                            : DataSource.class.isAssignableFrom(c) ? 
dh.getDataSource()
+                            : dh.getInputStream();
+                    }
+                }
+            }
+        } else {
+            stream = is;
+        }
+        if (stream != null) {
+            if (DataSource.class.isAssignableFrom(c)) {
+                return new ByteArrayDataSource(stream, mt.toString());
+            } else if (DataHandler.class.isAssignableFrom(c)) {
+                return new DataHandler(new ByteArrayDataSource(stream, 
mt.toString()));
+            } 
+        }
+        return stream;
+    }
+}

Propchange: 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/AttachmentUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/AttachmentUtils.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java?rev=736358&r1=736357&r2=736358&view=diff
==============================================================================
--- 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
 (original)
+++ 
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
 Wed Jan 21 10:17:31 2009
@@ -865,12 +865,17 @@
             for (MediaType userType : userMediaTypes) {
                 if (requiredType.isCompatible(userType) || 
userType.isCompatible(requiredType)) {
                     
+                    boolean parametersMatched = true;
                     for (Map.Entry<String, String> entry : 
userType.getParameters().entrySet()) {
                         String value = 
requiredType.getParameters().get(entry.getKey());
                         if (value != null && !value.equals(entry.getValue())) {
-                            continue;
+                            parametersMatched = false;
+                            break;
                         }
                     }
+                    if (!parametersMatched) {
+                        continue;
+                    }
                     
                     String type = 
requiredType.getType().equals(MediaType.MEDIA_TYPE_WILDCARD) 
                                       ? userType.getType() : 
requiredType.getType();

Modified: 
cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/context/WrappedMessageContext.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/context/WrappedMessageContext.java?rev=736358&r1=736357&r2=736358&view=diff
==============================================================================
--- 
cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/context/WrappedMessageContext.java
 (original)
+++ 
cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/context/WrappedMessageContext.java
 Wed Jan 21 10:17:31 2009
@@ -23,16 +23,14 @@
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Set;
 
 import javax.activation.DataHandler;
 import javax.xml.ws.BindingProvider;
 import javax.xml.ws.handler.MessageContext;
-import javax.xml.ws.handler.MessageContext.Scope;
 
-import org.apache.cxf.attachment.LazyAttachmentCollection;
+import org.apache.cxf.attachment.AttachmentUtil;
 import org.apache.cxf.binding.soap.SoapBindingConstants;
 import org.apache.cxf.configuration.security.AuthorizationPolicy;
 import org.apache.cxf.endpoint.Endpoint;
@@ -290,27 +288,14 @@
             return null;
         }
         Collection<Attachment> attachments = mc.getAttachments();
-        Map<String, DataHandler> dataHandlers = getDHMap(attachments);
+        Map<String, DataHandler> dataHandlers = 
+            AttachmentUtil.getDHMap(attachments);
         mc.put(propertyName, 
                dataHandlers);
         scopes.put(propertyName, Scope.APPLICATION);
         return dataHandlers;
     }    
-    private static Map<String, DataHandler> getDHMap(Collection<Attachment> 
attachments) {
-        Map<String, DataHandler> dataHandlers = null;
-        if (attachments != null) {
-            if (attachments instanceof LazyAttachmentCollection) {
-                dataHandlers = 
((LazyAttachmentCollection)attachments).createDataHandlerMap();
-            } else {
-                //preserve the order of iteration
-                dataHandlers = new LinkedHashMap<String, DataHandler>();
-                for (Attachment attachment : attachments) {
-                    dataHandlers.put(attachment.getId(), 
attachment.getDataHandler());
-                }
-            }
-        }
-        return dataHandlers == null ? new LinkedHashMap<String, DataHandler>() 
: dataHandlers;
-    }    
+        
     public final boolean isEmpty() {
         return message.isEmpty();
     }

Modified: 
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java?rev=736358&r1=736357&r2=736358&view=diff
==============================================================================
--- 
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
 (original)
+++ 
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
 Wed Jan 21 10:17:31 2009
@@ -42,7 +42,7 @@
     @BeforeClass
     public static void startServers() throws Exception {
         assertTrue("server did not launch correctly",
-                   launchServer(BookServer.class));
+                   launchServer(BookServer.class, true));
     }
     
     @Test

Added: 
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java?rev=736358&view=auto
==============================================================================
--- 
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java
 (added)
+++ 
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java
 Wed Jan 21 10:17:31 2009
@@ -0,0 +1,124 @@
+/**
+ * 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.InputStream;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.RequestEntity;
+import org.apache.cxf.helpers.IOUtils;
+import org.apache.cxf.io.CachedOutputStream;
+import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class JAXRSMultipartTest extends AbstractBusClientServerTestBase {
+
+    @BeforeClass
+    public static void startServers() throws Exception {
+        assertTrue("server did not launch correctly",
+                   launchServer(MultipartServer.class, true));
+    }
+    
+    @Test
+    public void testBookAsRootAttachmentStreamSource() throws Exception {
+        String address = "http://localhost:9082/bookstore/books/stream";;
+        doAddBook(address);               
+    }
+    
+    @Test
+    public void testBookAsRootAttachmentInputStream() throws Exception {
+        String address = "http://localhost:9082/bookstore/books/istream";;
+        doAddBook(address);               
+    }
+    
+    @Test
+    public void testBookAsMessageContextDataHandler() throws Exception {
+        String address = "http://localhost:9082/bookstore/books/mchandlers";;
+        doAddBook(address);               
+    }
+    
+    @Test
+    public void testAddBookAsRootAttachmentJAXB() throws Exception {
+        String address = "http://localhost:9082/bookstore/books/jaxb";;
+        doAddBook(address);               
+    }
+    
+    @Test
+    public void testAddBookAsDataSource() throws Exception {
+        String address = "http://localhost:9082/bookstore/books/dsource";;
+        doAddBook(address);               
+    }
+    
+    @Test
+    public void testAddBookAsDataSource2() throws Exception {
+        String address = "http://localhost:9082/bookstore/books/dsource2";;
+        doAddBook(address);               
+    }
+    
+    @Test
+    public void testAddBookAsJAXB2() throws Exception {
+        String address = "http://localhost:9082/bookstore/books/jaxb2";;
+        doAddBook(address);               
+    }
+    
+    @Test
+    public void testAddBookAsDataHandler() throws Exception {
+        String address = "http://localhost:9082/bookstore/books/dhandler";;
+        doAddBook(address);               
+    }
+    
+    private void doAddBook(String address) throws Exception {
+        PostMethod post = new PostMethod(address);
+        
+        String ct = "multipart/related; type=\"text/xml\"; " + 
"start=\"rootPart\"; "
+            + "boundary=\"----=_Part_4_701508.1145579811786\"";
+        post.setRequestHeader("Content-Type", ct);
+        InputStream is = 
+            
getClass().getResourceAsStream("/org/apache/cxf/systest/jaxrs/attachmentData");
+        RequestEntity entity = new InputStreamRequestEntity(is);
+        post.setRequestEntity(entity);
+        HttpClient httpclient = new HttpClient();
+        
+        try {
+            int result = httpclient.executeMethod(post);
+            assertEquals(200, result);
+            
+            InputStream expected = 
getClass().getResourceAsStream("resources/expected_add_book.txt");
+            
+            assertEquals(getStringFromInputStream(expected), 
post.getResponseBodyAsString());
+        } finally {
+            // Release current connection to the connection pool once you are 
done
+            post.releaseConnection();
+        }
+    }
+    
+    private String getStringFromInputStream(InputStream in) throws Exception { 
       
+        CachedOutputStream bos = new CachedOutputStream();
+        IOUtils.copy(in, bos);
+        in.close();
+        bos.close();
+        return bos.getOut().toString();        
+    }
+
+}

Propchange: 
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSMultipartTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: 
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/MultipartServer.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/MultipartServer.java?rev=736358&view=auto
==============================================================================
--- 
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/MultipartServer.java
 (added)
+++ 
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/MultipartServer.java
 Wed Jan 21 10:17:31 2009
@@ -0,0 +1,50 @@
+/**
+ * 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 org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
+import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
+import org.apache.cxf.testutil.common.AbstractBusTestServerBase;
+    
+public class MultipartServer extends AbstractBusTestServerBase {
+
+    protected void run() {
+        JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
+        sf.setResourceClasses(MultipartStore.class);
+        //default lifecycle is per-request, change it to singleton
+        sf.setResourceProvider(MultipartStore.class,
+                               new SingletonResourceProvider(new 
MultipartStore()));
+        sf.setAddress("http://localhost:9080/";);
+
+        sf.create();        
+    }
+
+    public static void main(String[] args) {
+        try {
+            MultipartServer s = new MultipartServer();
+            s.start();
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            System.exit(-1);
+        } finally {
+            System.out.println("done!");
+        }
+    }
+}

Propchange: 
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/MultipartServer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/MultipartServer.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: 
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java
URL: 
http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java?rev=736358&view=auto
==============================================================================
--- 
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java
 (added)
+++ 
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java
 Wed Jan 21 10:17:31 2009
@@ -0,0 +1,148 @@
+/**
+ * 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.InputStream;
+import java.util.Map;
+
+import javax.activation.DataHandler;
+import javax.activation.DataSource;
+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.Response;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.cxf.jaxrs.ext.MessageContext;
+import org.apache.cxf.jaxrs.ext.MultipartID;
+
+...@path("/bookstore")
+public class MultipartStore {
+
+    @Context
+    private MessageContext context;
+    
+    public MultipartStore() {
+    }
+    
+    @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/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")
+    @Produces("text/xml")
+    public Response addBook2(@MultipartID("rootPart") Book b1,
+                             @MultipartID("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/dsource2")
+    @Produces("text/xml")
+    public Response addBookFromDataSource2(@MultipartID("rootPart") DataSource 
ds1,
+                                           @MultipartID("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/dhandler")
+    @Produces("text/xml")
+    public Response addBookFromDataHandler(DataHandler dh) throws Exception {
+        return readBookFromInputStream(dh.getInputStream());
+    }
+    
+    @POST
+    @Path("/books/mchandlers")
+    @Produces("text/xml")
+    public Response addBookFromMessageContext() throws Exception {
+        Map<String, DataHandler> handlers = context.getAttachments();
+        for (Map.Entry<String, DataHandler> entry : handlers.entrySet()) {
+            if (entry.getKey().equals("book2")) {
+                return 
readBookFromInputStream(entry.getValue().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();
+    }
+    
+    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();
+    }
+    
+}
+
+

Propchange: 
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/MultipartStore.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: 
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/attachmentData
URL: 
http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/attachmentData?rev=736358&view=auto
==============================================================================
--- 
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/attachmentData 
(added)
+++ 
cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs/attachmentData 
Wed Jan 21 10:17:31 2009
@@ -0,0 +1,18 @@
+
+------=_Part_4_701508.1145579811786
+Content-Type: text/xml
+Content-ID: <rootPart>
+
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Book><name>CXF in 
Action - 2</name></Book>
+------=_Part_4_701508.1145579811786
+Content-Type: image/jpeg
+Content-Transfer-Encoding: binary
+Content-ID: <foo>
+
+foobar
+------=_Part_4_701508.1145579811786--
+Content-Type: application/xml
+Content-ID: <book2>
+
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Book><name>CXF in 
Action - 2</name></Book>
+------=_Part_4_701508.1145579811786--
\ No newline at end of file


Reply via email to