You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2009/12/23 17:42:27 UTC

svn commit: r893571 - in /cxf/branches/2.2.x-fixes: ./ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/wadl/ rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/

Author: sergeyb
Date: Wed Dec 23 16:42:27 2009
New Revision: 893571

URL: http://svn.apache.org/viewvc?rev=893571&view=rev
Log:
Merged revisions 893563 via svnmerge from 
https://svn.apache.org/repos/asf/cxf/trunk

........
  r893563 | sergeyb | 2009-12-23 16:31:12 +0000 (Wed, 23 Dec 2009) | 1 line
  
  JAX-RS : some improvements to the way WADL is generated
........

Modified:
    cxf/branches/2.2.x-fixes/   (props changed)
    cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java
    cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/BookStore.java
    cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/WadlGeneratorTest.java

Propchange: cxf/branches/2.2.x-fixes/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Dec 23 16:42:27 2009
@@ -1 +1 @@
-/cxf/trunk:891375-891393,891452,891817,891827,891859,891945-891946,892056,892307,892360,892664,892890,892920,892953,892988,893011,893250,893388-893389
+/cxf/trunk:891375-891393,891452,891817,891827,891859,891945-891946,892056,892307,892360,892664,892890,892920,892953,892988,893011,893250,893388-893389,893563

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

Modified: cxf/branches/2.2.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.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java?rev=893571&r1=893570&r2=893571&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java (original)
+++ cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java Wed Dec 23 16:42:27 2009
@@ -95,7 +95,10 @@
     private static final String JAXB_DEFAULT_NAME = "##default";
     private static final String CLASSPATH_PREFIX = "classpath:";
     
+    private String wadlNamespace;
     private boolean ignoreMessageWriters = true;
+    private boolean singleResourceMultipleMethods = true;
+    private boolean useSingleSlashResource = true;
     
     public Response handleRequest(Message m, ClassResourceInfo resource) {
         
@@ -109,7 +112,7 @@
         }
         
         StringBuilder sbMain = new StringBuilder();
-        sbMain.append("<application xmlns=\"").append(WADL_NS)
+        sbMain.append("<application xmlns=\"").append(getNamespace())
               .append("\" xmlns:xs=\"").append(XmlSchemaConstants.XSD_NAMESPACE_URI).append("\"");
         StringBuilder sbGrammars = new StringBuilder();
         sbGrammars.append("<grammars>");
@@ -129,8 +132,11 @@
         Map<Class<?>, QName> clsMap = new IdentityHashMap<Class<?>, QName>();
         Set<ClassResourceInfo> visitedResources = new HashSet<ClassResourceInfo>();
         for (ClassResourceInfo cri : cris) {
-            handleResource(sbResources, jaxbTypes, proxy, clsMap,
-                           cri, cri.getURITemplate().getValue(), visitedResources);
+            String path = cri.getURITemplate().getValue();
+            sbResources.append("<resource path=\"").append(path).append("\">");
+            handleDocs(cri.getServiceClass().getAnnotations(), sbResources);
+            handleResource(sbResources, jaxbTypes, proxy, clsMap, cri, visitedResources);
+            sbResources.append("</resource>");
         }
         sbResources.append("</resources>");
         
@@ -180,38 +186,52 @@
     }
     
     private void handleResource(StringBuilder sb, Set<Class<?>> jaxbTypes, JAXBContextProxy jaxbProxy,
-                                Map<Class<?>, QName> clsMap, ClassResourceInfo cri, String path,
+                                Map<Class<?>, QName> clsMap, ClassResourceInfo cri, 
                                 Set<ClassResourceInfo> visitedResources) {
         visitedResources.add(cri);
-        sb.append("<resource path=\"").append(path).append("\">");
-        handleDocs(cri.getServiceClass().getAnnotations(), sb);
         List<OperationResourceInfo> sortedOps = sortOperationsByPath(
             cri.getMethodDispatcher().getOperationResourceInfos());
         
-        for (OperationResourceInfo ori : sortedOps) {
+        boolean resourceTagOpened = false;
+        for (int i = 0; i < sortedOps.size(); i++) {
+            OperationResourceInfo ori = sortedOps.get(i); 
             
             if (ori.getHttpMethod() == null) {
                 Class<?> cls = ori.getMethodToInvoke().getReturnType();
                 ClassResourceInfo subcri = cri.findResource(cls, cls);
                 if (subcri != null && !visitedResources.contains(subcri)) {
+                    String path = ori.getURITemplate().getValue();
+                    sb.append("<resource path=\"").append(path).append("\">");
+                    handleDocs(cri.getServiceClass().getAnnotations(), sb);
+                    handlePathAndMatrixParams(sb, ori);
                     handleResource(sb, jaxbTypes, jaxbProxy, clsMap, subcri, 
-                                   ori.getURITemplate().getValue(), visitedResources);
+                                   visitedResources);
+                    sb.append("</resource>");
                 } else {
                     handleDynamicSubresource(sb, jaxbTypes, jaxbProxy, clsMap, ori, subcri);
                 }
                 continue;
             }
-            handleOperation(sb, jaxbTypes, jaxbProxy, clsMap, ori);
+            OperationResourceInfo nextOp = i + 1 < sortedOps.size() ? sortedOps.get(i + 1) : null;
+            resourceTagOpened = handleOperation(sb, jaxbTypes, jaxbProxy, clsMap, ori, nextOp, 
+                                                resourceTagOpened, i);
         }
-        sb.append("</resource>");
     }
     
