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 2013/11/05 15:22:33 UTC

svn commit: r1539008 - in /cxf/branches/2.7.x-fixes: ./ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/wadl/ systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/

Author: sergeyb
Date: Tue Nov  5 14:22:32 2013
New Revision: 1539008

URL: http://svn.apache.org/r1539008
Log:
Merged revisions 1538996 via svnmerge from 
https://svn.apache.org/repos/asf/cxf/trunk

........
  r1538996 | sergeyb | 2013-11-05 13:45:13 +0000 (Tue, 05 Nov 2013) | 1 line
  
  [CXF-5355] Initial support in WadlGenerator for XmlSeeAlso
........

Modified:
    cxf/branches/2.7.x-fixes/   (props changed)
    cxf/branches/2.7.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ResourceTypes.java
    cxf/branches/2.7.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java
    cxf/branches/2.7.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerResourceCreatedSpringProviderTest.java
    cxf/branches/2.7.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/PetStore.java

Propchange: cxf/branches/2.7.x-fixes/
------------------------------------------------------------------------------
  Merged /cxf/trunk:r1538996

Propchange: cxf/branches/2.7.x-fixes/
------------------------------------------------------------------------------
Binary property 'svnmerge-integrated' - no diff available.

Modified: cxf/branches/2.7.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ResourceTypes.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ResourceTypes.java?rev=1539008&r1=1539007&r2=1539008&view=diff
==============================================================================
--- cxf/branches/2.7.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ResourceTypes.java (original)
+++ cxf/branches/2.7.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/ResourceTypes.java Tue Nov  5 14:22:32 2013
@@ -28,6 +28,7 @@ public class ResourceTypes {
     private Map<Class<?>, Type> allTypes = new HashMap<Class<?>, Type>();
     private Map<Class<?>, QName> collectionMap = new HashMap<Class<?>, QName>();
     private Map<Class<?>, QName> xmlNameMap = new HashMap<Class<?>, QName>();
+    private Map<Class<?>, Class<?>> substitutions = new HashMap<Class<?>, Class<?>>();
     public Map<Class<?>, Type> getAllTypes() {
         return allTypes;
     }
@@ -40,4 +41,7 @@ public class ResourceTypes {
     public Map<Class<?>, QName> getXmlNameMap() {
         return xmlNameMap;
     }
+    public Map<Class<?>, Class<?>> getSubstitutions() {
+        return substitutions;
+    }
 }

Modified: cxf/branches/2.7.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java?rev=1539008&r1=1539007&r2=1539008&view=diff
==============================================================================
--- cxf/branches/2.7.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java (original)
+++ cxf/branches/2.7.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java Tue Nov  5 14:22:32 2013
@@ -27,6 +27,7 @@ import java.io.StringWriter;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
 import java.lang.reflect.Type;
 import java.net.URI;
 import java.util.ArrayList;
@@ -57,6 +58,7 @@ import javax.ws.rs.core.UriInfo;
 import javax.ws.rs.ext.MessageBodyWriter;
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlSeeAlso;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.namespace.QName;
 import javax.xml.parsers.ParserConfigurationException;
@@ -137,6 +139,7 @@ public class WadlGenerator implements Re
     private boolean useJaxbContextForQnames = true;
     private boolean supportCollections = true;
     private boolean supportJaxbXmlType = true;
+    private boolean supportJaxbSubstitutions = true;
 
     private List<String> externalSchemasCache;
     private List<URI> externalSchemaLinks;
@@ -238,6 +241,7 @@ public class WadlGenerator implements Re
         ResourceTypes resourceTypes = ResourceUtils.getAllRequestResponseTypes(cris, 
                                                                                useJaxbContextForQnames,
                                                                                jaxbWriter);
+        checkXmlSeeAlso(resourceTypes);
         Set<Class<?>> allTypes = resourceTypes.getAllTypes().keySet();
 
         JAXBContext jaxbContext = useJaxbContextForQnames ? ResourceUtils
@@ -390,6 +394,28 @@ public class WadlGenerator implements Re
         return xmlEncodeIfNeeded(thePath);
     }
 
+    private void checkXmlSeeAlso(ResourceTypes resourceTypes) {
+        if (!this.useJaxbContextForQnames) {
+            return;
+        }
+        List<Class<?>> extraClasses = new LinkedList<Class<?>>();
+        for (Class<?> cls : resourceTypes.getAllTypes().keySet()) {
+            if (!isXmlRoot(cls)) {
+                XmlSeeAlso seeAlsoAnn = cls.getAnnotation(XmlSeeAlso.class);
+                if (seeAlsoAnn != null) {
+                    List<Class<?>> seeAlsoList = CastUtils.cast(Arrays.asList(seeAlsoAnn.value()));
+                    for (Class<?> seeAlsoCls : seeAlsoList) {
+                        resourceTypes.getSubstitutions().put(seeAlsoCls, cls);
+                    }
+                    extraClasses.addAll(seeAlsoList);
+                }
+            }
+        }
+        for (Class<?> cls : extraClasses) {
+            resourceTypes.getAllTypes().put(cls, cls);
+        }
+    }
+    
     private String xmlEncodeIfNeeded(String value) {
         return XMLUtils.xmlEncode(value);
     }
@@ -994,6 +1020,10 @@ public class WadlGenerator implements Re
             .append("\"");
     }
 
+    private boolean isXmlRoot(Class<?> cls) {
+        return cls.getAnnotation(XmlRootElement.class) != null;
+    }
+    
     private SchemaCollection getSchemaCollection(ResourceTypes resourceTypes, JAXBContext context) {
         if (context == null) {
             return null;
@@ -1015,7 +1045,7 @@ public class WadlGenerator implements Re
                 
                 if (supportJaxbXmlType) {
                     for (Class<?> cls : resourceTypes.getAllTypes().keySet()) {
-                        if (cls.getAnnotation(XmlRootElement.class) != null) {
+                        if (isXmlRoot(cls)) {
                             continue;
                         }
                         XmlType root = cls.getAnnotation(XmlType.class);
@@ -1031,10 +1061,33 @@ public class WadlGenerator implements Re
                                     .createElementNS(XmlSchemaConstants.XSD_NAMESPACE_URI, "xs:element");
                                 newElement.setAttribute("name", elementName.getLocalPart());
                                 newElement.setAttribute("type", tnsPrefix + typeName.getLocalPart());
+                                
+                                if (Modifier.isAbstract(cls.getModifiers()) 
+                                    && resourceTypes.getSubstitutions().values().contains(cls)) {
+                                    newElement.setAttribute("abstract", "true");
+                                }
+                                
                                 doc.getDocumentElement().appendChild(newElement);
                             }
                         }
                     }
+                    if (supportJaxbSubstitutions) {
+                        for (Map.Entry<Class<?>, Class<?>> entry : resourceTypes.getSubstitutions().entrySet()) {
+                            QName typeName = theResolver.resolve(entry.getKey(), new Annotation[] {},
+                                                                 Collections.<Class<?>, QName> emptyMap());
+                            List<Element> elements = DOMUtils.findAllElementsByTagNameNS(doc.getDocumentElement(),
+                                                                XmlSchemaConstants.XSD_NAMESPACE_URI, "element");
+                            for (Element element : elements) {
+                                if (element.getAttribute("name").equals(typeName.getLocalPart())) {
+                                    QName groupName = theResolver.resolve(entry.getValue(), new Annotation[] {},
+                                                                         Collections.<Class<?>, QName> emptyMap());
+                                    if (groupName != null) {
+                                        element.setAttribute("substitutionGroup", tnsPrefix + groupName.getLocalPart());
+                                    }
+                                }
+                            }
+                        }
+                    }
                 }
                 if (supportCollections && !resourceTypes.getCollectionMap().isEmpty()) {
                     for (Map.Entry<Class<?>, QName> entry : resourceTypes.getCollectionMap().entrySet()) {
@@ -1690,6 +1743,10 @@ public class WadlGenerator implements Re
         this.supportJaxbXmlType = supportJaxbXmlType;
     }
 
+    public void setSupportJaxbSubstitutions(boolean supportJaxbSubstitutions) {
+        this.supportJaxbSubstitutions = supportJaxbSubstitutions;
+    }
+
     private static class SchemaConverter extends DelegatingXMLStreamWriter {
         private static final String SCHEMA_LOCATION = "schemaLocation";
         private Map<String, String> locsMap;

Modified: cxf/branches/2.7.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerResourceCreatedSpringProviderTest.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerResourceCreatedSpringProviderTest.java?rev=1539008&r1=1539007&r2=1539008&view=diff
==============================================================================
--- cxf/branches/2.7.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerResourceCreatedSpringProviderTest.java (original)
+++ cxf/branches/2.7.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerResourceCreatedSpringProviderTest.java Tue Nov  5 14:22:32 2013
@@ -30,6 +30,7 @@ import java.net.HttpURLConnection;
 import java.net.Socket;
 import java.net.URL;
 import java.net.URLConnection;
+import java.util.Collections;
 import java.util.List;
 
 import javax.xml.stream.XMLStreamReader;
@@ -39,9 +40,11 @@ import org.w3c.dom.Element;
 
 import org.apache.cxf.helpers.DOMUtils;
 import org.apache.cxf.helpers.IOUtils;
+import org.apache.cxf.interceptor.LoggingInInterceptor;
 import org.apache.cxf.jaxrs.client.WebClient;
 import org.apache.cxf.jaxrs.model.AbstractResourceInfo;
 import org.apache.cxf.jaxrs.model.wadl.WadlGenerator;
+import org.apache.cxf.jaxrs.provider.JAXBElementProvider;
 import org.apache.cxf.staxutils.StaxUtils;
 import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
 import org.apache.cxf.transport.http.HTTPConduit;
@@ -114,10 +117,16 @@ public class JAXRSClientServerResourceCr
         String s = bos.toString();
         assertTrue(s.contains("<xs:element name=\"elstatus\" type=\"petStoreStatusElement\"/>"));
         assertTrue(s.contains("<xs:element name=\"status\" type=\"status\"/>"));
+        assertTrue(s.contains("<xs:element name=\"statusType\" type=\"statusType\"/>"));
+        assertTrue(s.contains(
+            "<xs:element name=\"statusImpl1\" substitutionGroup=\"statusType\" type=\"petStoreStatusImpl1\"/>"));
+        assertTrue(s.contains(
+            "<xs:element name=\"statusImpl2\" substitutionGroup=\"statusType\" type=\"petStoreStatusImpl2\"/>"));
         assertTrue(s.contains("<xs:element name=\"statuses\""));
         assertTrue(s.contains("element=\"prefix1:status\""));
         assertTrue(s.contains("element=\"prefix1:elstatus\""));
         assertTrue(s.contains("element=\"prefix1:statuses\""));
+        assertTrue(s.contains("element=\"prefix1:statusType\""));
     }
     
     @Test
@@ -298,4 +307,16 @@ public class JAXRSClientServerResourceCr
         return IOUtils.toString(in);
     }
 
+    
+    @Test
+    public void testPostPetStatusType() throws Exception {
+        JAXBElementProvider<Object> p = new JAXBElementProvider<Object>();
+        p.setUnmarshallAsJaxbElement(true);
+        WebClient wc = WebClient.create("http://localhost:" + PORT + "/webapp/pets/petstore/jaxb/statusType/",
+                                        Collections.singletonList(p));
+        WebClient.getConfig(wc).getInInterceptors().add(new LoggingInInterceptor());
+        wc.accept("text/xml");
+        PetStore.PetStoreStatusType type = wc.get(PetStore.PetStoreStatusType.class);
+        assertEquals(PetStore.CLOSED, type.getStatus());
+    }
 }

