Return-Path: Delivered-To: apmail-cxf-commits-archive@www.apache.org Received: (qmail 48830 invoked from network); 3 Jan 2011 15:18:27 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 3 Jan 2011 15:18:27 -0000 Received: (qmail 36892 invoked by uid 500); 3 Jan 2011 15:18:26 -0000 Delivered-To: apmail-cxf-commits-archive@cxf.apache.org Received: (qmail 36774 invoked by uid 500); 3 Jan 2011 15:18:23 -0000 Mailing-List: contact commits-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list commits@cxf.apache.org Received: (qmail 36750 invoked by uid 99); 3 Jan 2011 15:18:22 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 03 Jan 2011 15:18:22 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 03 Jan 2011 15:18:19 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 575FA23889E9; Mon, 3 Jan 2011 15:17:57 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1054645 - in /cxf/trunk: rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/tl/ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/ systests/jaxrs/src/test/java/o... Date: Mon, 03 Jan 2011 15:17:57 -0000 To: commits@cxf.apache.org From: sergeyb@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20110103151757.575FA23889E9@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: sergeyb Date: Mon Jan 3 15:17:54 2011 New Revision: 1054645 URL: http://svn.apache.org/viewvc?rev=1054645&view=rev Log: [CXF-3227] Adding JAXRSDataBinding Added: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXRSDataBinding.java (with props) Modified: 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/provider/AbstractJAXBProvider.java cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSSoapBookTest.java cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/jaxws/HelloWorld.java cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/jaxws/HelloWorldImpl.java cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_soap_rest/WEB-INF/beans.xml 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=1054645&r1=1054644&r2=1054645&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 Mon Jan 3 15:17:54 2011 @@ -81,8 +81,6 @@ public class ThreadLocalMessageContext e public void put(Object key, Object value) { if (get() != null) { get().put(key, value); - } else { - throw new IllegalStateException("MessageContext is not set"); } } 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=1054645&r1=1054644&r2=1054645&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 Mon Jan 3 15:17:54 2011 @@ -77,6 +77,8 @@ import org.apache.cxf.jaxrs.utils.Inject import org.apache.cxf.jaxrs.utils.JAXRSUtils; import org.apache.cxf.jaxrs.utils.ResourceUtils; import org.apache.cxf.jaxrs.utils.schemas.SchemaHandler; +import org.apache.cxf.message.Message; +import org.apache.cxf.phase.PhaseInterceptorChain; import org.apache.cxf.staxutils.DelegatingXMLStreamWriter; import org.apache.cxf.staxutils.DepthXMLStreamReader; import org.apache.cxf.staxutils.StaxStreamFilter; @@ -171,15 +173,26 @@ public abstract class AbstractJAXBProvid protected void checkContentLength() { if (mc != null) { - List values = mc.getHttpHeaders().getRequestHeader(HttpHeaders.CONTENT_LENGTH); - if (values.size() == 1 && "0".equals(values.get(0))) { - String message = new org.apache.cxf.common.i18n.Message("EMPTY_BODY", BUNDLE).toString(); - LOG.warning(message); - throw new WebApplicationException(400); + HttpHeaders headers = mc.getHttpHeaders(); + if (headers != null) { + List values = mc.getHttpHeaders().getRequestHeader(HttpHeaders.CONTENT_LENGTH); + if (values.size() == 1 && "0".equals(values.get(0))) { + String message = new org.apache.cxf.common.i18n.Message("EMPTY_BODY", BUNDLE).toString(); + LOG.warning(message); + throw new WebApplicationException(400); + } } } } + protected T getStaxHandlerFromCurrentMessage(Class staxCls) { + Message m = PhaseInterceptorChain.getCurrentMessage(); + if (m != null) { + return staxCls.cast(m.getContent(staxCls)); + } + return null; + } + @SuppressWarnings("unchecked") protected Object convertToJaxbElementIfNeeded(Object obj, Class cls, Type genericType) throws Exception { 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=1054645&r1=1054644&r2=1054645&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 Mon Jan 3 15:17:54 2011 @@ -205,11 +205,15 @@ public class JAXBElementProvider extends reader = factory.createXMLStreamReader(is); } catch (XMLStreamException e) { throw new WebApplicationException( - new RuntimeException("Cant' create XMLStreamReader", e)); + new RuntimeException("Can not create XMLStreamReader", e)); } } } + if (reader == null && is == null) { + reader = getStaxHandlerFromCurrentMessage(XMLStreamReader.class); + } + reader = createTransformReaderIfNeeded(reader, is); if (InjectionUtils.isSupportedCollectionOrArray(type)) { return new JAXBCollectionWrapperReader(createNewReaderIfNeeded(reader, is)); @@ -235,7 +239,7 @@ public class JAXBElementProvider extends throws IOException { try { Object actualObject = checkAdapter(obj, cls, anns, true); - Class actualClass = obj != actualObject ? actualObject.getClass() : cls; + Class actualClass = obj != actualObject || cls.isInterface() ? actualObject.getClass() : cls; String encoding = HttpUtils.getSetEncoding(m, headers, null); if (InjectionUtils.isSupportedCollectionOrArray(actualClass)) { actualClass = InjectionUtils.getActualType(genericType); @@ -385,12 +389,15 @@ public class JAXBElementProvider extends } XMLStreamWriter writer = getStreamWriter(obj, os, mt); if (writer != null) { - if (mc != null) { + if (os == null) { + ms.setProperty(Marshaller.JAXB_FRAGMENT, true); + } else if (mc != null) { if (mc.getContent(XMLStreamWriter.class) != null) { ms.setProperty(Marshaller.JAXB_FRAGMENT, true); } - mc.put(XMLStreamWriter.class.getName(), writer); - } + mc.put(XMLStreamWriter.class.getName(), writer); + } + marshalToWriter(ms, obj, writer, mt); if (mc != null && mc.getContent(XMLStreamWriter.class) != null) { writer.writeEndDocument(); @@ -421,6 +428,10 @@ public class JAXBElementProvider extends if (writer == null && enableStreaming) { writer = StaxUtils.createXMLStreamWriter(os); } + } + + if (writer == null && os == null) { + writer = getStaxHandlerFromCurrentMessage(XMLStreamWriter.class); } return createTransformWriterIfNeeded(writer, os); } Added: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXRSDataBinding.java URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXRSDataBinding.java?rev=1054645&view=auto ============================================================================== --- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXRSDataBinding.java (added) +++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXRSDataBinding.java Mon Jan 3 15:17:54 2011 @@ -0,0 +1,193 @@ +/** + * 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.lang.reflect.Method; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +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.xml.namespace.QName; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; +import javax.xml.validation.Schema; + +import org.apache.cxf.databinding.AbstractDataBinding; +import org.apache.cxf.databinding.DataReader; +import org.apache.cxf.databinding.DataWriter; +import org.apache.cxf.frontend.MethodDispatcher; +import org.apache.cxf.jaxrs.impl.MetadataMap; +import org.apache.cxf.message.Attachment; +import org.apache.cxf.message.Message; +import org.apache.cxf.phase.PhaseInterceptorChain; +import org.apache.cxf.service.Service; +import org.apache.cxf.service.model.BindingOperationInfo; +import org.apache.cxf.service.model.MessagePartInfo; + +/** + * CXF DataBinding implementation wrapping JAX-RS providers + */ +public class JAXRSDataBinding extends AbstractDataBinding { + + private static final Class SUPPORTED_READER_FORMATS[] = new Class[] {XMLStreamReader.class}; + private static final Class SUPPORTED_WRITER_FORMATS[] = new Class[] {XMLStreamWriter.class}; + + private MessageBodyReader xmlReader; + private MessageBodyWriter xmlWriter; + + public void setProvider(Object provider) { + if (!(provider instanceof MessageBodyWriter)) { + throw new IllegalArgumentException( + "The provider must implement javax.ws.rs.ext.MessageBodyWriter"); + } + xmlWriter = (MessageBodyWriter)provider; + + if (provider instanceof MessageBodyReader) { + xmlReader = (MessageBodyReader)provider; + } + } + + @SuppressWarnings("unchecked") + public DataReader createReader(final Class cls) { + if (xmlReader == null) { + throw new IllegalStateException( + "javax.ws.rs.ext.MessageBodyReader reference is uninitialized"); + } + return (DataReader)new MessageBodyDataReader(); + } + + @SuppressWarnings("unchecked") + public DataWriter createWriter(final Class cls) { + return (DataWriter)new MessageBodyDataWriter(); + } + + public Class[] getSupportedReaderFormats() { + return SUPPORTED_READER_FORMATS; + } + + public Class[] getSupportedWriterFormats() { + return SUPPORTED_WRITER_FORMATS; + } + + public void initialize(Service service) { + // Check how to deal with individual parts if needed, build a single JAXBContext, etc + } + + + // TODO: The method containing the actual annotations have to retrieved + protected Method getTargetMethod(Message m) { + BindingOperationInfo bop = m.getExchange().get(BindingOperationInfo.class); + MethodDispatcher md = (MethodDispatcher) + m.getExchange().get(Service.class).get(MethodDispatcher.class.getName()); + return md.getMethod(bop); + } + + @SuppressWarnings("unchecked") + private MultivaluedMap getHeaders(Message message) { + return new MetadataMap( + (Map>)message.get(Message.PROTOCOL_HEADERS), true, true); + } + + private class MessageBodyDataWriter implements DataWriter { + + public void write(Object obj, XMLStreamWriter output) { + write(obj, null, output); + } + + @SuppressWarnings("unchecked") + public void write(Object obj, MessagePartInfo part, XMLStreamWriter output) { + try { + Message message = PhaseInterceptorChain.getCurrentMessage(); + Method method = getTargetMethod(message); + MultivaluedMap headers = getHeaders(message); + xmlWriter.writeTo(obj, + method.getReturnType(), + method.getGenericReturnType(), + method.getAnnotations(), + MediaType.APPLICATION_XML_TYPE, + headers, + null); + message.put(Message.PROTOCOL_HEADERS, headers); + } catch (Exception ex) { + // ignore + } + } + + public void setAttachments(Collection attachments) { + // complete + } + + public void setProperty(String key, Object value) { + // complete + } + + public void setSchema(Schema s) { + // complete + } + } + + private class MessageBodyDataReader implements DataReader { + + public Object read(XMLStreamReader input) { + throw new UnsupportedOperationException(); + } + + public Object read(MessagePartInfo part, XMLStreamReader input) { + return doRead(part.getTypeClass(), input); + } + + public Object read(QName elementQName, XMLStreamReader input, Class type) { + return doRead(type, input); + } + + + @SuppressWarnings("unchecked") + private Object doRead(Class cls, XMLStreamReader input) { + try { + Message message = PhaseInterceptorChain.getCurrentMessage(); + Method method = getTargetMethod(message); + return xmlReader.readFrom(cls, + method.getGenericParameterTypes()[0], + method.getParameterTypes()[0].getAnnotations(), + MediaType.APPLICATION_ATOM_XML_TYPE, + getHeaders(message), + null); + } catch (Exception ex) { + return null; + } + } + + public void setAttachments(Collection attachments) { + // complete + } + + public void setProperty(String prop, Object value) { + // complete + } + + public void setSchema(Schema s) { + // complete + } + + }; +} Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXRSDataBinding.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXRSDataBinding.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Modified: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSSoapBookTest.java URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSSoapBookTest.java?rev=1054645&r1=1054644&r2=1054645&view=diff ============================================================================== --- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSSoapBookTest.java (original) +++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSSoapBookTest.java Mon Jan 3 15:17:54 2011 @@ -110,6 +110,24 @@ public class JAXRSSoapBookTest extends A useHelloService(hw); } + @Test + public void testHelloSoapCustomDataBinding() throws Exception { + final QName serviceName = new QName("http://hello.com", "HelloWorld"); + final QName portName = new QName("http://hello.com", "HelloWorldPort"); + final String address = "http://localhost:" + PORT + "/test/services/hello-soap-databinding"; + + Service service = Service.create(serviceName); + service.addPort(portName, SOAPBinding.SOAP11HTTP_BINDING, address); + + HelloWorld hw = service.getPort(HelloWorld.class); + + User user = new UserImpl("Barry"); + User user2 = hw.echoUser(user); + + assertNotSame(user, user2); + assertEquals("Barry", user.getName()); + } + private void useHelloService(HelloWorld service) { assertEquals("Hello Barry", service.sayHi("Barry")); assertEquals("Hello Fred", service.sayHiToUser(new UserImpl("Fred"))); Modified: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/jaxws/HelloWorld.java URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/jaxws/HelloWorld.java?rev=1054645&r1=1054644&r2=1054645&view=diff ============================================================================== --- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/jaxws/HelloWorld.java (original) +++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/jaxws/HelloWorld.java Mon Jan 3 15:17:54 2011 @@ -20,6 +20,8 @@ package org.apache.cxf.systest.jaxrs.jax import java.util.Map; +import javax.jws.WebParam; +import javax.jws.WebResult; import javax.jws.WebService; import javax.ws.rs.Consumes; import javax.ws.rs.GET; @@ -54,4 +56,11 @@ public interface HelloWorld { @Consumes("text/xml") @XmlJavaTypeAdapter(IntegerUserMapAdapter.class) Map echoUsers(@XmlJavaTypeAdapter(IntegerUserMapAdapter.class) Map users); + + @POST + @Produces("text/xml") + @Consumes("text/xml") + @Path("user") + @WebResult(name = "User") + User echoUser(@WebParam(name = "User") User user); } Modified: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/jaxws/HelloWorldImpl.java URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/jaxws/HelloWorldImpl.java?rev=1054645&r1=1054644&r2=1054645&view=diff ============================================================================== --- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/jaxws/HelloWorldImpl.java (original) +++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/jaxws/HelloWorldImpl.java Mon Jan 3 15:17:54 2011 @@ -50,5 +50,9 @@ public class HelloWorldImpl implements H return us; } + public User echoUser(User user) { + return user; + } + } // END SNIPPET: service Modified: cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_soap_rest/WEB-INF/beans.xml URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_soap_rest/WEB-INF/beans.xml?rev=1054645&r1=1054644&r2=1054645&view=diff ============================================================================== --- cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_soap_rest/WEB-INF/beans.xml (original) +++ cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_soap_rest/WEB-INF/beans.xml Mon Jan 3 15:17:54 2011 @@ -73,7 +73,7 @@ http://cxf.apache.org/schemas/jaxrs.xsd" - + - + + + + + + + + + + + + + + + @@ -109,7 +128,7 @@ http://cxf.apache.org/schemas/jaxrs.xsd" - + @@ -124,7 +143,7 @@ http://cxf.apache.org/schemas/jaxrs.xsd" - + @@ -135,7 +154,7 @@ http://cxf.apache.org/schemas/jaxrs.xsd" - + @@ -143,7 +162,7 @@ http://cxf.apache.org/schemas/jaxrs.xsd" - +