-    private void handleOperation(StringBuilder sb, Set<Class<?>> jaxbTypes, JAXBContextProxy jaxbProxy, 
-                                 Map<Class<?>, QName> clsMap, OperationResourceInfo ori) {
+    //CHECKSTYLE:OFF
+    private boolean handleOperation(StringBuilder sb, Set<Class<?>> jaxbTypes, 
+                                 JAXBContextProxy jaxbProxy, 
+                                 Map<Class<?>, QName> clsMap, 
+                                 OperationResourceInfo ori,
+                                 OperationResourceInfo nextOp,
+                                 boolean resourceTagOpened,
+                                 int index) {
+    //CHECKSTYLE:ON    
+        boolean samePathOperationFollows = singleResourceMultipleMethods && compareOperations(ori, nextOp);
         
         String path = ori.getURITemplate().getValue();
-        boolean useResource = useResource(ori);
-        if (useResource) {
+        if (!resourceTagOpened && openResource(path)) {
+            resourceTagOpened = true;
             URITemplate template = ori.getClassResourceInfo().getURITemplate();
             if (template != null) {
                 String parentPath = template.getValue();
@@ -220,12 +240,13 @@
                 }
             }
             sb.append("<resource path=\"").append(path).append("\">");
-            handleDocs(ori.getAnnotatedMethod().getAnnotations(), sb);
+            handlePathAndMatrixParams(sb, ori);
+        } else if (index == 0) {
+            handlePathAndMatrixParams(sb, ori);
         }
-        handleParams(sb, ori, ParameterType.PATH);
-        handleParams(sb, ori, ParameterType.MATRIX);
         
         sb.append("<method name=\"").append(ori.getHttpMethod()).append("\">");
+        handleDocs(ori.getAnnotatedMethod().getAnnotations(), sb);
         if (ori.getMethodToInvoke().getParameterTypes().length != 0) {
             sb.append("<request>");
             if (isFormRequest(ori)) {
@@ -237,11 +258,12 @@
             }
             sb.append("</request>");
         }
+        sb.append("<response");
         boolean isVoid = void.class == ori.getMethodToInvoke().getReturnType();
         if (isVoid) {
-            sb.append("<!-- Only status code is returned -->");
+            sb.append(" status=\"204\"");
         }
-        sb.append("<response>");
+        sb.append(">");
         if (void.class != ori.getMethodToInvoke().getReturnType()) {
             handleRepresentation(sb, jaxbTypes, jaxbProxy, clsMap, ori,
                                  ori.getMethodToInvoke().getReturnType(), false);
@@ -250,21 +272,45 @@
         
         sb.append("</method>");
         
-        if (useResource) {
+        if (resourceTagOpened && !samePathOperationFollows) {
             sb.append("</resource>");
+            resourceTagOpened = false;
         }
+        return resourceTagOpened;
     }
     
-    private boolean useResource(OperationResourceInfo ori) {
-        String path = ori.getURITemplate().getValue();
-        if ("/".equals(path)) {
-            for (Parameter pm : ori.getParameters()) {
-                if (pm.getType() == ParameterType.PATH || pm.getType() == ParameterType.MATRIX) {
-                    return true;
-                }
-            }
+    private boolean compareOperations(OperationResourceInfo ori1, OperationResourceInfo ori2) {
+        if (ori1 == null || ori2 == null
+            || !ori1.getURITemplate().getValue().equals(ori2.getURITemplate().getValue())) {
             return false;
         }
+        int ori1PathParams = 0;
+        int ori1MatrixParams = 0;
+        for (Parameter p : ori1.getParameters()) {
+            if (p.getType() == ParameterType.PATH) {
+                ori1PathParams++;
+            } else if (p.getType() == ParameterType.MATRIX) {
+                ori1MatrixParams++;
+            }
+        }
+        
+        int ori2PathParams = 0;
+        int ori2MatrixParams = 0;
+        for (Parameter p : ori2.getParameters()) {
+            if (p.getType() == ParameterType.PATH) {
+                ori2PathParams++;
+            } else if (p.getType() == ParameterType.MATRIX) {
+                ori2MatrixParams++;
+            }
+        }
+        
+        return ori1PathParams == ori2PathParams && ori1MatrixParams == ori2MatrixParams;
+    }
+    
+    private boolean openResource(String path) {
+        if ("/".equals(path)) {
+            return useSingleSlashResource;
+        }
         return true;
     }
     
@@ -278,16 +324,15 @@
             sb.append("<!-- Dynamic subresource -->");    
         }
         sb.append("<resource path=\"").append(ori.getURITemplate().getValue()).append("\">");
-        if (ori.getMethodToInvoke().getParameterTypes().length != 0) {
-            sb.append("<request>");
-            for (Parameter p : ori.getParameters()) {        
-                handleParameter(sb, jaxbTypes, jaxbProxy, clsMap, ori, p);             
-            }
-            sb.append("</request>");
-        }
+        handlePathAndMatrixParams(sb, ori);
         sb.append("</resource>");
     }
     
+    private void handlePathAndMatrixParams(StringBuilder sb, OperationResourceInfo ori) {
+        handleParams(sb, ori, ParameterType.PATH);
+        handleParams(sb, ori, ParameterType.MATRIX);
+    }
+    
     
     private void handleParameter(StringBuilder sb, Set<Class<?>> jaxbTypes, JAXBContextProxy jaxbProxy, 
                                  Map<Class<?>, QName> clsMap, OperationResourceInfo ori, Parameter pm) {
@@ -400,7 +445,11 @@
                 }
                 URITemplate ut1 = op1.getURITemplate();
                 URITemplate ut2 = op2.getURITemplate();
-                return ut1.getValue().compareTo(ut2.getValue());
+                int result = ut1.getValue().compareTo(ut2.getValue());
+                if (result == 0) {
+                    result = op1.getHttpMethod().compareTo(op2.getHttpMethod());
+                }
+                return result;
             }
             
         });        