Modified: cxf/branches/2.7.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/PetStore.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.7.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/PetStore.java?rev=1539008&r1=1539007&r2=1539008&view=diff
==============================================================================
--- cxf/branches/2.7.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/PetStore.java (original)
+++ cxf/branches/2.7.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/PetStore.java Tue Nov  5 14:22:32 2013
@@ -32,6 +32,7 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
 import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlSeeAlso;
 import javax.xml.bind.annotation.XmlType;
 
 import org.apache.cxf.jaxrs.model.wadl.XMLName;
@@ -69,6 +70,14 @@ public class PetStore {
     }
     
     @GET
+    @Path("/petstore/jaxb/statusType/")
+    @Produces("text/xml")
+    public PetStoreStatusType getJaxbStatusTyoe() {
+
+        return new PetStoreStatusImpl1();
+    }
+    
+    @GET
     @Path("/petstore/jaxb/status/elements")
     @Produces({"text/xml", "application/json" })
     @XMLName("{http://pets}statuses")
@@ -109,4 +118,26 @@ public class PetStore {
     @XmlRootElement(name = "elstatus", namespace = "http://pets")
     public static class PetStoreStatusElement extends PetStoreStatus {
     }
+    
+    @XmlType(name = "statusType", namespace = "http://pets")
+    @XmlSeeAlso({PetStoreStatusImpl1.class, PetStoreStatusImpl2.class })
+    public static class PetStoreStatusType {
+        private String status = PetStore.CLOSED;
+
+        public String getStatus() {
+            return status;
+        }
+
+        public void setStatus(String status) {
+            this.status = status;
+        }
+        
+    }
+    
+    @XmlRootElement(name = "statusImpl1", namespace = "http://pets")
+    public static class PetStoreStatusImpl1 extends PetStoreStatusType {
+    }
+    @XmlRootElement(name = "statusImpl2", namespace = "http://pets")
+    public static class PetStoreStatusImpl2 extends PetStoreStatusType {
+    }
 }