Author: sergeyb
Date: Thu Jun 25 17:24:46 2009
New Revision: 788444
URL: http://svn.apache.org/viewvc?rev=788444&view=rev
Log:
JAXRS : some more wadl updates - tests to follow shortly
Modified:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/Parameter.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java
Modified:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/Parameter.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/Parameter.java?rev=788444&r1=788443&r2=788444&view=diff
==============================================================================
---
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/Parameter.java
(original)
+++
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/Parameter.java
Thu Jun 25 17:24:46 2009
@@ -31,8 +31,8 @@
}
- public Parameter(String type, String aValue) {
- this(ParameterType.valueOf(type), 0, aValue);
+ public Parameter(String type, int pos, String aValue) {
+ this(ParameterType.valueOf(type), pos, aValue);
}
public Parameter(ParameterType type, String aValue) {
Modified:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java?rev=788444&r1=788443&r2=788444&view=diff
==============================================================================
---
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java
(original)
+++
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java
Thu Jun 25 17:24:46 2009
@@ -18,23 +18,38 @@
*/
package org.apache.cxf.jaxrs.model.wadl;
+import java.io.IOException;
+import java.io.StringWriter;
import java.util.Collections;
-import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
+import java.util.logging.Logger;
+import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.SchemaOutputResolver;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.Result;
+import javax.xml.transform.sax.SAXResult;
+import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.jaxrs.ext.RequestHandler;
+import org.apache.cxf.jaxrs.impl.HttpHeadersImpl;
import org.apache.cxf.jaxrs.impl.UriInfoImpl;
import org.apache.cxf.jaxrs.model.ClassResourceInfo;
import org.apache.cxf.jaxrs.model.OperationResourceInfo;
+import org.apache.cxf.jaxrs.model.OperationResourceInfoComparator;
import org.apache.cxf.jaxrs.model.Parameter;
import org.apache.cxf.jaxrs.model.ParameterType;
+import org.apache.cxf.jaxrs.provider.JAXBElementProvider;
+import org.apache.cxf.jaxrs.utils.InjectionUtils;
import org.apache.cxf.message.Message;
+import org.apache.cxf.staxutils.StaxUtils;
+import org.apache.cxf.staxutils.StreamWriterContentHandler;
// TODO :
// 1. extract JavaDocs and put them into XML comments
@@ -47,6 +62,8 @@
public static final MediaType WADL_TYPE =
MediaType.valueOf("application/vnd.sun.wadl+xml");
public static final String WADL_NS =
"http://research.sun.com/wadl/2006/10";
+ private static final Logger LOG =
LogUtils.getL7dLogger(WadlGenerator.class);
+
public Response handleRequest(Message m, ClassResourceInfo resource) {
if (!"GET".equals(m.get(Message.HTTP_REQUEST_METHOD))) {
@@ -58,16 +75,24 @@
return null;
}
- StringBuilder sb = new StringBuilder();
- sb.append("<application xmlns=\"").append(WADL_NS).append("\">");
-
- sb.append("<resources
base=\"").append(ui.getBaseUri().toString()).append("\">");
- handleResource(sb, resource, resource.getURITemplate().getValue(),
+ StringBuilder sbMain = new StringBuilder();
+ sbMain.append("<application xmlns=\"").append(WADL_NS).append("\">");
+ StringBuilder sbGrammars = new StringBuilder();
+ sbGrammars.append("<grammars>");
+ StringBuilder sbResources = new StringBuilder();
+ sbResources.append("<resources
base=\"").append(ui.getBaseUri().toString()).append("\">");
+ handleResource(sbResources, resource,
resource.getURITemplate().getValue(),
resource.getURITemplate().getVariables());
- sb.append("</resources>");
- sb.append("</application>");
+ sbResources.append("</resources>");
+ sbGrammars.append("</grammars>");
+ sbMain.append(sbGrammars.toString());
+ sbMain.append(sbResources.toString());
+ sbMain.append("</application>");
- return Response.ok().type(WADL_TYPE).entity(sb.toString()).build();
+ HttpHeaders headers = new HttpHeadersImpl(m);
+ MediaType type =
headers.getAcceptableMediaTypes().contains(MediaType.APPLICATION_XML_TYPE)
+ ? MediaType.APPLICATION_XML_TYPE : WADL_TYPE;
+ return Response.ok().type(type).entity(sbMain.toString()).build();
}
private void handleResource(StringBuilder sb, ClassResourceInfo cri,
String path,
@@ -77,65 +102,55 @@
List<OperationResourceInfo> sortedOps = sortOperationsByPath(
cri.getMethodDispatcher().getOperationResourceInfos());
- List<OperationResourceInfo> opsWithSamePath = new
LinkedList<OperationResourceInfo>();
- for (int i = 0; i < sortedOps.size(); i++) {
+
+ for (OperationResourceInfo ori : sortedOps) {
- if (sortedOps.get(i).getHttpMethod() == null) {
- Class<?> cls =
sortedOps.get(i).getMethodToInvoke().getReturnType();
+ if (ori.getHttpMethod() == null) {
+ Class<?> cls = ori.getMethodToInvoke().getReturnType();
ClassResourceInfo subcri = cri.findResource(cls, cls);
if (subcri != null) {
- handleResource(sb, subcri,
sortedOps.get(i).getURITemplate().getValue(),
-
sortedOps.get(i).getURITemplate().getVariables());
- opsWithSamePath.clear();
- continue;
+ handleResource(sb, subcri,
ori.getURITemplate().getValue(),
+ ori.getURITemplate().getVariables());
} else {
- handleDynamicSubresource(sb, sortedOps.get(i));
+ handleDynamicSubresource(sb, ori);
}
+ continue;
}
- if (opsWithSamePath.size() == 0) {
- opsWithSamePath.add(sortedOps.get(i));
- } else if (i > 0 && sortedOps.get(i -
1).getURITemplate().getValue()
- .equals(sortedOps.get(i).getURITemplate().getValue())) {
- opsWithSamePath.add(sortedOps.get(i));
- } else {
- handleOperation(sb, opsWithSamePath);
- opsWithSamePath.clear();
- opsWithSamePath.add(sortedOps.get(i));
- }
+ handleOperation(sb, ori);
}
- handleOperation(sb, opsWithSamePath);
sb.append("</resource>");
}
- private void handleOperation(StringBuilder sb, List<OperationResourceInfo>
oris) {
- if (oris.size() == 0) {
- return;
- }
- String path = oris.get(0).getURITemplate().getValue();
+ private void handleOperation(StringBuilder sb, OperationResourceInfo ori) {
+
+ String path = ori.getURITemplate().getValue();
boolean isSlash = "/".equals(path);
if (!isSlash) {
sb.append("<resource path=\"").append(path).append("\">");
}
- for (OperationResourceInfo ori : oris) {
- handleTemplateParams(sb, ori.getURITemplate().getVariables());
- handleMatrixParams(sb, ori);
- }
- for (OperationResourceInfo ori : oris) {
- sb.append("<method
name=\"").append(ori.getHttpMethod()).append("\">");
- if (ori.getMethodToInvoke().getParameterTypes().length != 0) {
- sb.append("<request>");
- for (Parameter p : ori.getParameters()) {
- handleParameter(sb, ori, p);
- }
- sb.append("</request>");
- }
- if (Void.class != ori.getMethodToInvoke().getReturnType()) {
- sb.append("<response>");
- handleRepresentation(sb, ori);
- sb.append("</response>");
+ handleTemplateParams(sb, ori.getURITemplate().getVariables());
+ handleMatrixParams(sb, ori);
+
+ sb.append("<method name=\"").append(ori.getHttpMethod()).append("\">");
+ if (ori.getMethodToInvoke().getParameterTypes().length != 0) {
+ sb.append("<request>");
+ for (Parameter p : ori.getParameters()) {
+ handleParameter(sb, ori, p);
}
- sb.append("</method>");
+ sb.append("</request>");
+ }
+ boolean isVoid = void.class == ori.getMethodToInvoke().getReturnType();
+ if (isVoid) {
+ sb.append("<!-- Only status code is returned -->");
+ }
+ sb.append("<response>");
+ if (void.class != ori.getMethodToInvoke().getReturnType()) {
+ handleRepresentation(sb, ori,
ori.getMethodToInvoke().getReturnType(), false);
}
+ sb.append("</response>");
+
+ sb.append("</method>");
+
if (!isSlash) {
sb.append("</resource>");
}
@@ -158,7 +173,8 @@
private void handleParameter(StringBuilder sb, OperationResourceInfo ori,
Parameter pm) {
if (pm.getType() == ParameterType.REQUEST_BODY) {
- handleRepresentation(sb, ori);
+ handleRepresentation(sb, ori,
ori.getMethodToInvoke().getParameterTypes()[pm.getIndex()],
+ true);
return;
}
if (pm.getType() == ParameterType.PATH || pm.getType() ==
ParameterType.MATRIX) {
@@ -193,22 +209,72 @@
}
}
- private void handleRepresentation(StringBuilder sb, OperationResourceInfo
ori) {
- sb.append("<representation>");
+ private void handleRepresentation(StringBuilder sb, OperationResourceInfo
ori,
+ Class<?> type, boolean inbound) {
+ if (InjectionUtils.isPrimitive(type)) {
+ sb.append("<!-- Primitive type : " + type.getSimpleName() + "
-->");
+ }
+ sb.append("<representation");
+
+ List<MediaType> types = inbound ? ori.getConsumeTypes() :
ori.getProduceTypes();
+ boolean wildcardOnly = true;
+ for (MediaType mt : types) {
+ if (!mt.isWildcardType()) {
+ wildcardOnly = false;
+ break;
+ }
+ }
+ if (!wildcardOnly) {
+ sb.append(" mediaType=\"");
+ for (int i = 0; i < types.size(); i++) {
+ sb.append(types.get(i).toString());
+ if (i + 1 < types.size()) {
+ sb.append(',');
+ }
+ }
+ if (types.size() > 0) {
+ sb.append("\"");
+ }
+ }
+ sb.append(">");
+
+ if (!type.isPrimitive()) {
+ // try to use JAXB
+ // TODO : reuse JaxbDatabinding code
+ JAXBElementProvider jaxb = new JAXBElementProvider();
+ try {
+ JAXBContext context = jaxb.getPackageContext(type);
+ if (context == null) {
+ context = jaxb.getClassContext(type);
+ }
+ if (context != null) {
+ StringWriter writer = new StringWriter();
+ XMLStreamWriter streamWriter =
StaxUtils.createXMLStreamWriter(writer);
+ final StreamWriterContentHandler handler = new
StreamWriterContentHandler(streamWriter);
+ context.generateSchema(new SchemaOutputResolver() {
+ @Override
+ public Result createOutput(String ns, String file)
throws IOException {
+ SAXResult result = new SAXResult(handler);
+ result.setSystemId(file);
+ return result;
+ }
+ });
+ streamWriter.flush();
+ sb.append(writer.toString());
+ }
+ } catch (Exception ex) {
+ LOG.fine("No schema can be generated from " + type.getName());
+ }
+ }
+
sb.append("</representation>");
}
private List<OperationResourceInfo>
sortOperationsByPath(Set<OperationResourceInfo> ops) {
List<OperationResourceInfo> opsWithSamePath = new
LinkedList<OperationResourceInfo>(ops);
- Collections.sort(opsWithSamePath, new
Comparator<OperationResourceInfo>() {
-
- public int compare(OperationResourceInfo op1,
OperationResourceInfo op2) {
- String path1 = op1.getURITemplate().getValue();
- String path2 = op2.getURITemplate().getValue();
- return path1.compareTo(path2);
- }
-
- });
+ Collections.sort(opsWithSamePath, new
OperationResourceInfoComparator());
return opsWithSamePath;
}
+
+
}
Modified:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java?rev=788444&r1=788443&r2=788444&view=diff
==============================================================================
---
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java
(original)
+++
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java
Thu Jun 25 17:24:46 2009
@@ -398,8 +398,9 @@
DOMUtils.findAllElementsByTagNameNS(e,
"http://cxf.apache.org/jaxrs", "param");
List<Parameter> params = new ArrayList<Parameter>(paramEls.size());
- for (Element paramEl : paramEls) {
- Parameter p = new Parameter(paramEl.getAttribute("type"),
paramEl.getAttribute("name"));
+ for (int i = 0; i < paramEls.size(); i++) {
+ Element paramEl = paramEls.get(i);
+ Parameter p = new Parameter(paramEl.getAttribute("type"), i,
paramEl.getAttribute("name"));
p.setEncoded(Boolean.valueOf(paramEl.getAttribute("encoded")));
p.setDefaultValue(paramEl.getAttribute("default"));
params.add(p);