[prev in list] [next in list] [prev in thread] [next in thread]
List: wink-commits
Subject: svn commit: r927462 - in /incubator/wink/trunk: ./
From: rott () apache ! org
Date: 2010-03-25 15:58:08
Message-ID: 20100325155809.16DE72388A36 () eris ! apache ! org
[Download RAW message or body]
Author: rott
Date: Thu Mar 25 15:58:08 2010
New Revision: 927462
URL: http://svn.apache.org/viewvc?rev=927462&view=rev
Log:
WINK-219: best-effort to support JAXB inherited types
Added:
incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/providers/entity/JAXBProviderInheritanceTest.java
Modified:
incubator/wink/trunk/ (props changed)
incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/xml/AbstractJAXBProvider.java
incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/xml/JAXBXmlProvider.java
incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/providers/entity/JAXBCollectionXMLProviderTest.java
Propchange: incubator/wink/trunk/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Thu Mar 25 15:58:08 2010
@@ -3,3 +3,4 @@ target
dir_conflicts.prej
.settings
.classpath
+.metadata
Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/xml/AbstractJAXBProvider.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/a \
pache/wink/common/internal/providers/entity/xml/AbstractJAXBProvider.java?rev=927462&r1=927461&r2=927462&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/xml/AbstractJAXBProvider.java \
(original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/xml/AbstractJAXBProvider.java \
Thu Mar 25 15:58:08 2010 @@ -277,6 +277,15 @@ public abstract class \
AbstractJAXBProvid }
public static boolean isJAXBObject(Class<?> type, Type genericType) {
+ if (isJAXBObject(type)) {
+ return true;
+ } else if (genericType instanceof Class<?>) {
+ return isJAXBObject((Class<?>)genericType);
+ }
+ return false;
+ }
+
+ public static boolean isJAXBObject(Class<?> type) {
return isXMLRootElement(type) || isXMLType(type);
}
@@ -309,6 +318,10 @@ public abstract class AbstractJAXBProvid
}
protected JAXBContext getContext(Class<?> type, MediaType mediaType) throws \
JAXBException { + return getContext(type, type, mediaType);
+ }
+
+ protected JAXBContext getContext(Class<?> type, Type genericType, MediaType \
mediaType) throws JAXBException {
ContextResolver<JAXBContext> contextResolver =
providers.getContextResolver(JAXBContext.class, mediaType);
@@ -330,7 +343,7 @@ public abstract class AbstractJAXBProvid
}
if (context == null) {
- context = getDefaultContext(type);
+ context = getDefaultContext(type, genericType);
}
if (contextCacheOn) {
@@ -340,10 +353,20 @@ public abstract class AbstractJAXBProvid
return context;
}
- private JAXBContext getDefaultContext(Class<?> type) throws JAXBException {
+ private JAXBContext getDefaultContext(Class<?> type, Type genericType) throws \
JAXBException { JAXBContext context = jaxbDefaultContexts.get(type);
if (context == null) {
- context = JAXBContext.newInstance(type);
+
+ // CAUTION: be careful with this. Adding a second or more classes to \
the JAXBContext has the side + // effect of putting a namespace prefix and \
the namespace decl on the subelements of the + // desired type, thus \
degrading performance. +
+ if(!isXMLRootElement(type) && !isXMLType(type)) { // use genericType. \
If that fails, we'll know soon enough + context = \
JAXBContext.newInstance((Class<?>)genericType); + } else {
+ context = JAXBContext.newInstance(type);
+ }
+
jaxbDefaultContexts.put(type, context);
}
return context;
Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/xml/JAXBXmlProvider.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/a \
pache/wink/common/internal/providers/entity/xml/JAXBXmlProvider.java?rev=927462&r1=927461&r2=927462&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/xml/JAXBXmlProvider.java \
(original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/providers/entity/xml/JAXBXmlProvider.java \
Thu Mar 25 15:58:08 2010 @@ -119,14 +119,26 @@ public class JAXBXmlProvider extends \
Abs MultivaluedMap<String, Object> httpHeaders,
OutputStream entityStream) throws IOException, \
WebApplicationException { try {
- JAXBContext context = getContext(type, mediaType);
- Marshaller marshaller = getJAXBMarshaller(type, context, mediaType);
- Object entityToMarshal = getEntityToMarshal(t, type);
+ if (isJAXBObject(type)) {
+ JAXBContext context = getContext(type, genericType, mediaType);
+ Marshaller marshaller = getJAXBMarshaller(type, context, mediaType);
+ Object entityToMarshal = getEntityToMarshal(t, type);
// Use an OutputStream directly instead of a Writer for performance.
- marshaller.marshal(entityToMarshal, entityStream);
+ marshaller.marshal(entityToMarshal, entityStream);
- releaseJAXBMarshaller(context, marshaller);
+ releaseJAXBMarshaller(context, marshaller);
+ } else if (genericType instanceof Class<?>) {
+ JAXBContext context = getContext((Class<?>)genericType, genericType, \
mediaType); + Marshaller marshaller = \
getJAXBMarshaller((Class<?>)genericType, context, mediaType); + Object \
entityToMarshal = getEntityToMarshal(t, (Class<?>)genericType); +
+ // Use an OutputStream directly instead of a Writer for
+ // performance.
+ marshaller.marshal(entityToMarshal, entityStream);
+
+ releaseJAXBMarshaller(context, marshaller);
+ }
} catch (JAXBException e) {
logger.error(Messages.getMessage("jaxbFailToMarshal", type.getName()), \
e); //$NON-NLS-1$ throw new WebApplicationException(e);
Modified: incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/providers/entity/JAXBCollectionXMLProviderTest.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-server/src/test/java/org/a \
pache/wink/server/internal/providers/entity/JAXBCollectionXMLProviderTest.java?rev=927462&r1=927461&r2=927462&view=diff
==============================================================================
--- incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/providers/entity/JAXBCollectionXMLProviderTest.java \
(original)
+++ incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/providers/entity/JAXBCollectionXMLProviderTest.java \
Thu Mar 25 15:58:08 2010 @@ -23,6 +23,9 @@ package org.apache.wink.server.internal.
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.List;
+import java.util.regex.MatchResult;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
@@ -532,15 +535,23 @@ public class JAXBCollectionXMLProviderTe
SOURCE_REQUEST_BYTES);
MockHttpServletResponse invoke = invoke(request);
assertEquals(200, invoke.getStatus());
-
+
+ // nested elements may or may not have a namespace prefix, so...
+ String xml = invoke.getContentAsString();
+ Pattern myPattern = Pattern.compile("feeds><\\w*?:?feed");
+ Matcher matcher = myPattern.matcher(xml);
+ matcher.find();
+ // +6 to skip the "feeds>"
+ String feedString = xml.substring(matcher.start() + 6, matcher.end());
+
String[] elements =
- getElementsFromList("<feeds>", "</feeds>", "<feed", \
invoke.getContentAsString()); + getElementsFromList("<feeds>", "</feeds>", \
feedString, invoke.getContentAsString()); assertEquals(4, elements.length);
AtomFeed feed = null;
for (int i = 1; i < elements.length; ++i) {
feed =
- (AtomFeed)((JAXBElement<?>)unmarshallElement(AtomFeed.class, "<feed" \
+ elements[i])) + \
(AtomFeed)((JAXBElement<?>)unmarshallElement(AtomFeed.class, feedString + \
elements[i]))
.getValue();
assertEquals("" + (i - 1) + "10", feed.getId());
}
@@ -556,15 +567,23 @@ public class JAXBCollectionXMLProviderTe
SOURCE_REQUEST_BYTES);
MockHttpServletResponse invoke = invoke(request);
assertEquals(200, invoke.getStatus());
+
+ // nested elements may or may not have a namespace prefix, so...
+ String xml = invoke.getContentAsString();
+ Pattern myPattern = Pattern.compile("feeds><\\w*?:?feed");
+ Matcher matcher = myPattern.matcher(xml);
+ matcher.find();
+ // +6 to skip the "feeds>"
+ String feedString = xml.substring(matcher.start() + 6, matcher.end());
String[] elements =
- getElementsFromList("<feeds>", "</feeds>", "<feed", \
invoke.getContentAsString()); + getElementsFromList("<feeds>", "</feeds>", \
feedString, invoke.getContentAsString()); assertEquals(4, elements.length);
AtomFeed feed = null;
for (int i = 1; i < elements.length; ++i) {
feed =
- (AtomFeed)((JAXBElement<?>)unmarshallElement(AtomFeed.class, "<feed" \
+ elements[i])) + \
(AtomFeed)((JAXBElement<?>)unmarshallElement(AtomFeed.class, feedString + \
elements[i]))
.getValue();
assertEquals("" + (i - 1) + "10", feed.getId());
}
@@ -580,14 +599,22 @@ public class JAXBCollectionXMLProviderTe
MockHttpServletResponse invoke = invoke(request);
assertEquals(200, invoke.getStatus());
+ // nested elements may or may not have a namespace prefix, so...
+ String xml = invoke.getContentAsString();
+ Pattern myPattern = Pattern.compile("feeds><\\w*?:?feed");
+ Matcher matcher = myPattern.matcher(xml);
+ matcher.find();
+ // +6 to skip the "feeds>"
+ String feedString = xml.substring(matcher.start() + 6, matcher.end());
+
String[] elements =
- getElementsFromList("<feeds>", "</feeds>", "<feed", \
invoke.getContentAsString()); + getElementsFromList("<feeds>", "</feeds>", \
feedString, invoke.getContentAsString()); assertEquals(4, elements.length);
AtomFeed feed = null;
for (int i = 1; i < elements.length; ++i) {
feed =
- (AtomFeed)((JAXBElement<?>)unmarshallElement(AtomFeed.class, "<feed" \
+ elements[i])) + \
(AtomFeed)((JAXBElement<?>)unmarshallElement(AtomFeed.class, feedString + \
elements[i]))
.getValue();
assertEquals("" + (i - 1) + "10", feed.getId());
}
Added: incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/providers/entity/JAXBProviderInheritanceTest.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-server/src/test/java/org/a \
pache/wink/server/internal/providers/entity/JAXBProviderInheritanceTest.java?rev=927462&view=auto
==============================================================================
--- incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/providers/entity/JAXBProviderInheritanceTest.java \
(added)
+++ incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/providers/entity/JAXBProviderInheritanceTest.java \
Thu Mar 25 15:58:08 2010 @@ -0,0 +1,213 @@
+/*******************************************************************************
+ * 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.wink.server.internal.providers.entity;
+
+import java.io.ByteArrayInputStream;
+import java.io.StringWriter;
+import java.io.Writer;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.GenericEntity;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+import org.apache.wink.server.internal.servlet.MockServletInvocationTest;
+import org.apache.wink.test.mock.MockRequestConstructor;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+
+/**
+ * Intent of this class is to exercise the JAXBContext cache in the \
ProvidersRegistry. + */
+public class JAXBProviderInheritanceTest extends MockServletInvocationTest {
+
+ @XmlAccessorType(XmlAccessType.FIELD)
+ @XmlType(name = "", propOrder = {
+ "arg0",
+ "arg1"
+ })
+ @XmlRootElement(name = "addNumbers")
+ public static class AddNumbers {
+
+ protected int arg0;
+ protected int arg1;
+
+ /**
+ * Gets the value of the arg0 property.
+ *
+ */
+ public int getArg0() {
+ return arg0;
+ }
+
+ /**
+ * Sets the value of the arg0 property.
+ *
+ */
+ public void setArg0(int value) {
+ this.arg0 = value;
+ }
+
+ /**
+ * Gets the value of the arg1 property.
+ *
+ */
+ public int getArg1() {
+ return arg1;
+ }
+
+ /**
+ * Sets the value of the arg1 property.
+ *
+ */
+ public void setArg1(int value) {
+ this.arg1 = value;
+ }
+
+ }
+
+ @XmlRootElement
+ public static class AddIntsAnnotated extends AddNumbers {}
+
+ public static class AddIntsNotAnnotated extends AddNumbers {}
+
+
+ @Override
+ protected Class<?>[] getClasses() {
+ return new Class<?>[] {Resource.class, ResourceInherited.class};
+ }
+
+ @Path("jaxbresource")
+ public static class Resource {
+
+ @POST
+ @Path("jaxbelement")
+ public String add(AddNumbers addNumbers) {
+ return String.valueOf(addNumbers.getArg0() + addNumbers.getArg1());
+ }
+ }
+
+ @Path("jaxbresourceinherited")
+ public static class ResourceInherited {
+
+ @POST
+ @Path("jaxbelement")
+ public String add(AddIntsAnnotated addInts) {
+ return String.valueOf(addInts.getArg0() + addInts.getArg1());
+ }
+
+ @GET
+ @Path("getannotated")
+ public Response getAnnotated() {
+ AddIntsAnnotated addInts = new AddIntsAnnotated();
+ addInts.setArg0(11);
+ addInts.setArg1(12);
+ return Response.ok(new GenericEntity<AddNumbers>(addInts) {}).build();
+ }
+
+ @GET
+ @Path("getnotannotated")
+ public Response getNotAnnotated() {
+ AddIntsNotAnnotated addInts = new AddIntsNotAnnotated();
+ addInts.setArg0(15);
+ addInts.setArg1(16);
+ return Response.ok(new GenericEntity<AddNumbers>(addInts) {}).build();
+ }
+ }
+
+
+ public void testNormal() throws Exception {
+ AddNumbers addNumbers = new AddNumbers();
+ addNumbers.setArg0(2);
+ addNumbers.setArg1(3);
+
+ JAXBContext context = JAXBContext.newInstance(AddNumbers.class);
+ Marshaller marshaller = context.createMarshaller();
+ Writer writer = new StringWriter();
+ marshaller.marshal(addNumbers, writer);
+
+ MockHttpServletRequest request = MockRequestConstructor
+ .constructMockRequest("POST", "/jaxbresource/jaxbelement",
+ MediaType.TEXT_PLAIN, MediaType.APPLICATION_XML,
+ writer.toString().getBytes());
+ MockHttpServletResponse response = invoke(request);
+ assertEquals(200, response.getStatus());
+ assertEquals("5", response.getContentAsString());
+ }
+
+ public void testInheritance() throws Exception {
+ AddIntsAnnotated addInts = new AddIntsAnnotated();
+ addInts.setArg0(2);
+ addInts.setArg1(3);
+
+ // JAXBContext can handle inherited types
+ JAXBContext context = JAXBContext.newInstance(AddIntsAnnotated.class);
+ Marshaller marshaller = context.createMarshaller();
+ Writer writer = new StringWriter();
+ marshaller.marshal(addInts, writer);
+
+ MockHttpServletRequest request = MockRequestConstructor
+ .constructMockRequest("POST", "/jaxbresourceinherited/jaxbelement",
+ MediaType.TEXT_PLAIN, MediaType.APPLICATION_XML,
+ writer.toString().getBytes());
+ MockHttpServletResponse response = invoke(request);
+ assertEquals(200, response.getStatus());
+ assertEquals("5", response.getContentAsString());
+ }
+
+ public void testGenericEntityAnnotatedJAXB() throws Exception {
+ MockHttpServletRequest request = \
MockRequestConstructor.constructMockRequest("GET", \
"/jaxbresourceinherited/getannotated", MediaType.APPLICATION_XML); + \
MockHttpServletResponse response = invoke(request); + assertEquals(200, \
response.getStatus()); + ByteArrayInputStream bais = new \
ByteArrayInputStream(response.getContentAsByteArray()); +
+ JAXBContext context = JAXBContext.newInstance(AddIntsAnnotated.class);
+ Unmarshaller unmarshaller = context.createUnmarshaller();
+ AddIntsAnnotated addInts = (AddIntsAnnotated)unmarshaller.unmarshal(bais);
+
+ assertEquals(11, addInts.getArg0());
+ assertEquals(12, addInts.getArg1());
+ }
+
+ public void testGenericEntityNotAnnotatedJAXB() throws Exception {
+ MockHttpServletRequest request = \
MockRequestConstructor.constructMockRequest("GET", \
"/jaxbresourceinherited/getnotannotated", MediaType.APPLICATION_XML); + \
MockHttpServletResponse response = invoke(request); + assertEquals(200, \
response.getStatus()); + ByteArrayInputStream bais = new \
ByteArrayInputStream(response.getContentAsByteArray()); +
+ JAXBContext context = JAXBContext.newInstance(new \
Class[]{AddIntsAnnotated.class, AddNumbers.class}); + Unmarshaller \
unmarshaller = context.createUnmarshaller(); + // JAXB cannot unmarshal to \
AddIntsNotAnnotated because there is no @XmlRootElement annotation on it, so... + \
AddNumbers addNumbers = (AddNumbers)unmarshaller.unmarshal(bais); +
+ assertEquals(15, addNumbers.getArg0());
+ assertEquals(16, addNumbers.getArg1());
+ }
+
+}
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic