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) {