@@ -668,5 +717,21 @@
             }
         }
     }
+
+    private String getNamespace() {
+        return wadlNamespace != null ? wadlNamespace : WADL_NS;
+    }
     
+    public void setWadlNamespace(String namespace) {
+        this.wadlNamespace = namespace;
+    }
+
+    public void setSingleResourceMultipleMethods(boolean singleResourceMultipleMethods) {
+        this.singleResourceMultipleMethods = singleResourceMultipleMethods;
+    }
+
+    public void setUseSingleSlashResource(boolean useSingleSlashResource) {
+        this.useSingleSlashResource = useSingleSlashResource;
+    }
+
 }

Modified: cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/BookStore.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/BookStore.java?rev=893571&r1=893570&r2=893571&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/BookStore.java (original)
+++ cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/BookStore.java Wed Dec 23 16:42:27 2009
@@ -24,6 +24,7 @@
 import javax.ws.rs.HeaderParam;
 import javax.ws.rs.MatrixParam;
 import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
@@ -48,8 +49,21 @@
         return "store";
     }
     
+    @PUT 
+    @Consumes("text/plain")
+    public void setName(@PathParam("id") Long id, String name) {
+    }
+    
+    @Path("books/{bookid}")
+    public Object addBook(@PathParam("id") int id,
+                        @PathParam("bookid") int bookId,
+                        @MatrixParam("mid") int matrixId) {
+        return new Book(1);
+    }
+    
     @POST
     @Path("books/{bookid}")
