Author: sergeyb Date: Fri Jun 26 20:38:19 2009 New Revision: 788861 URL: http://svn.apache.org/viewvc?rev=788861&view=rev Log: Merged revisions 788444 via svnmerge from https://svn.apache.org/repos/asf/cxf/trunk
........ r788444 | sergeyb | 2009-06-25 18:24:46 +0100 (Thu, 25 Jun 2009) | 1 line JAXRS : some more wadl updates - tests to follow shortly ........ 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/Parameter.java 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/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java Propchange: cxf/branches/2.2.x-fixes/ ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Fri Jun 26 20:38:19 2009 @@ -1 +1 @@ -/cxf/trunk:782728-782730,783097,783294,783396,784059,784181-784184,784893,784895,785279-785282,785468,785621,785624,785651,785734,785866,786142,786271-786272,786395,786512,786514,786582-786583,786638,786647,786850,787200,787269,787277-787279,787290-787291,787305,787323,787366,787849,788030,788060,788187,788451,788703,788774,788819-788820 +/cxf/trunk:782728-782730,783097,783294,783396,784059,784181-784184,784893,784895,785279-785282,785468,785621,785624,785651,785734,785866,786142,786271-786272,786395,786512,786514,786582-786583,786638,786647,786850,787200,787269,787277-787279,787290-787291,787305,787323,787366,787849,788030,788060,788187,788444,788451,788703,788774,788819-788820 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/Parameter.java URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/Parameter.java?rev=788861&r1=788860&r2=788861&view=diff ============================================================================== --- cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/Parameter.java (original) +++ cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/Parameter.java Fri Jun 26 20:38:19 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/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=788861&r1=788860&r2=788861&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 Fri Jun 26 20:38:19 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/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java?rev=788861&r1=788860&r2=788861&view=diff ============================================================================== --- cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java (original) +++ cxf/branches/2.2.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java Fri Jun 26 20:38:19 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);