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 2010/03/09 18:53:56 UTC
svn commit: r921014 [1/2] - in /cxf/trunk:
common/common/src/main/java/org/apache/cxf/jaxb/
rt/databinding/jaxb/src/main/java/org/apache/cxf/endpoint/dynamic/
rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/codegen/
rt/frontend/jaxrs/src/main/...
Author: sergeyb
Date: Tue Mar 9 17:53:56 2010
New Revision: 921014
URL: http://svn.apache.org/viewvc?rev=921014&view=rev
Log:
JAXRS : introducing a provider capable of generating and serving the client code
Added:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/codegen/
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/codegen/CodeGeneratorProvider.java (with props)
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/codegen/
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/codegen/CodeGeneratorProviderTest.java (with props)
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/FormInterface.java (with props)
Modified:
cxf/trunk/common/common/src/main/java/org/apache/cxf/jaxb/JAXBUtils.java
cxf/trunk/rt/databinding/jaxb/src/main/java/org/apache/cxf/endpoint/dynamic/DynamicClientFactory.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/RequestPreprocessor.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/UriBuilderImpl.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.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/provider/AbstractJAXBProvider.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/UriBuilderImplTest.java
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/BookStore.java
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/WadlGeneratorTest.java
cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/jaxb/Book.java
cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerResourceCreatedSpringProviderTest.java
cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_spring_providers/WEB-INF/beans.xml
Modified: cxf/trunk/common/common/src/main/java/org/apache/cxf/jaxb/JAXBUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/common/common/src/main/java/org/apache/cxf/jaxb/JAXBUtils.java?rev=921014&r1=921013&r2=921014&view=diff
==============================================================================
--- cxf/trunk/common/common/src/main/java/org/apache/cxf/jaxb/JAXBUtils.java (original)
+++ cxf/trunk/common/common/src/main/java/org/apache/cxf/jaxb/JAXBUtils.java Tue Mar 9 17:53:56 2010
@@ -664,6 +664,45 @@ public final class JAXBUtils {
throw new JAXBException(ex);
}
}
+
+ public static SchemaCompiler createSchemaCompilerWithDefaultAllocator(Set<String> allocatorSet) {
+
+ try {
+ SchemaCompiler compiler = JAXBUtils.createSchemaCompiler();
+ Object allocator = ReflectionInvokationHandler
+ .createProxyWrapper(new DefaultClassNameAllocator(allocatorSet),
+ JAXBUtils.getParamClass(compiler, "setClassNameAllocator"));
+
+ compiler.setClassNameAllocator(allocator);
+ return compiler;
+ } catch (JAXBException e1) {
+ throw new IllegalStateException("Unable to create schema compiler", e1);
+ }
+
+ }
+
+ public static void logGeneratedClassNames(Logger logger, JCodeModel codeModel) {
+ if (!logger.isLoggable(Level.INFO)) {
+ return;
+ }
+
+ StringBuilder sb = new StringBuilder();
+ boolean first = true;
+ for (Iterator<JPackage> itr = codeModel.packages(); itr.hasNext();) {
+ JPackage package1 = itr.next();
+
+ for (Iterator<JDefinedClass> citr = package1.classes(); citr.hasNext();) {
+ if (!first) {
+ sb.append(", ");
+ } else {
+ first = false;
+ }
+ sb.append(citr.next().fullName());
+ }
+ }
+
+ logger.log(Level.INFO, "Created classes: " + sb.toString());
+ }
public static Object createFileCodeWriter(File f) throws JAXBException {
try {
@@ -834,6 +873,32 @@ public final class JAXBUtils {
}
}
+ public static class DefaultClassNameAllocator {
+ private final Set<String> typesClassNames;
+
+ public DefaultClassNameAllocator() {
+ this(new HashSet<String>());
+ }
+
+ public DefaultClassNameAllocator(Set<String> set) {
+ typesClassNames = set;
+ }
+
+ public String assignClassName(String packageName, String className) {
+ String fullClassName = className;
+ String fullPckClass = packageName + "." + fullClassName;
+ int cnt = 0;
+ while (typesClassNames.contains(fullPckClass)) {
+ cnt++;
+ fullClassName = className + cnt;
+ fullPckClass = packageName + "." + fullClassName;
+ }
+ typesClassNames.add(fullPckClass);
+ return fullClassName;
+ }
+
+ }
+
public static interface SchemaCompiler {
void setErrorListener(Object elForRun);
Modified: cxf/trunk/rt/databinding/jaxb/src/main/java/org/apache/cxf/endpoint/dynamic/DynamicClientFactory.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/databinding/jaxb/src/main/java/org/apache/cxf/endpoint/dynamic/DynamicClientFactory.java?rev=921014&r1=921013&r2=921014&view=diff
==============================================================================
--- cxf/trunk/rt/databinding/jaxb/src/main/java/org/apache/cxf/endpoint/dynamic/DynamicClientFactory.java (original)
+++ cxf/trunk/rt/databinding/jaxb/src/main/java/org/apache/cxf/endpoint/dynamic/DynamicClientFactory.java Tue Mar 9 17:53:56 2010
@@ -34,7 +34,6 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.StringTokenizer;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
@@ -258,24 +257,15 @@ public class DynamicClientFactory {
//all SI's should have the same schemas
Collection<SchemaInfo> schemas = svc.getServiceInfos().get(0).getSchemas();
- SchemaCompiler compiler;
- try {
- compiler = JAXBUtils.createSchemaCompiler();
- } catch (JAXBException e1) {
- throw new IllegalStateException("Unable to create schema compiler", e1);
- }
+ SchemaCompiler compiler =
+ JAXBUtils.createSchemaCompilerWithDefaultAllocator(new HashSet<String>());
+
Object elForRun = ReflectionInvokationHandler
.createProxyWrapper(new InnerErrorListener(wsdlUrl),
JAXBUtils.getParamClass(compiler, "setErrorListener"));
compiler.setErrorListener(elForRun);
- Object allocator = ReflectionInvokationHandler
- .createProxyWrapper(new ClassNameAllocatorImpl(),
- JAXBUtils.getParamClass(compiler, "setClassNameAllocator"));
-
- compiler.setClassNameAllocator(allocator);
-
addSchemas(wsdlUrl, schemas, compiler);
addBindingFiles(bindingFiles, compiler);
S2JJAXBModel intermediateModel = compiler.bind();
@@ -295,7 +285,7 @@ public class DynamicClientFactory {
}
sb.append(jpackage.name());
}
- outputDebug(codeModel);
+ JAXBUtils.logGeneratedClassNames(LOG, codeModel);
String packageList = sb.toString();
@@ -413,30 +403,6 @@ public class DynamicClientFactory {
return false;
}
- private void outputDebug(JCodeModel codeModel) {
- if (!LOG.isLoggable(Level.INFO)) {
- return;
- }
-
- StringBuilder sb = new StringBuilder();
- boolean first = true;
- for (Iterator<JPackage> itr = codeModel.packages(); itr.hasNext();) {
- JPackage package1 = itr.next();
-
- for (Iterator<JDefinedClass> citr = package1.classes(); citr.hasNext();) {
- if (!first) {
- sb.append(", ");
- } else {
- first = false;
- }
- sb.append(citr.next().fullName());
- }
- }
-
- LOG.log(Level.INFO, "Created classes: " + sb.toString());
-
- }
-
private void addSchemas(String wsdlUrl, Collection<SchemaInfo> schemas, SchemaCompiler compiler) {
int num = 1;
for (SchemaInfo schema : schemas) {
@@ -689,26 +655,4 @@ public class DynamicClientFactory {
this.jaxbContextProperties = jaxbContextProperties;
}
-
-
- public static class ClassNameAllocatorImpl {
- private final Set<String> typesClassNames = new HashSet<String>();
-
- public ClassNameAllocatorImpl() {
- }
-
- public String assignClassName(String packageName, String className) {
- String fullClassName = className;
- String fullPckClass = packageName + "." + fullClassName;
- int cnt = 0;
- while (typesClassNames.contains(fullPckClass)) {
- cnt++;
- fullClassName = className + cnt;
- fullPckClass = packageName + "." + fullClassName;
- }
- typesClassNames.add(fullPckClass);
- return fullClassName;
- }
-
- }
}
Added: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/codegen/CodeGeneratorProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/codegen/CodeGeneratorProvider.java?rev=921014&view=auto
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/codegen/CodeGeneratorProvider.java (added)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/codegen/CodeGeneratorProvider.java Tue Mar 9 17:53:56 2010
@@ -0,0 +1,891 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.jaxrs.ext.codegen;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.logging.Logger;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.GET;
+import javax.ws.rs.HEAD;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.MatrixParam;
+import javax.ws.rs.OPTIONS;
+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;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+import javax.xml.namespace.QName;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXParseException;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.PackageUtils;
+import org.apache.cxf.common.util.ReflectionInvokationHandler;
+import org.apache.cxf.common.xmlschema.XmlSchemaConstants;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.helpers.FileUtils;
+import org.apache.cxf.helpers.IOUtils;
+import org.apache.cxf.jaxb.JAXBUtils;
+import org.apache.cxf.jaxb.JAXBUtils.JCodeModel;
+import org.apache.cxf.jaxb.JAXBUtils.S2JJAXBModel;
+import org.apache.cxf.jaxb.JAXBUtils.SchemaCompiler;
+import org.apache.cxf.jaxrs.ext.RequestHandler;
+import org.apache.cxf.jaxrs.model.ClassResourceInfo;
+import org.apache.cxf.jaxrs.model.ProviderInfo;
+import org.apache.cxf.jaxrs.model.wadl.WadlGenerator;
+import org.apache.cxf.jaxrs.provider.ProviderFactory;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.message.Message;
+
+public class CodeGeneratorProvider implements RequestHandler {
+ public static final String CODE_QUERY = "_code";
+ public static final String LANGUAGE_QUERY = "_lang";
+ public static final String OS_QUERY = "_os";
+ public static final String SOURCE_QUERY = "_source";
+ public static final String CODE_TYPE_QUERY = "_codeType";
+ public static final String CODE_TYPE_GRAMMAR = "grammar";
+ public static final String CODE_TYPE_PROXY = "proxy";
+ public static final String CODE_TYPE_WEB = "web";
+
+ private static final Logger LOG = LogUtils.getL7dLogger(CodeGeneratorProvider.class);
+ private static final Set<String> SUPPORTED_LANGUAGES = new HashSet<String>(
+ Arrays.asList(new String[]{"java"}));
+
+ private static final String TMPDIR = System.getProperty("java.io.tmpdir");
+ private static final String TAB = " ";
+
+ private static final Map<String, Class<?>> HTTP_METHOD_ANNOTATIONS;
+ private static final Map<String, Class<?>> PARAM_ANNOTATIONS;
+
+ static {
+ HTTP_METHOD_ANNOTATIONS = new HashMap<String, Class<?>>();
+ HTTP_METHOD_ANNOTATIONS.put("get", GET.class);
+ HTTP_METHOD_ANNOTATIONS.put("put", PUT.class);
+ HTTP_METHOD_ANNOTATIONS.put("post", POST.class);
+ HTTP_METHOD_ANNOTATIONS.put("delete", DELETE.class);
+ HTTP_METHOD_ANNOTATIONS.put("head", HEAD.class);
+ HTTP_METHOD_ANNOTATIONS.put("options", OPTIONS.class);
+
+ PARAM_ANNOTATIONS = new HashMap<String, Class<?>>();
+ PARAM_ANNOTATIONS.put("template", PathParam.class);
+ PARAM_ANNOTATIONS.put("header", HeaderParam.class);
+ PARAM_ANNOTATIONS.put("query", QueryParam.class);
+ PARAM_ANNOTATIONS.put("matrix", MatrixParam.class);
+ }
+
+ private Comparator<String> importsComparator;
+ private UriInfo ui;
+ private boolean generateInterfaces = true;
+
+
+ @Context
+ public void setUriInfo(UriInfo uriInfo) {
+ this.ui = uriInfo;
+ }
+
+ public Response handleRequest(Message m, ClassResourceInfo resourceClass) {
+
+ if (!"GET".equals(m.get(Message.HTTP_REQUEST_METHOD))) {
+ return null;
+ }
+
+ if (ui.getQueryParameters().containsKey(SOURCE_QUERY)) {
+ synchronized (this) {
+ return getSource(new File(TMPDIR, getStem(resourceClass, "zip")));
+ }
+ }
+
+ String codeQuery = ui.getQueryParameters().getFirst(CODE_QUERY);
+ if (codeQuery == null) {
+ return null;
+ }
+
+ String language = ui.getQueryParameters().getFirst(LANGUAGE_QUERY);
+ if (language != null && !SUPPORTED_LANGUAGES.contains(language)) {
+ return Response.noContent().entity("Unsupported language" + language).type("text/plain").build();
+ }
+ return doHandleRequest(m, resourceClass);
+ }
+
+ protected Response doHandleRequest(Message m, ClassResourceInfo resourceClass) {
+ synchronized (this) {
+ File zipDir = new File(TMPDIR, getStem(resourceClass, "zip"));
+ Response r = getLink(zipDir, m);
+ if (r != null) {
+ return r;
+ }
+
+ File srcDir = new File(TMPDIR, getStem(resourceClass, "src"));
+ if (!srcDir.exists() && !srcDir.mkdir()) {
+ throw new IllegalStateException("Unable to create working directory " + srcDir.getPath());
+ }
+ String codeType = ui.getQueryParameters().getFirst(CODE_TYPE_QUERY);
+ try {
+ String wadl = getWadl(m, resourceClass);
+ if (wadl == null) {
+ LOG.warning("WADL for "
+ + (resourceClass != null ? resourceClass.getServiceClass().getName()
+ : "this service")
+ + " can not be loaded");
+ return Response.noContent().build();
+ }
+ generateSource(wadl, srcDir, codeType);
+ zipSource(srcDir, zipDir);
+ return getLink(zipDir, m);
+ } catch (Exception ex) {
+ LOG.warning("Code can not be generated for "
+ + resourceClass != null ? resourceClass.getServiceClass().getName()
+ : "this service");
+ FileUtils.removeDir(zipDir);
+ return Response.noContent().build();
+ } finally {
+ FileUtils.removeDir(srcDir);
+ }
+ }
+ }
+
+ private void zipSource(File srcDir, File zipDir) throws Exception {
+ if (!zipDir.exists()) {
+ zipDir.mkdir();
+ }
+ String pathSep = getPathSep();
+ File zipFile = new File(zipDir.getAbsolutePath(), "src.zip");
+ zipFile.createNewFile();
+ ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile));
+ List<File> srcFiles = FileUtils.getFilesRecurse(srcDir, ".+\\.java$");
+ for (File f : srcFiles) {
+ String entryName = f.getAbsolutePath().substring(srcDir.getAbsolutePath().length() + 1);
+ entryName = entryName.replace(".", pathSep).replace(pathSep + "java", ".java");
+ zos.putNextEntry(new ZipEntry(entryName));
+ IOUtils.copy(new FileInputStream(f), zos);
+ }
+ zos.close();
+ }
+
+ private String getLineSep() {
+ String os = ui.getQueryParameters().getFirst(OS_QUERY);
+ if (os == null) {
+ return "\r\n";
+ }
+ return "unix".equals(os) ? "\r" : "\r\n";
+ }
+
+ protected String getPathSep() {
+ String os = ui.getQueryParameters().getFirst(OS_QUERY);
+ if (os == null) {
+ return "\\";
+ }
+ return "unix".equals(os) ? "/" : "\\";
+ }
+
+ private Response getSource(File zipDir) {
+ if (zipDir.exists()) {
+ File zipFile = new File(zipDir.getAbsolutePath(), "src.zip");
+ if (zipFile.exists()) {
+ try {
+ return Response.ok().type("application/zip").entity(new FileInputStream(zipFile)).build();
+ } catch (FileNotFoundException ex) {
+ // should not happen given we've checked it exists
+ throw new WebApplicationException();
+ }
+ }
+ }
+ return Response.noContent().build();
+
+ }
+
+ private Response getLink(File zipDir, Message m) {
+ if (zipDir.exists() && new File(zipDir.getAbsolutePath(), "src.zip").exists()) {
+ UriBuilder builder = ui.getAbsolutePathBuilder();
+ String link = builder.queryParam(SOURCE_QUERY).build().toString();
+ // TODO : move it into a resource template
+ StringBuilder sb = new StringBuilder();
+ sb.append("<html xmlns=\"http://www.w3.org/1999/xhtml\">");
+ sb.append("<head><title>Download the source</title></head>");
+ sb.append("<body>");
+ sb.append("<h1>Link:</h1><br/>");
+ sb.append("<ul>" + "<a href=\"" + link + "\">" + link + "</a>" + "</ul>");
+ sb.append("</body>");
+ sb.append("</html>");
+ m.getExchange().put(JAXRSUtils.IGNORE_MESSAGE_WRITERS, true);
+ return Response.ok().type("application/xhtml+xml").entity(
+ sb.toString()).build();
+ }
+ return null;
+ }
+
+ public void removeCode(ClassResourceInfo cri) {
+ removeCode(new File(TMPDIR, getStem(cri, "src")));
+ removeCode(new File(TMPDIR, getStem(cri, "zip")));
+ }
+
+ protected String getStem(ClassResourceInfo cri, String suffix) {
+ if (cri == null) {
+ return "cxf-jaxrs-" + suffix;
+ } else {
+ return "cxf-jaxrs-" + cri.getServiceClass().getName() + "-" + suffix;
+ }
+ }
+
+ private static void removeCode(File src) {
+ if (src.exists()) {
+ FileUtils.removeDir(src);
+ }
+ }
+
+ protected String getWadl(Message m, ClassResourceInfo resourceClass) {
+ m.put(Message.QUERY_STRING, WadlGenerator.WADL_QUERY);
+
+ List<ProviderInfo<RequestHandler>> shs = ProviderFactory.getInstance(m).getRequestHandlers();
+ // this is actually being tested by ProviderFactory unit tests but just in case
+ // WadlGenerator, the custom or default one, must be the first one
+ if (shs.size() > 0 && shs.get(0).getProvider() instanceof WadlGenerator) {
+ WadlGenerator wg = (WadlGenerator)shs.get(0).getProvider();
+ wg = new WadlGenerator(wg);
+ wg.setAddResourceAndMethodIds(true);
+ Response r = wg.handleRequest(m, resourceClass);
+ return r == null ? null : (String)r.getEntity();
+ }
+ return null;
+ }
+
+ protected void generateSource(String wadl, File srcDir, String codeType) {
+ Element appElement = readWadl(wadl);
+
+ Set<String> typeClassNames = new HashSet<String>();
+ List<Element> schemaElements = getSchemaElements(appElement);
+ if (!schemaElements.isEmpty()) {
+ // generate classes from schema
+ JCodeModel codeModel = createCodeModel(schemaElements, typeClassNames);
+ if (codeModel != null) {
+ generateClassesFromSchema(codeModel, srcDir);
+ }
+ }
+
+ if (!CODE_TYPE_GRAMMAR.equals(codeType)) {
+ generateResourceClasses(appElement, schemaElements, typeClassNames, srcDir);
+ }
+ }
+
+ private void generateResourceClasses(Element appElement, List<Element> schemaElements,
+ Set<String> typeClassNames, File src) {
+ List<Element> resourcesEls = DOMUtils.getChildrenWithName(appElement,
+ WadlGenerator.WADL_NS, "resources");
+ if (resourcesEls.size() != 1) {
+ throw new IllegalStateException("WADL resources element is missing");
+ }
+
+ List<Element> resourceEls = DOMUtils.getChildrenWithName(resourcesEls.get(0),
+ WadlGenerator.WADL_NS, "resource");
+ if (resourceEls.size() == 0) {
+ throw new IllegalStateException("WADL has no resource elements");
+ }
+
+ GrammarInfo gInfo = getGrammarInfo(appElement, schemaElements);
+ for (Element resource : resourceEls) {
+ writeResourceClass(resource, typeClassNames, gInfo, src);
+ }
+
+ generateMainClass(resourcesEls.get(0), src);
+
+ }
+
+ private GrammarInfo getGrammarInfo(Element appElement, List<Element> schemaElements) {
+
+ if (schemaElements.isEmpty()) {
+ return null;
+ }
+
+ Map<String, String> nsMap = new HashMap<String, String>();
+ NamedNodeMap attrMap = appElement.getAttributes();
+ for (int i = 0; i < attrMap.getLength(); i++) {
+ Node node = attrMap.item(i);
+ String nodeName = node.getNodeName();
+ if (nodeName.startsWith("xmlns:")) {
+ String nsValue = node.getNodeValue();
+ nsMap.put(nodeName.substring(6), nsValue);
+ }
+ }
+ Map<String, String> elementTypeMap = new HashMap<String, String>();
+ for (Element schemaEl : schemaElements) {
+ List<Element> elementEls = DOMUtils.getChildrenWithName(schemaEl,
+ XmlSchemaConstants.XSD_NAMESPACE_URI, "element");
+ for (Element el : elementEls) {
+ String type = el.getAttribute("type");
+ if (type.length() > 0) {
+ String[] pair = type.split(":");
+ elementTypeMap.put(el.getAttribute("name"), pair.length == 1 ? pair[0] : pair[1]);
+ }
+ }
+ }
+ return new GrammarInfo(nsMap, elementTypeMap);
+ }
+
+ public void generateMainClass(Element resourcesEl, File src) {
+
+ }
+
+ private void writeResourceClass(Element rElement, Set<String> typeClassNames,
+ GrammarInfo gInfo, File src) {
+ String resourceId = rElement.getAttribute("id");
+ String path = rElement.getAttribute("path");
+ if (resourceId.length() == 0) {
+ LOG.warning("Resource with path " + path + " can not be mapped to a class");
+ return;
+ }
+
+
+ QName qname = JAXRSUtils.convertStringToQName(resourceId);
+ if (getSchemaClassName(PackageUtils.getPackageNameByNameSpaceURI(qname.getNamespaceURI()),
+ gInfo, qname.getLocalPart(), typeClassNames) != null) {
+ return;
+ }
+
+ StringBuilder sbImports = new StringBuilder();
+ StringBuilder sbCode = new StringBuilder();
+ Set<String> imports = createImports();
+
+ sbImports.append(getClassComment()).append(getLineSep());
+ sbImports.append("package " + qname.getNamespaceURI())
+ .append(";").append(getLineSep()).append(getLineSep());
+
+ writeAnnotation(sbCode, imports, Path.class, path, true, false);
+ sbCode.append("public " + getClassType() + " " + qname.getLocalPart()
+ + " {" + getLineSep() + getLineSep());
+
+ writeMethods(rElement, imports, sbCode, typeClassNames, gInfo);
+
+ List<Element> childEls = DOMUtils.getChildrenWithName(rElement,
+ WadlGenerator.WADL_NS, "resource");
+ for (Element childEl : childEls) {
+ if (childEl.getAttribute("id").length() == 0) {
+ writeMethods(childEl, imports, sbCode, typeClassNames, gInfo);
+ } else {
+ writeResourceMethod(childEl, childEl, imports, sbCode, typeClassNames, gInfo);
+ }
+ }
+ sbCode.append("}");
+ writeImports(sbImports, imports);
+
+ createJavaSourceFile(src, qname, sbCode, sbImports);
+
+ for (Element subEl : childEls) {
+ String id = subEl.getAttribute("id");
+ if (id.length() > 0 && !resourceId.equals(id) && !id.startsWith("{java")) {
+ writeResourceClass(subEl, typeClassNames, gInfo, src);
+ }
+ }
+ }
+
+ private String getClassType() {
+ return generateInterfaces ? "interface" : "class";
+ }
+
+ private String getClassComment() {
+ return "/**"
+ + getLineSep() + " * Generated by Apache CXF"
+ + getLineSep() + "**/";
+ }
+
+ private void writeMethods(Element rElement,
+ Set<String> imports, StringBuilder sbCode,
+ Set<String> typeClassNames, GrammarInfo gInfo) {
+ List<Element> methodEls = DOMUtils.getChildrenWithName(rElement,
+ WadlGenerator.WADL_NS, "method");
+
+ for (Element methodEl : methodEls) {
+ writeResourceMethod(rElement, methodEl, imports, sbCode, typeClassNames, gInfo);
+ }
+ }
+
+ private void writeAnnotation(StringBuilder sbCode, Set<String> imports,
+ Class<?> cls, String value, boolean nextLine, boolean addTab) {
+ if (value != null && value.length() == 0) {
+ return;
+ }
+ addImport(imports, cls.getName());
+ sbCode.append("@").append(cls.getSimpleName());
+ if (value != null) {
+ sbCode.append("(\"" + value + "\")");
+ }
+ if (nextLine) {
+ sbCode.append(getLineSep());
+ if (addTab) {
+ sbCode.append(TAB);
+ }
+ }
+ }
+
+ private void addImport(Set<String> imports, String clsName) {
+ if (imports == null || clsName.startsWith("java.lang")) {
+ return;
+ }
+ if (!imports.contains(clsName)) {
+ imports.add(clsName);
+ }
+ }
+
+ private void writeImports(StringBuilder sbImports, Set<String> imports) {
+ for (String clsName : imports) {
+ sbImports.append("import " + clsName).append(";").append(getLineSep());
+ }
+ }
+
+ private void writeResourceMethod(Element resourceEl, Element methodEl,
+ Set<String> imports, StringBuilder sbCode,
+ Set<String> typeClassNames, GrammarInfo gInfo) {
+ String id = methodEl.getAttribute("id");
+ String methodName = methodEl.getAttribute("name");
+ String path = resourceEl.getAttribute("path");
+ if (id.length() == 0) {
+ LOG.warning("Method with path " + path + " can not be mapped to a class method");
+ return;
+ }
+
+ sbCode.append(TAB);
+ writeAnnotation(sbCode, imports, Path.class, path, true, true);
+ if (methodName.length() > 0) {
+ if (HTTP_METHOD_ANNOTATIONS.containsKey(methodName.toLowerCase())) {
+ writeAnnotation(sbCode, imports,
+ HTTP_METHOD_ANNOTATIONS.get(methodName.toLowerCase()), null, true, true);
+ } else {
+ // TODO : write a custom annotation class based on HttpMethod
+ }
+ }
+
+ List<Element> responseEls = DOMUtils.getChildrenWithName(methodEl,
+ WadlGenerator.WADL_NS, "response");
+ List<Element> requestEls = DOMUtils.getChildrenWithName(methodEl,
+ WadlGenerator.WADL_NS, "request");
+
+ if (methodName.length() > 0) {
+ writeFormatAnnotations(requestEls, sbCode, imports, true);
+ writeFormatAnnotations(responseEls, sbCode, imports, false);
+ }
+ if (!generateInterfaces) {
+ sbCode.append("public ");
+ }
+ boolean responseTypeAvailable = true;
+ if (methodName.length() > 0) {
+ responseTypeAvailable = writeResponseType(responseEls, sbCode, imports, typeClassNames, gInfo);
+ sbCode.append(id);
+ } else {
+ QName qname = JAXRSUtils.convertStringToQName(id);
+ String packageName = PackageUtils.getPackageNameByNameSpaceURI(qname.getNamespaceURI());
+ String clsSimpleName = getSchemaClassName(packageName, gInfo, qname.getLocalPart(),
+ typeClassNames);
+ String localName = clsSimpleName == null ? qname.getLocalPart()
+ : clsSimpleName.substring(packageName.length() + 1);
+ String parentId = ((Element)resourceEl.getParentNode()).getAttribute("id");
+ writeSubResponseType(id.equals(parentId), clsSimpleName == null ? qname.getNamespaceURI()
+ : clsSimpleName.substring(0, packageName.length()), localName, sbCode, imports);
+ // TODO : we need to take care of multiple subresource locators with diff @Path
+ // returning the same type; also we might have ids like "{org.apache.cxf}Book#getName"
+ sbCode.append("get" + localName);
+ }
+
+ sbCode.append("(");
+ List<Element> inParamElements = new LinkedList<Element>();
+ inParamElements.addAll(DOMUtils.getChildrenWithName(resourceEl,
+ WadlGenerator.WADL_NS, "param"));
+ boolean form = false;
+ if (requestEls.size() == 1 && inParamElements.size() == 0) {
+ inParamElements.addAll(DOMUtils.getChildrenWithName(requestEls.get(0),
+ WadlGenerator.WADL_NS, "param"));
+ addFormParameters(inParamElements, requestEls.get(0));
+ form = true;
+ }
+ writeRequestTypes(requestEls, inParamElements, sbCode, imports, typeClassNames, gInfo,
+ form);
+ sbCode.append(")");
+ if (generateInterfaces) {
+ sbCode.append(";");
+ } else {
+ generateEmptyMethodBody(sbCode, responseTypeAvailable);
+ }
+ sbCode.append(getLineSep()).append(getLineSep());
+ }
+
+ protected void generateEmptyMethodBody(StringBuilder sbCode, boolean responseTypeAvailable) {
+ sbCode.append(" {");
+ sbCode.append(getLineSep()).append(TAB).append(TAB);
+ sbCode.append("//TODO: implement").append(getLineSep()).append(TAB);
+ if (responseTypeAvailable) {
+ sbCode.append(TAB).append("return null;").append(getLineSep()).append(TAB);
+ }
+ sbCode.append("}");
+ }
+
+ private void addFormParameters(List<Element> inParamElements, Element requestEl) {
+ List<Element> repElements =
+ DOMUtils.getChildrenWithName(requestEl, WadlGenerator.WADL_NS, "representation");
+
+ if (repElements.size() == 1) {
+ String mediaType = repElements.get(0).getAttribute("mediaType");
+ if (MediaType.APPLICATION_FORM_URLENCODED.equals(mediaType)) {
+ inParamElements.addAll(DOMUtils.getChildrenWithName(repElements.get(0),
+ WadlGenerator.WADL_NS, "param"));
+ }
+ }
+ }
+
+ private boolean writeResponseType(List<Element> responseEls, StringBuilder sbCode,
+ Set<String> imports, Set<String> typeClassNames,
+ GrammarInfo gInfo) {
+ List<Element> repElements = responseEls.size() == 1
+ ? DOMUtils.getChildrenWithName(responseEls.get(0), WadlGenerator.WADL_NS, "representation")
+ : CastUtils.cast(Collections.emptyList(), Element.class);
+ if (repElements.size() == 0) {
+ sbCode.append("void ");
+ return false;
+ }
+ String elementName = getElementRefName(repElements, typeClassNames, gInfo, imports);
+ if (elementName != null) {
+ sbCode.append(elementName + " ");
+ } else {
+ addImport(imports, Response.class.getName());
+ sbCode.append("Response ");
+ }
+ return true;
+ }
+
+ private void writeSubResponseType(boolean recursive, String ns, String localName,
+ StringBuilder sbCode, Set<String> imports) {
+ if (!recursive && ns.length() > 0) {
+ addImport(imports, ns + "." + localName);
+ }
+ sbCode.append(localName).append(" ");
+ }
+
+ private void writeRequestTypes(List<Element> requestEls,
+ List<Element> inParamEls,
+ StringBuilder sbCode,
+ Set<String> imports,
+ Set<String> typeClassNames,
+ GrammarInfo gInfo,
+ boolean form) {
+
+ String elementName = null;
+
+ List<Element> repElements = requestEls.size() == 1
+ ? DOMUtils.getChildrenWithName(requestEls.get(0), WadlGenerator.WADL_NS, "representation")
+ : CastUtils.cast(Collections.emptyList(), Element.class);
+ if (repElements.size() > 0) {
+ elementName = getElementRefName(repElements, typeClassNames, gInfo, imports);
+ }
+ if (elementName != null) {
+ sbCode.append(elementName).append(" ").append(elementName.toLowerCase());
+ if (inParamEls.size() > 0) {
+ sbCode.append(", ");
+ }
+ } else if (inParamEls.size() == 0) {
+ if (form) {
+ addImport(imports, MultivaluedMap.class.getName());
+ sbCode.append("MultivaluedMap map");
+ }
+ return;
+ }
+ for (int i = 0; i < inParamEls.size(); i++) {
+ Element paramEl = inParamEls.get(i);
+
+ String name = paramEl.getAttribute("name");
+ Class<?> paramAnnotation = form ? FormParam.class
+ : PARAM_ANNOTATIONS.get(paramEl.getAttribute("style"));
+ writeAnnotation(sbCode, imports, paramAnnotation, name, false, false);
+ String type = getPrimitiveType(paramEl);
+ sbCode.append(" ").append(type).append(" ").append(name.replace('.', '_'));
+ if (i + 1 < inParamEls.size()) {
+ sbCode.append(", ");
+ if (i + 1 >= 4 && ((i + 1) % 4) == 0) {
+ sbCode.append(getLineSep()).append(TAB).append(TAB).append(TAB).append(TAB);
+ }
+ }
+ }
+ }
+
+ private String getPrimitiveType(Element paramEl) {
+ String type = paramEl.getAttribute("type");
+ if (type == null) {
+ return "String";
+ }
+ String[] pair = type.split(":");
+ String value = pair.length == 2 ? pair[1] : type;
+ return "string".equals(value) ? "String" : value;
+ }
+
+ private String getElementRefName(List<Element> repElements, Set<String> typeClassNames,
+ GrammarInfo gInfo, Set<String> imports) {
+ String elementRef = null;
+ for (Element el : repElements) {
+ String value = el.getAttribute("element");
+ if (value.length() > 0) {
+ elementRef = value;
+ break;
+ }
+ }
+ if (elementRef != null) {
+ String[] pair = elementRef.split(":");
+ if (pair.length == 2) {
+ String namespace = gInfo != null ? gInfo.getNsMap().get(pair[0]) : null;
+ if (namespace == null) {
+ return null;
+ }
+ String packageName = PackageUtils.getPackageNameByNameSpaceURI(namespace);
+ String clsName = getSchemaClassName(packageName, gInfo, pair[1], typeClassNames);
+ if (clsName != null) {
+ addImport(imports, clsName);
+ return clsName.substring(packageName.length() + 1);
+ }
+ }
+ }
+ return null;
+ }
+
+ private String getSchemaClassName(String packageName, GrammarInfo gInfo, String localName,
+ Set <String> typeClassNames) {
+ String clsName = matchClassName(typeClassNames, packageName, localName);
+ if (clsName == null && gInfo != null) {
+ clsName = matchClassName(typeClassNames, packageName,
+ gInfo.getElementTypeMap().get(localName));
+ }
+ return clsName;
+ }
+
+ private String matchClassName(Set<String> typeClassNames, String packageName, String localName) {
+ if (localName == null) {
+ return null;
+ }
+ String clsName = packageName + "." + localName;
+ for (String type : typeClassNames) {
+ if (type.toLowerCase().equals(clsName)) {
+ return type;
+ }
+ }
+ return null;
+ }
+
+
+
+ private void writeFormatAnnotations(List<Element> parentEls, StringBuilder sbCode,
+ Set<String> imports, boolean inRep) {
+ List<Element> repElements = parentEls.size() == 1
+ ? DOMUtils.getChildrenWithName(parentEls.get(0), WadlGenerator.WADL_NS, "representation")
+ : CastUtils.cast(Collections.emptyList(), Element.class);
+ if (repElements.size() == 0) {
+ return;
+ }
+ Class<?> cls = inRep ? Consumes.class : Produces.class;
+ addImport(imports, cls.getName());
+ sbCode.append("@").append(cls.getSimpleName()).append("(");
+ if (repElements.size() > 1) {
+ sbCode.append("{");
+ }
+ for (int i = 0; i < repElements.size(); i++) {
+ String mediaType = repElements.get(i).getAttribute("mediaType");
+ if (mediaType != null) {
+ sbCode.append("\"" + mediaType + "\"");
+ if (i + 1 < repElements.size()) {
+ sbCode.append(", ");
+ }
+ }
+ }
+ if (repElements.size() > 1) {
+ sbCode.append(" }");
+ }
+ sbCode.append(")");
+ sbCode.append(getLineSep()).append(TAB);
+ }
+
+ private void createJavaSourceFile(File src, QName qname, StringBuilder sbCode, StringBuilder sbImports) {
+ String content = sbImports.toString() + getLineSep() + sbCode.toString();
+ File currentDir = new File(src.getAbsolutePath(), qname.getNamespaceURI());
+ currentDir.mkdirs();
+ File file = new File(currentDir.getAbsolutePath(), qname.getLocalPart() + ".java");
+
+ try {
+ file.createNewFile();
+ FileOutputStream fos = new FileOutputStream(file);
+ fos.write(content.getBytes());
+ fos.close();
+ } catch (FileNotFoundException ex) {
+ LOG.warning(file.getAbsolutePath() + " is not found");
+ } catch (IOException ex) {
+ LOG.warning("Problem writing into " + file.getAbsolutePath());
+ }
+ }
+
+ private Element readWadl(String wadl) {
+ try {
+ Document doc = DOMUtils.readXml(new StringReader(wadl));
+ return doc.getDocumentElement();
+ } catch (Exception ex) {
+ throw new IllegalStateException("Unable to read wadl", ex);
+ }
+ }
+
+ private void generateClassesFromSchema(JCodeModel codeModel, File src) {
+ try {
+ Object writer = JAXBUtils.createFileCodeWriter(src);
+ codeModel.build(writer);
+ } catch (Exception e) {
+ throw new IllegalStateException("Unable to write generated Java files for schemas: "
+ + e.getMessage(), e);
+ }
+ List<File> srcFiles = FileUtils.getFilesRecurse(src, ".+\\.java$");
+ for (File f : srcFiles) {
+ System.out.println(f.getAbsolutePath());
+ }
+ }
+
+ private List<Element> getSchemaElements(Element appElement) {
+ List<Element> grammarEls = DOMUtils.getChildrenWithName(appElement,
+ WadlGenerator.WADL_NS, "grammars");
+ if (grammarEls.size() != 1) {
+ return null;
+ }
+
+ List<Element> schemasEls = DOMUtils.getChildrenWithName(grammarEls.get(0),
+ XmlSchemaConstants.XSD_NAMESPACE_URI, "schema");
+ //TODO : check remote referencs if size() == 0
+ return schemasEls;
+ }
+
+ private JCodeModel createCodeModel(List<Element> schemaElements, Set<String> type) {
+
+ SchemaCompiler compiler = createCompiler(type);
+
+ addSchemas(schemaElements, compiler);
+
+ S2JJAXBModel intermediateModel = compiler.bind();
+
+ Object elForRun = ReflectionInvokationHandler
+ .createProxyWrapper(new InnerErrorListener(),
+ JAXBUtils.getParamClass(compiler, "setErrorListener"));
+
+ JCodeModel codeModel = intermediateModel.generateCode(null, elForRun);
+ JAXBUtils.logGeneratedClassNames(LOG, codeModel);
+ return codeModel;
+ }
+
+ private SchemaCompiler createCompiler(Set<String> typeClassNames) {
+ return JAXBUtils.createSchemaCompilerWithDefaultAllocator(typeClassNames);
+ }
+
+ private void addSchemas(List<Element> schemaElements, SchemaCompiler compiler) {
+
+ for (int i = 0; i < schemaElements.size(); i++) {
+ String key = Integer.toString(i);
+ //For JAXB 2.1.8
+ InputSource is = new InputSource((InputStream)null);
+ is.setSystemId(key);
+ is.setPublicId(key);
+ compiler.getOptions().addGrammar(is);
+
+ compiler.parseSchema(key, schemaElements.get(i));
+ }
+ }
+
+ public void setImportsComparator(Comparator<String> importsComparator) {
+ this.importsComparator = importsComparator;
+ }
+
+ private Set<String> createImports() {
+ return importsComparator == null ? new TreeSet<String>() : new TreeSet<String>(importsComparator);
+ }
+
+ public void setGenerateInterfaces(boolean generateInterfaces) {
+ this.generateInterfaces = generateInterfaces;
+ }
+
+ private static class GrammarInfo {
+ private Map<String, String> nsMap;
+ private Map<String, String> elementTypeMap;
+
+ public GrammarInfo(Map<String, String> nsMap, Map<String, String> elementTypeMap) {
+ this.nsMap = nsMap;
+ this.elementTypeMap = elementTypeMap;
+ }
+
+ public Map<String, String> getNsMap() {
+ return nsMap;
+ }
+
+ public Map<String, String> getElementTypeMap() {
+ return elementTypeMap;
+ }
+ }
+
+ private static class InnerErrorListener {
+
+ public void error(SAXParseException ex) {
+ throw new RuntimeException("Error compiling schema from WADL : "
+ + ex.getMessage(), ex);
+ }
+
+ public void fatalError(SAXParseException ex) {
+ throw new RuntimeException("Fatal error compiling schema from WADL : "
+ + ex.getMessage(), ex);
+ }
+
+ public void info(SAXParseException ex) {
+ // ignore
+ }
+
+ public void warning(SAXParseException ex) {
+ // ignore
+ }
+ }
+}
Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/codegen/CodeGeneratorProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/codegen/CodeGeneratorProvider.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/RequestPreprocessor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/RequestPreprocessor.java?rev=921014&r1=921013&r2=921014&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/RequestPreprocessor.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/RequestPreprocessor.java Tue Mar 9 17:53:56 2010
@@ -30,10 +30,12 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import org.apache.cxf.jaxrs.ext.RequestHandler;
+import org.apache.cxf.jaxrs.ext.codegen.CodeGeneratorProvider;
import org.apache.cxf.jaxrs.model.ProviderInfo;
import org.apache.cxf.jaxrs.model.wadl.WadlGenerator;
import org.apache.cxf.jaxrs.provider.ProviderFactory;
import org.apache.cxf.jaxrs.utils.HttpUtils;
+import org.apache.cxf.jaxrs.utils.InjectionUtils;
import org.apache.cxf.message.Message;
public class RequestPreprocessor {
@@ -75,7 +77,13 @@ public class RequestPreprocessor {
MultivaluedMap<String, String> queries = u.getQueryParameters();
handleTypeQuery(m, queries);
handleMethod(m, queries, new HttpHeadersImpl(m));
- checkMetadataRequest(m);
+ Response r = checkMetadataRequest(m);
+ if (r == null) {
+ r = checkCodeRequest(m);
+ }
+ if (r != null) {
+ m.getExchange().put(Response.class, r);
+ }
return new UriInfoImpl(m, null).getPath();
}
@@ -159,7 +167,7 @@ public class RequestPreprocessor {
* has been selected are handy. Consider implementing this method as part of the QueryHandler,
* we will need to save the list of ClassResourceInfos on the EndpointInfo though
*/
- public void checkMetadataRequest(Message m) {
+ public Response checkMetadataRequest(Message m) {
String query = (String)m.get(Message.QUERY_STRING);
if (query != null && query.contains(WadlGenerator.WADL_QUERY)) {
String requestURI = (String)m.get(Message.REQUEST_URI);
@@ -169,12 +177,29 @@ public class RequestPreprocessor {
// this is actually being tested by ProviderFactory unit tests but just in case
// WadlGenerator, the custom or default one, must be the first one
if (shs.size() > 0 && shs.get(0).getProvider() instanceof WadlGenerator) {
- Response r = shs.get(0).getProvider().handleRequest(m, null);
- if (r != null) {
- m.getExchange().put(Response.class, r);
- }
+ return shs.get(0).getProvider().handleRequest(m, null);
+ }
+ }
+ }
+ return null;
+ }
+
+ public Response checkCodeRequest(Message m) {
+ String query = (String)m.get(Message.QUERY_STRING);
+ if (query != null && (query.contains(CodeGeneratorProvider.CODE_QUERY)
+ || query.contains(CodeGeneratorProvider.SOURCE_QUERY))) {
+ String requestURI = (String)m.get(Message.REQUEST_URI);
+ String baseAddress = HttpUtils.getBaseAddress(m);
+ if (baseAddress.equals(requestURI)) {
+ List<ProviderInfo<RequestHandler>> shs = ProviderFactory.getInstance(m).getRequestHandlers();
+ for (ProviderInfo<RequestHandler> provider : shs) {
+ if (provider.getProvider() instanceof CodeGeneratorProvider) {
+ InjectionUtils.injectContextMethods(provider.getProvider(), provider, m);
+ return provider.getProvider().handleRequest(m, null);
+ }
}
}
}
+ return null;
}
}
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/UriBuilderImpl.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/UriBuilderImpl.java?rev=921014&r1=921013&r2=921014&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/UriBuilderImpl.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/UriBuilderImpl.java Tue Mar 9 17:53:56 2010
@@ -503,6 +503,9 @@ public class UriBuilderImpl extends UriB
}
list.add(value.toString());
}
+ if (list.isEmpty()) {
+ list.add("");
+ }
return list;
}
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java?rev=921014&r1=921013&r2=921014&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSInInterceptor.java Tue Mar 9 17:53:56 2010
@@ -180,7 +180,7 @@ public class JAXRSInInterceptor extends
}
InjectionUtils.injectContextFields(sh.getProvider(), sh, message);
- InjectionUtils.injectContextFields(sh.getProvider(), sh, message);
+ InjectionUtils.injectContextMethods(sh.getProvider(), sh, message);
Response response = sh.getProvider().handleRequest(message, resource);
if (response != null) {
message.getExchange().put(Response.class, response);
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=921014&r1=921013&r2=921014&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 Tue Mar 9 17:53:56 2010
@@ -62,6 +62,7 @@ import org.w3c.dom.Node;
import org.apache.cxf.BusFactory;
import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.PackageUtils;
import org.apache.cxf.common.util.ReflectionInvokationHandler;
import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.common.util.XmlSchemaPrimitiveUtils;
@@ -113,6 +114,7 @@ public class WadlGenerator implements Re
private boolean ignoreMessageWriters = true;
private boolean singleResourceMultipleMethods = true;
private boolean useSingleSlashResource;
+ private boolean addResourceAndMethodIds;
private boolean useJaxbContextForQnames = true;
@@ -122,6 +124,24 @@ public class WadlGenerator implements Re
private ElementQNameResolver resolver;
private List<String> privateAddresses;
+ public WadlGenerator() {
+
+ }
+
+ public WadlGenerator(WadlGenerator other) {
+ this.wadlNamespace = other.wadlNamespace;
+ this.externalQnamesMap = other.externalQnamesMap;
+ this.externalSchemaLinks = other.externalSchemaLinks;
+ this.externalSchemasCache = other.externalSchemasCache;
+ this.ignoreMessageWriters = other.ignoreMessageWriters;
+ this.privateAddresses = other.privateAddresses;
+ this.resolver = other.resolver;
+ this.addResourceAndMethodIds = other.addResourceAndMethodIds;
+ this.singleResourceMultipleMethods = other.singleResourceMultipleMethods;
+ this.useJaxbContextForQnames = other.useJaxbContextForQnames;
+ this.useSingleSlashResource = other.useSingleSlashResource;
+ }
+
public Response handleRequest(Message m, ClassResourceInfo resource) {
if (!"GET".equals(m.get(Message.HTTP_REQUEST_METHOD))) {
@@ -159,8 +179,7 @@ public class WadlGenerator implements Re
Map<Class<?>, QName> clsMap = new IdentityHashMap<Class<?>, QName>();
Set<ClassResourceInfo> visitedResources = new HashSet<ClassResourceInfo>();
for (ClassResourceInfo cri : cris) {
- String path = cri.getURITemplate().getValue();
- sbResources.append("<resource path=\"").append(path).append("\">");
+ startResourceTag(sbResources, cri.getServiceClass(), cri.getURITemplate().getValue());
handleDocs(cri.getServiceClass().getAnnotations(), sbResources);
handleResource(sbResources, allTypes, qnameResolver, clsMap, cri, visitedResources);
sbResources.append("</resource>");
@@ -218,8 +237,7 @@ public class WadlGenerator implements Re
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("\">");
+ startResourceTag(sb, subcri.getServiceClass(), ori.getURITemplate().getValue());
handleDocs(subcri.getServiceClass().getAnnotations(), sb);
handlePathAndMatrixParams(sb, ori);
handleResource(sb, jaxbTypes, qnameResolver, clsMap, subcri,
@@ -236,6 +254,30 @@ public class WadlGenerator implements Re
}
}
+ private void startResourceTag(StringBuilder sb, Class<?> serviceClass, String path) {
+ sb.append("<resource path=\"").append(path).append("\"");
+ if (addResourceAndMethodIds) {
+ QName jaxbQname = null;
+ if (useJaxbContextForQnames) {
+ jaxbQname = getJaxbQName(null, serviceClass, new HashMap<Class<?>, QName>(0));
+ }
+ String pName = jaxbQname == null ? PackageUtils.getPackageName(serviceClass)
+ : jaxbQname.getNamespaceURI();
+ String localName = jaxbQname == null ? serviceClass.getSimpleName()
+ : jaxbQname.getLocalPart();
+ sb.append(" id=\"").append("{" + pName + "}" + localName).append("\"");
+ }
+ sb.append(">");
+ }
+
+ private void startMethodTag(StringBuilder sb, OperationResourceInfo ori) {
+ sb.append("<method name=\"").append(ori.getHttpMethod()).append("\"");
+ if (addResourceAndMethodIds) {
+ sb.append(" id=\"").append(ori.getMethodToInvoke().getName()).append("\"");
+ }
+ sb.append(">");
+ }
+
//CHECKSTYLE:OFF
private boolean handleOperation(StringBuilder sb, Set<Class<?>> jaxbTypes,
ElementQNameResolver qnameResolver,
@@ -263,7 +305,7 @@ public class WadlGenerator implements Re
handlePathAndMatrixParams(sb, ori);
}
- sb.append("<method name=\"").append(ori.getHttpMethod()).append("\">");
+ startMethodTag(sb, ori);
handleDocs(ori.getAnnotatedMethod().getAnnotations(), sb);
if (ori.getMethodToInvoke().getParameterTypes().length != 0) {
sb.append("<request>");
@@ -342,7 +384,8 @@ public class WadlGenerator implements Re
} else {
sb.append("<!-- Dynamic subresource -->");
}
- sb.append("<resource path=\"").append(ori.getURITemplate().getValue()).append("\">");
+ startResourceTag(sb, subcri != null ? subcri.getServiceClass() : Object.class,
+ ori.getURITemplate().getValue());
handlePathAndMatrixParams(sb, ori);
sb.append("</resource>");
}
@@ -483,7 +526,7 @@ public class WadlGenerator implements Re
URITemplate ut1 = op1.getURITemplate();
URITemplate ut2 = op2.getURITemplate();
int result = ut1.getValue().compareTo(ut2.getValue());
- if (result == 0) {
+ if (result == 0 && !(sub1 && sub2)) {
result = op1.getHttpMethod().compareTo(op2.getHttpMethod());
}
return result;
@@ -1004,7 +1047,7 @@ public class WadlGenerator implements Re
name = type.getAnnotation(XMLName.class);
}
if (name != null) {
- QName qname = convertStringToQName(name.value(), name.prefix());
+ QName qname = JAXRSUtils.convertStringToQName(name.value(), name.prefix());
if (qname.getPrefix().length() > 0) {
return qname;
} else {
@@ -1043,21 +1086,6 @@ public class WadlGenerator implements Re
}
- private QName convertStringToQName(String name, String prefix) {
- int ind1 = name.indexOf('{');
- if (ind1 != 0) {
- return null;
- }
-
- int ind2 = name.indexOf('}');
- if (ind2 <= ind1 + 1 || ind2 >= name.length() - 1) {
- return null;
- }
- String ns = name.substring(ind1 + 1, ind2);
- String localName = name.substring(ind2 + 1);
- return new QName(ns, localName, prefix);
- }
-
public void setResolver(ElementQNameResolver resolver) {
this.resolver = resolver;
}
@@ -1074,6 +1102,10 @@ public class WadlGenerator implements Re
return MessageUtils.isTrue(m.getContextualProperty("org.apache.cxf.endpoint.private"));
}
+ public void setAddResourceAndMethodIds(boolean addResourceAndMethodIds) {
+ this.addResourceAndMethodIds = addResourceAndMethodIds;
+ }
+
private static class SchemaConverter extends DelegatingXMLStreamWriter {
private static final String SCHEMA_LOCATION = "schemaLocation";
private Map<String, String> locsMap;
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java?rev=921014&r1=921013&r2=921014&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java Tue Mar 9 17:53:56 2010
@@ -164,13 +164,13 @@ public abstract class AbstractJAXBProvid
if (jaxbElementClassNames != null && jaxbElementClassNames.contains(cls.getName())
|| jaxbElementClassMap != null && jaxbElementClassMap.containsKey(cls.getName())) {
if (jaxbElementClassMap != null) {
- name = convertStringToQName(jaxbElementClassMap.get(cls.getName()));
+ name = JAXRSUtils.convertStringToQName(jaxbElementClassMap.get(cls.getName()));
} else {
name = getJaxbQName(cls, genericType, obj, false);
}
}
if (name == null && marshalAsJaxbElement) {
- name = convertStringToQName(cls.getSimpleName());
+ name = JAXRSUtils.convertStringToQName(cls.getSimpleName());
}
if (name != null) {
return new JAXBElement(name, cls, null, obj);
@@ -221,22 +221,7 @@ public abstract class AbstractJAXBProvid
return getJaxbQName(cls, type, object, pluralName);
}
- return convertStringToQName(name);
- }
-
- protected static QName convertStringToQName(String name) {
- int ind1 = name.indexOf('{');
- if (ind1 != 0) {
- return new QName(name);
- }
-
- int ind2 = name.indexOf('}');
- if (ind2 <= ind1 + 1 || ind2 >= name.length() - 1) {
- return null;
- }
- String ns = name.substring(ind1 + 1, ind2);
- String localName = name.substring(ind2 + 1);
- return new QName(ns, localName);
+ return JAXRSUtils.convertStringToQName(name);
}
private String getCollectionWrapperName(Class<?> cls) {
@@ -591,7 +576,7 @@ public abstract class AbstractJAXBProvid
if (dropEls != null) {
dropElements = new LinkedHashSet<QName>(dropEls.size());
for (String val : dropEls) {
- dropElements.add(convertStringToQName(val));
+ dropElements.add(JAXRSUtils.convertStringToQName(val));
}
}
return dropElements;
@@ -634,8 +619,8 @@ public abstract class AbstractJAXBProvid
Map<String, String> nsMap) {
if (map != null) {
for (Map.Entry<String, String> entry : map.entrySet()) {
- QName lname = convertStringToQName(entry.getKey());
- QName rname = convertStringToQName(entry.getValue());
+ QName lname = JAXRSUtils.convertStringToQName(entry.getKey());
+ QName rname = JAXRSUtils.convertStringToQName(entry.getValue());
elementsMap.put(lname, rname);
if (nsMap != null) {
nsMap.put(lname.getNamespaceURI(), rname.getNamespaceURI());
@@ -648,8 +633,8 @@ public abstract class AbstractJAXBProvid
Map<QName, QName> elementsMap) {
if (map != null) {
for (Map.Entry<String, String> entry : map.entrySet()) {
- QName lname = convertStringToQName(entry.getKey());
- QName rname = convertStringToQName(entry.getValue());
+ QName lname = JAXRSUtils.convertStringToQName(entry.getKey());
+ QName rname = JAXRSUtils.convertStringToQName(entry.getValue());
elementsMap.put(lname, rname);
}
}
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java?rev=921014&r1=921013&r2=921014&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java Tue Mar 9 17:53:56 2010
@@ -1160,5 +1160,23 @@ public final class JAXRSUtils {
}
return new QName(nsURI, type.getSimpleName(), "ns1");
}
+
+ public static QName convertStringToQName(String name) {
+ return convertStringToQName(name, "");
+ }
+ public static QName convertStringToQName(String name, String prefix) {
+ int ind1 = name.indexOf('{');
+ if (ind1 != 0) {
+ return new QName(name);
+ }
+
+ int ind2 = name.indexOf('}');
+ if (ind2 <= ind1 + 1 || ind2 >= name.length() - 1) {
+ return null;
+ }
+ String ns = name.substring(ind1 + 1, ind2);
+ String localName = name.substring(ind2 + 1);
+ return new QName(ns, localName, prefix);
+ }
}
Added: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/codegen/CodeGeneratorProviderTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/codegen/CodeGeneratorProviderTest.java?rev=921014&view=auto
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/codegen/CodeGeneratorProviderTest.java (added)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/codegen/CodeGeneratorProviderTest.java Tue Mar 9 17:53:56 2010
@@ -0,0 +1,336 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.jaxrs.ext.codegen;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.HashMap;
+import java.util.List;
+import java.util.jar.Attributes;
+import java.util.jar.JarFile;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import org.apache.cxf.endpoint.Endpoint;
+import org.apache.cxf.helpers.FileUtils;
+import org.apache.cxf.jaxrs.JAXRSServiceImpl;
+import org.apache.cxf.jaxrs.impl.UriInfoImpl;
+import org.apache.cxf.jaxrs.model.ClassResourceInfo;
+import org.apache.cxf.jaxrs.model.wadl.BookStore;
+import org.apache.cxf.jaxrs.provider.ProviderFactory;
+import org.apache.cxf.jaxrs.utils.ResourceUtils;
+import org.apache.cxf.message.Exchange;
+import org.apache.cxf.message.ExchangeImpl;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageImpl;
+import org.apache.cxf.service.Service;
+import org.apache.cxf.service.model.BindingInfo;
+import org.apache.cxf.service.model.EndpointInfo;
+import org.apache.cxf.transport.servlet.ServletDestination;
+import org.easymock.classextension.EasyMock;
+import org.easymock.classextension.IMocksControl;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class CodeGeneratorProviderTest extends Assert {
+
+ private IMocksControl control;
+
+ @Before
+ public void setUp() {
+ control = EasyMock.createNiceControl();
+ control.makeThreadSafe(true);
+ }
+
+ @Test
+ public void testBookStoreAsInterface() throws Exception {
+ generateCodeAndCheck(true, false);
+ }
+
+ @Test
+ public void testBookStoreAsClass() throws Exception {
+ generateCodeAndCheck(false, false);
+ }
+
+ @Test
+ public void testBookStoreTypesOnly() throws Exception {
+ generateCodeAndCheck(false, true);
+ }
+
+ private void generateCodeAndCheck(boolean generateInterfaces, boolean typesOnly) throws Exception {
+ CodeGeneratorProvider cgp = new CodeGeneratorProvider();
+ cgp.setGenerateInterfaces(generateInterfaces);
+
+ ClassResourceInfo cri =
+ ResourceUtils.createClassResourceInfo(BookStore.class, BookStore.class, true, true);
+
+ String query = CodeGeneratorProvider.CODE_QUERY + "&_os=" + getOs();
+ if (typesOnly) {
+ query += "&_codeType=grammar";
+ }
+ Message m = mockMessage("http://localhost:8080/baz", "/bar", query, null);
+ try {
+ cgp.removeCode(cri);
+ cgp.setUriInfo(new UriInfoImpl(m, null));
+ cgp.handleRequest(m, cri);
+
+ String tmpdir = System.getProperty("java.io.tmpdir");
+ File classes = new File(tmpdir, cgp.getStem(cri, "classes"));
+ if (!classes.mkdir()) {
+ fail();
+ }
+ File unzippedSrc = new File(tmpdir, cgp.getStem(cri, "unzip"));
+ if (!unzippedSrc.mkdir()) {
+ fail();
+ }
+ File zipDir = new File(tmpdir, cgp.getStem(cri, "zip"));
+ try {
+ compileSrc(classes, unzippedSrc, new FileInputStream(new File(zipDir, "src.zip")));
+ verifyClasses(classes, typesOnly);
+ } finally {
+ FileUtils.removeDir(classes);
+ FileUtils.removeDir(unzippedSrc);
+ }
+ } finally {
+ cgp.removeCode(cri);
+ }
+ }
+
+ private void verifyClasses(File classesDir, boolean typesOnly) {
+ List<File> clsFiles = FileUtils.getFilesRecurse(classesDir, ".+\\.class$");
+ assertEquals(typesOnly ? 5 : 7, clsFiles.size());
+ assertTrue(checkContains(clsFiles, "superbooks.Book.class"));
+ assertTrue(checkContains(clsFiles, "superbooks.Book2.class"));
+ assertTrue(checkContains(clsFiles, "superbooks.Chapter.class"));
+ assertTrue(checkContains(clsFiles, "superbooks.ObjectFactory.class"));
+ assertTrue(checkContains(clsFiles, "superbooks.package-info.class"));
+ if (!typesOnly) {
+ assertTrue(checkContains(clsFiles, "org.apache.cxf.jaxrs.model.wadl.FormInterface.class"));
+ assertTrue(checkContains(clsFiles, "org.apache.cxf.jaxrs.model.wadl.BookStore.class"));
+ }
+ }
+
+ private boolean checkContains(List<File> clsFiles, String name) {
+
+ for (File f : clsFiles) {
+ if (f.getAbsolutePath().replace(getPathSep(), ".").endsWith(name)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ private String getPathSep() {
+ String os = System.getProperty("os.name");
+ if (os.toLowerCase().contains("win")) {
+ return "\\";
+ } else {
+ return "/";
+ }
+ }
+
+ private String getOs() {
+ String os = System.getProperty("os.name");
+ if (os.toLowerCase().contains("win")) {
+ return "win";
+ } else {
+ return "unix";
+ }
+ }
+
+ private void compileSrc(File classes, File unzippedSrc, InputStream zipFile) throws Exception {
+ unzip(zipFile, unzippedSrc);
+ StringBuilder classPath = new StringBuilder();
+ try {
+ setupClasspath(classPath, this.getClass().getClassLoader());
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+
+ List<File> srcFiles = FileUtils.getFilesRecurse(unzippedSrc, ".+\\.java$");
+ if (!compileJavaSrc(classPath.toString(), srcFiles, classes.toString())) {
+ fail("Could not compile classes");
+ }
+ }
+
+ private void unzip(InputStream fin, File unzippedSrc) throws Exception {
+ ZipInputStream zin = new ZipInputStream(fin);
+ ZipEntry ze = null;
+ while ((ze = zin.getNextEntry()) != null) {
+ String entryName = ze.getName();
+ int index = entryName.lastIndexOf(System.getProperty("file.separator"));
+ File packageDir = new File(unzippedSrc, entryName.substring(0, index));
+ packageDir.mkdirs();
+ FileOutputStream fout = new FileOutputStream(
+ new File(packageDir, entryName.substring(index + 1)));
+ for (int c = zin.read(); c != -1; c = zin.read()) {
+ fout.write(c);
+ }
+ zin.closeEntry();
+ fout.close();
+ }
+ zin.close();
+ }
+
+ protected boolean compileJavaSrc(String classPath, List<File> srcList, String dest) {
+ String[] javacCommand = new String[srcList.size() + 7];
+
+ javacCommand[0] = "javac";
+ javacCommand[1] = "-classpath";
+ javacCommand[2] = classPath;
+ javacCommand[3] = "-d";
+ javacCommand[4] = dest;
+ javacCommand[5] = "-target";
+ javacCommand[6] = "1.5";
+
+ int i = 7;
+ for (File f : srcList) {
+ javacCommand[i++] = f.getAbsolutePath();
+ }
+ org.apache.cxf.common.util.Compiler javaCompiler
+ = new org.apache.cxf.common.util.Compiler();
+
+ return javaCompiler.internalCompile(javacCommand, 7);
+ }
+
+ static void setupClasspath(StringBuilder classPath, ClassLoader classLoader)
+ throws URISyntaxException, IOException {
+
+ ClassLoader scl = ClassLoader.getSystemClassLoader();
+ ClassLoader tcl = classLoader;
+ do {
+ if (tcl instanceof URLClassLoader) {
+ URL[] urls = ((URLClassLoader)tcl).getURLs();
+ if (urls == null) {
+ urls = new URL[0];
+ }
+ for (URL url : urls) {
+ if (url.getProtocol().startsWith("file")) {
+ File file;
+ if (url.toURI().getPath() == null) {
+ continue;
+ }
+ try {
+ file = new File(url.toURI().getPath());
+ } catch (URISyntaxException urise) {
+ if (url.getPath() == null) {
+ continue;
+ }
+ file = new File(url.getPath());
+ }
+
+ if (file.exists()) {
+ classPath.append(file.getAbsolutePath())
+ .append(System
+ .getProperty("path.separator"));
+
+ if (file.getName().endsWith(".jar")) {
+ addClasspathFromManifest(classPath, file);
+ }
+ }
+ }
+ }
+ }
+ tcl = tcl.getParent();
+ if (null == tcl) {
+ break;
+ }
+ } while(!tcl.equals(scl.getParent()));
+ }
+
+ static void addClasspathFromManifest(StringBuilder classPath, File file)
+ throws URISyntaxException, IOException {
+
+ JarFile jar = new JarFile(file);
+ Attributes attr = null;
+ if (jar.getManifest() != null) {
+ attr = jar.getManifest().getMainAttributes();
+ }
+ if (attr != null) {
+ String cp = attr.getValue("Class-Path");
+ while (cp != null) {
+ String fileName = cp;
+ int idx = fileName.indexOf(' ');
+ if (idx != -1) {
+ fileName = fileName.substring(0, idx);
+ cp = cp.substring(idx + 1).trim();
+ } else {
+ cp = null;
+ }
+ URI uri = new URI(fileName);
+ File f2;
+ if (uri.isAbsolute()) {
+ f2 = new File(uri);
+ } else {
+ f2 = new File(file, fileName);
+ }
+ if (f2.exists()) {
+ classPath.append(f2.getAbsolutePath());
+ classPath.append(System.getProperty("path.separator"));
+ }
+ }
+ }
+ }
+
+ private Message mockMessage(String baseAddress, String pathInfo, String query,
+ List<ClassResourceInfo> cris) {
+ Message m = new MessageImpl();
+ Exchange e = new ExchangeImpl();
+ e.put(Service.class, new JAXRSServiceImpl(cris));
+
+ m.setExchange(e);
+ control.reset();
+ ServletDestination d = control.createMock(ServletDestination.class);
+
+ EndpointInfo epr = new EndpointInfo();
+ epr.setAddress(baseAddress);
+
+ epr.setProperty("org.apache.cxf.http.case_insensitive_queries", "false");
+ epr.setProperty("org.apache.cxf.endpoint.private", "false");
+
+ BindingInfo bi = control.createMock(BindingInfo.class);
+ bi.getProperties();
+ EasyMock.expectLastCall().andReturn(new HashMap<String, Object>()).anyTimes();
+ epr.setBinding(bi);
+
+ d.getEndpointInfo();
+ EasyMock.expectLastCall().andReturn(epr).anyTimes();
+ e.setDestination(d);
+ m.put(Message.REQUEST_URI, pathInfo);
+ m.put(Message.QUERY_STRING, query);
+ m.put(Message.HTTP_REQUEST_METHOD, "GET");
+ Endpoint endpoint = control.createMock(Endpoint.class);
+ e.put(Endpoint.class, endpoint);
+ endpoint.get(ProviderFactory.class.getName());
+ EasyMock.expectLastCall().andReturn(ProviderFactory.getSharedInstance());
+ endpoint.getEndpointInfo();
+ EasyMock.expectLastCall().andReturn(epr).anyTimes();
+ control.replay();
+ return m;
+ }
+
+}
Propchange: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/codegen/CodeGeneratorProviderTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/ext/codegen/CodeGeneratorProviderTest.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/UriBuilderImplTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/UriBuilderImplTest.java?rev=921014&r1=921013&r2=921014&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/UriBuilderImplTest.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/impl/UriBuilderImplTest.java Tue Mar 9 17:53:56 2010
@@ -150,6 +150,20 @@ public class UriBuilderImplTest extends
}
@Test
+ public void testQueryWithNoValue() throws Exception {
+ URI uri = new URI("http://bar");
+ URI newUri = new UriBuilderImpl(uri).queryParam("q").build();
+ assertEquals("URI is not built correctly", "http://bar?q", newUri.toString());
+ }
+
+ @Test
+ public void testMatrixWithNoValue() throws Exception {
+ URI uri = new URI("http://bar/foo");
+ URI newUri = new UriBuilderImpl(uri).matrixParam("q").build();
+ assertEquals("URI is not built correctly", "http://bar/foo;q", newUri.toString());
+ }
+
+ @Test
public void testSchemeSpecificPart() throws Exception {
URI uri = new URI("http://bar");
URI newUri = new UriBuilderImpl(uri).scheme("https").schemeSpecificPart("//localhost:8080/foo/bar")
Modified: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/BookStore.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/BookStore.java?rev=921014&r1=921013&r2=921014&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/BookStore.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/BookStore.java Tue Mar 9 17:53:56 2010
@@ -102,6 +102,11 @@ public class BookStore {
return new Chapter(1);
}
+ @Path("form")
+ public FormInterface getForm() {
+ return new Book(1);
+ }
+
@Path("itself")
public BookStore getItself() {
return this;
Added: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/FormInterface.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/FormInterface.java?rev=921014&view=auto
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/FormInterface.java (added)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/FormInterface.java Tue Mar 9 17:53:56 2010
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.jaxrs.model.wadl;
+
+import javax.ws.rs.FormParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.MultivaluedMap;
+
+public interface FormInterface {
+ @Path("/form1")
+ @POST
+ void form1(MultivaluedMap map);
+
+ @Path("/form2")
+ @POST
+ void form2(@FormParam("field1") String f1, @FormParam("field2") String f2);
+}
Propchange: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/FormInterface.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/FormInterface.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/WadlGeneratorTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/WadlGeneratorTest.java?rev=921014&r1=921013&r2=921014&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/WadlGeneratorTest.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/WadlGeneratorTest.java Tue Mar 9 17:53:56 2010
@@ -329,13 +329,14 @@ public class WadlGeneratorTest extends A
List<Element> resourceEls = DOMUtils.getChildrenWithName(resource,
WadlGenerator.WADL_NS, "resource");
- assertEquals(6, resourceEls.size());
+ assertEquals(7, resourceEls.size());
assertEquals("/book2", resourceEls.get(0).getAttribute("path"));
assertEquals("/books/{bookid}", resourceEls.get(1).getAttribute("path"));
assertEquals("/chapter", resourceEls.get(2).getAttribute("path"));
assertEquals("/books/{bookid}", resourceEls.get(3).getAttribute("path"));
assertEquals("/booksubresource", resourceEls.get(4).getAttribute("path"));
- assertEquals("/itself", resourceEls.get(5).getAttribute("path"));
+ assertEquals("/form", resourceEls.get(5).getAttribute("path"));
+ assertEquals("/itself", resourceEls.get(6).getAttribute("path"));
// verify root resource starting with "/"
// must have a single template parameter
Modified: cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/jaxb/Book.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/jaxb/Book.java?rev=921014&r1=921013&r2=921014&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/jaxb/Book.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/wadl/jaxb/Book.java Tue Mar 9 17:53:56 2010
@@ -18,9 +18,7 @@
*/
package org.apache.cxf.jaxrs.model.wadl.jaxb;
-import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
-import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
@@ -31,12 +29,13 @@ import javax.xml.bind.annotation.XmlType
import org.apache.cxf.jaxrs.ext.Description;
import org.apache.cxf.jaxrs.ext.xml.XMLName;
+import org.apache.cxf.jaxrs.model.wadl.FormInterface;
@XmlRootElement(name = "thebook", namespace = "http://superbooks")
@XmlType(name = "book", namespace = "http://superbooks")
@Description("Book subresource")
@XMLName(value = "{http://books}thesuperbook", prefix = "p1")
-public class Book {
+public class Book implements FormInterface {
private int id;
@XmlElement(name = "thechapter", namespace = "http://superbooks")
@@ -70,14 +69,10 @@ public class Book {
return chapter;
}
- @Path("/form1")
- @POST
public void form1(MultivaluedMap map) {
}
- @Path("/form2")
- @POST
- public void form2(@FormParam("field1") String f1, @FormParam("field2") String f2) {
+ public void form2(String f1, String f2) {
}
}