+    @Description("Update the books collection")
     //CHECKSTYLE:OFF
     public Book addBook(@PathParam("id") int id,
                         @PathParam("bookid") int bookId,
@@ -61,9 +75,20 @@
                         Book b) {
         return new Book(1);
     }
+    
+    @PUT
+    @Path("books/{bookid}")
+    @Description("Update the book")
+    public void addBook(@PathParam("id") int id,
+                        @PathParam("bookid") int bookId,
+                        @MatrixParam("mid") int matrixId,
+                        Book b) {
+    }
+    
     //CHECKSTYLE:ON
     @Path("booksubresource")
-    public Book getBook() {
+    public Book getBook(@PathParam("id") int id,
+                        @MatrixParam("mid") int matrixId) {
         return new Book(1);
     }
     

Modified: cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/WadlGeneratorTest.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/WadlGeneratorTest.java?rev=893571&r1=893570&r2=893571&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/WadlGeneratorTest.java (original)
+++ cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/WadlGeneratorTest.java Wed Dec 23 16:42:27 2009
@@ -160,20 +160,22 @@
         
         List<Element> resourceEls = DOMUtils.getChildrenWithName(resource, 
                                          WadlGenerator.WADL_NS, "resource");
-        assertEquals(6, resourceEls.size());        
+        assertEquals(7, resourceEls.size());        
         assertEquals("/", resourceEls.get(0).getAttribute("path"));
         assertEquals("/book2", resourceEls.get(1).getAttribute("path"));
         assertEquals("/books/{bookid}", resourceEls.get(2).getAttribute("path"));
         assertEquals("/chapter", resourceEls.get(3).getAttribute("path"));
-        assertEquals("/booksubresource", resourceEls.get(4).getAttribute("path"));
-        assertEquals("/itself", resourceEls.get(5).getAttribute("path"));
+        assertEquals("/books/{bookid}", resourceEls.get(4).getAttribute("path"));
+        assertEquals("/booksubresource", resourceEls.get(5).getAttribute("path"));
+        assertEquals("/itself", resourceEls.get(6).getAttribute("path"));
         
         
         List<Element> methodEls = DOMUtils.getChildrenWithName(resourceEls.get(0), 
                                                                WadlGenerator.WADL_NS, "method");
         
-        assertEquals(1, methodEls.size());
+        assertEquals(2, methodEls.size());
         assertEquals("GET", methodEls.get(0).getAttribute("name"));
+        assertEquals("PUT", methodEls.get(1).getAttribute("name"));
         
         List<Element> paramsEls = DOMUtils.getChildrenWithName(resourceEls.get(0), 
                                                                WadlGenerator.WADL_NS, "param");
@@ -203,10 +205,11 @@
         
         methodEls = DOMUtils.getChildrenWithName(resourceEls.get(2), 
                                                  WadlGenerator.WADL_NS, "method");
-        assertEquals(1, methodEls.size());
+        assertEquals(2, methodEls.size());
+        
         assertEquals("POST", methodEls.get(0).getAttribute("name"));
         
-        requestEls = DOMUtils.getChildrenWithName(methodEls.get(0), 
+        requestEls = DOMUtils.getChildrenWithName(methodEls.get(1), 
                                                                 WadlGenerator.WADL_NS, "request");
         assertEquals(1, requestEls.size());
         List<Element> repEls = DOMUtils.getChildrenWithName(requestEls.get(0), 
@@ -217,6 +220,19 @@
         assertEquals("application/json", repEls.get(1).getAttribute("mediaType"));
         assertEquals("", repEls.get(1).getAttribute("element"));
         
+        assertEquals("PUT", methodEls.get(1).getAttribute("name"));
+        
+        requestEls = DOMUtils.getChildrenWithName(methodEls.get(0), 
+                                                                WadlGenerator.WADL_NS, "request");
+        assertEquals(1, requestEls.size());
+        repEls = DOMUtils.getChildrenWithName(requestEls.get(0), 
+                                                            WadlGenerator.WADL_NS, "representation");
+        assertEquals(2, repEls.size());
+        assertEquals("application/xml", repEls.get(0).getAttribute("mediaType"));
+        assertEquals("prefix1:thebook", repEls.get(0).getAttribute("element"));
+        assertEquals("application/json", repEls.get(1).getAttribute("mediaType"));
+        assertEquals("", repEls.get(1).getAttribute("element"));
+        
     }
     
     private void checkParameter(Element paramEl, String name, String type) {