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 2011/05/06 18:44:54 UTC
svn commit: r1100277 [1/2] - in /cxf/trunk:
rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/codegen/ tools/
tools/wadlto/ tools/wadlto/jaxrs/ tools/wadlto/jaxrs/src/
tools/wadlto/jaxrs/src/main/ tools/wadlto/jaxrs/src/main/java/
tools/wadlto/j...
Author: sergeyb
Date: Fri May 6 16:44:53 2011
New Revision: 1100277
URL: http://svn.apache.org/viewvc?rev=1100277&view=rev
Log:
[CXF-3498] Starting working on wadltojava tool
Added:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/codegen/SourceGenerator.java (with props)
cxf/trunk/tools/wadlto/
cxf/trunk/tools/wadlto/jaxrs/
cxf/trunk/tools/wadlto/jaxrs/pom.xml (with props)
cxf/trunk/tools/wadlto/jaxrs/src/
cxf/trunk/tools/wadlto/jaxrs/src/main/
cxf/trunk/tools/wadlto/jaxrs/src/main/java/
cxf/trunk/tools/wadlto/jaxrs/src/main/java/org/
cxf/trunk/tools/wadlto/jaxrs/src/main/java/org/apache/
cxf/trunk/tools/wadlto/jaxrs/src/main/java/org/apache/cxf/
cxf/trunk/tools/wadlto/jaxrs/src/main/java/org/apache/cxf/tools/
cxf/trunk/tools/wadlto/jaxrs/src/main/java/org/apache/cxf/tools/wadlto/
cxf/trunk/tools/wadlto/jaxrs/src/main/java/org/apache/cxf/tools/wadlto/jaxrs/
cxf/trunk/tools/wadlto/jaxrs/src/main/java/org/apache/cxf/tools/wadlto/jaxrs/JAXRSContainer.java (with props)
cxf/trunk/tools/wadlto/jaxrs/src/main/java/org/apache/cxf/tools/wadlto/jaxrs/jaxrs-toolspec.xml (with props)
cxf/trunk/tools/wadlto/jaxrs/src/main/resources/
cxf/trunk/tools/wadlto/jaxrs/src/test/
cxf/trunk/tools/wadlto/jaxrs/src/test/java/
cxf/trunk/tools/wadlto/jaxrs/src/test/java/org/
cxf/trunk/tools/wadlto/jaxrs/src/test/java/org/apache/
cxf/trunk/tools/wadlto/jaxrs/src/test/java/org/apache/cxf/
cxf/trunk/tools/wadlto/jaxrs/src/test/java/org/apache/cxf/tools/
cxf/trunk/tools/wadlto/jaxrs/src/test/java/org/apache/cxf/tools/wadlto/
cxf/trunk/tools/wadlto/jaxrs/src/test/java/org/apache/cxf/tools/wadlto/jaxrs/
cxf/trunk/tools/wadlto/jaxrs/src/test/java/org/apache/cxf/tools/wadlto/jaxrs/JAXRSContainerTest.java (with props)
cxf/trunk/tools/wadlto/jaxrs/src/test/resources/
cxf/trunk/tools/wadlto/jaxrs/src/test/resources/wadl/
cxf/trunk/tools/wadlto/jaxrs/src/test/resources/wadl/bookstore.xml (with props)
cxf/trunk/tools/wadlto/pom.xml (with props)
Modified:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/codegen/CodeGeneratorProvider.java
cxf/trunk/tools/pom.xml
Modified: 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=1100277&r1=1100276&r2=1100277&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/codegen/CodeGeneratorProvider.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/codegen/CodeGeneratorProvider.java Fri May 6 16:44:53 2011
@@ -22,66 +22,27 @@ 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.Level;
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.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;
@@ -89,7 +50,6 @@ import org.apache.cxf.jaxrs.model.wadl.W
import org.apache.cxf.jaxrs.provider.ProviderFactory;
import org.apache.cxf.jaxrs.utils.JAXRSUtils;
import org.apache.cxf.message.Message;
-import org.apache.cxf.staxutils.StaxUtils;
public class CodeGeneratorProvider implements RequestHandler {
public static final String CODE_QUERY = "_code";
@@ -97,36 +57,14 @@ public class CodeGeneratorProvider imple
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;
@@ -183,7 +121,13 @@ public class CodeGeneratorProvider imple
+ " can not be loaded");
return Response.noContent().build();
}
- generateSource(wadl, srcDir, codeType);
+
+ Map<String, String> properties = getProperties();
+ SourceGenerator sg = new SourceGenerator(properties);
+ sg.setGenerateInterfaces(generateInterfaces);
+ sg.setImportsComparator(importsComparator);
+ sg.generateSource(wadl, srcDir, codeType);
+
zipSource(srcDir, zipDir);
return getLink(zipDir, m);
} catch (Exception ex) {
@@ -198,18 +142,23 @@ public class CodeGeneratorProvider imple
}
}
+ private Map<String, String> getProperties() {
+ Map<String, String> map = new HashMap<String, String>();
+ map.put(SourceGenerator.LINE_SEP_PROPERTY, getLineSep());
+ map.put(SourceGenerator.FILE_SEP_PROPERTY, getFileSep());
+ return map;
+ }
+
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);
}
@@ -219,15 +168,15 @@ public class CodeGeneratorProvider imple
private String getLineSep() {
String os = ui.getQueryParameters().getFirst(OS_QUERY);
if (os == null) {
- return "\r\n";
+ return System.getProperty(SourceGenerator.LINE_SEP_PROPERTY);
}
return "unix".equals(os) ? "\r" : "\r\n";
}
- protected String getPathSep() {
+ private String getFileSep() {
String os = ui.getQueryParameters().getFirst(OS_QUERY);
if (os == null) {
- return "\\";
+ return System.getProperty(SourceGenerator.FILE_SEP_PROPERTY);
}
return "unix".equals(os) ? "/" : "\\";
}
@@ -303,590 +252,12 @@ public class CodeGeneratorProvider imple
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);
- if (Boolean.valueOf(paramEl.getAttribute("repeating"))) {
- addImport(imports, List.class.getName());
- type = "List<" + type + ">";
- }
- 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 {
- return StaxUtils.read(new InputSource(new StringReader(wadl))).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);
- }
- }
-
- 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);
-
-
- Object elForRun = ReflectionInvokationHandler
- .createProxyWrapper(new InnerErrorListener(),
- JAXBUtils.getParamClass(compiler, "setErrorListener"));
-
- compiler.setErrorListener(elForRun);
- S2JJAXBModel intermediateModel = compiler.bind();
- 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;
- }
- }
-
- 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
- }
- }
}
Added: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/codegen/SourceGenerator.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/codegen/SourceGenerator.java?rev=1100277&view=auto
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/codegen/SourceGenerator.java (added)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/codegen/SourceGenerator.java Fri May 6 16:44:53 2011
@@ -0,0 +1,721 @@
+/**
+ * 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.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+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 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.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.xml.namespace.QName;
+
+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.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.model.wadl.WadlGenerator;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.staxutils.StaxUtils;
+
+public class SourceGenerator {
+ public static final String CODE_TYPE_GRAMMAR = "grammar";
+ public static final String CODE_TYPE_PROXY = "proxy";
+ public static final String CODE_TYPE_WEB = "web";
+ public static final String LINE_SEP_PROPERTY = "line.separator";
+ public static final String FILE_SEP_PROPERTY = "file.separator";
+
+ private static final Logger LOG = LogUtils.getL7dLogger(SourceGenerator.class);
+
+ 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 boolean generateInterfaces = true;
+
+ private Map<String, String> properties;
+
+ public SourceGenerator() {
+ this(Collections.<String, String>emptyMap());
+ }
+
+ public SourceGenerator(Map<String, String> properties) {
+ this.properties = properties;
+ }
+
+ private String getLineSep() {
+ String value = properties.get(LINE_SEP_PROPERTY);
+ return value == null ? System.getProperty(LINE_SEP_PROPERTY) : value;
+ }
+
+ private String getFileSep() {
+ String value = properties.get(FILE_SEP_PROPERTY);
+ return value == null ? System.getProperty(FILE_SEP_PROPERTY) : value;
+ }
+
+ public 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());
+ }
+
+ private 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);
+ if (Boolean.valueOf(paramEl.getAttribute("repeating"))) {
+ addImport(imports, List.class.getName());
+ type = "List<" + type + ">";
+ }
+ 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();
+
+ String namespace = qname.getNamespaceURI();
+ namespace = namespace.replace(".", getFileSep());
+
+ File currentDir = new File(src.getAbsolutePath(), namespace);
+ 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 {
+ return StaxUtils.read(new InputSource(new StringReader(wadl))).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);
+ }
+ }
+
+ 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);
+
+
+ Object elForRun = ReflectionInvokationHandler
+ .createProxyWrapper(new InnerErrorListener(),
+ JAXBUtils.getParamClass(compiler, "setErrorListener"));
+
+ compiler.setErrorListener(elForRun);
+ S2JJAXBModel intermediateModel = compiler.bind();
+ 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;
+ }
+ }
+
+ 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/SourceGenerator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/codegen/SourceGenerator.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified: cxf/trunk/tools/pom.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/tools/pom.xml?rev=1100277&r1=1100276&r2=1100277&view=diff
==============================================================================
--- cxf/trunk/tools/pom.xml (original)
+++ cxf/trunk/tools/pom.xml Fri May 6 16:44:53 2011
@@ -36,6 +36,7 @@
<module>validator</module>
<module>wsdlto</module>
<module>javato</module>
+ <module>wadlto</module>
<module>corba</module>
</modules>
Added: cxf/trunk/tools/wadlto/jaxrs/pom.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/tools/wadlto/jaxrs/pom.xml?rev=1100277&view=auto
==============================================================================
--- cxf/trunk/tools/wadlto/jaxrs/pom.xml (added)
+++ cxf/trunk/tools/wadlto/jaxrs/pom.xml Fri May 6 16:44:53 2011
@@ -0,0 +1,71 @@
+<!--
+ 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-tools-wadlto-jaxrs</artifactId>
+ <packaging>jar</packaging>
+ <version>2.4.1-SNAPSHOT</version>
+ <name>Apache CXF Command Line Tools WADLTo JAXRS Frontend</name>
+ <url>http://cxf.apache.org</url>
+
+ <parent>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-parent</artifactId>
+ <version>2.4.1-SNAPSHOT</version>
+ <relativePath>../../../../parent/pom.xml</relativePath>
+ </parent>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-tools-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-frontend-jaxrs</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>xml-resolver</groupId>
+ <artifactId>xml-resolver</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-core</artifactId>
+ <version>${project.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-testutils</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+
+ </dependencies>
+
+
+</project>
Propchange: cxf/trunk/tools/wadlto/jaxrs/pom.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/tools/wadlto/jaxrs/pom.xml
------------------------------------------------------------------------------
svn:keywords = Rev Date
Propchange: cxf/trunk/tools/wadlto/jaxrs/pom.xml
------------------------------------------------------------------------------
svn:mime-type = text/xml
Added: cxf/trunk/tools/wadlto/jaxrs/src/main/java/org/apache/cxf/tools/wadlto/jaxrs/JAXRSContainer.java
URL: http://svn.apache.org/viewvc/cxf/trunk/tools/wadlto/jaxrs/src/main/java/org/apache/cxf/tools/wadlto/jaxrs/JAXRSContainer.java?rev=1100277&view=auto
==============================================================================
--- cxf/trunk/tools/wadlto/jaxrs/src/main/java/org/apache/cxf/tools/wadlto/jaxrs/JAXRSContainer.java (added)
+++ cxf/trunk/tools/wadlto/jaxrs/src/main/java/org/apache/cxf/tools/wadlto/jaxrs/JAXRSContainer.java Fri May 6 16:44:53 2011
@@ -0,0 +1,108 @@
+/**
+ * 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.tools.wadlto.jaxrs;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+
+import org.apache.cxf.helpers.IOUtils;
+import org.apache.cxf.jaxrs.ext.codegen.SourceGenerator;
+import org.apache.cxf.tools.common.AbstractCXFToolContainer;
+import org.apache.cxf.tools.common.ClassUtils;
+import org.apache.cxf.tools.common.ToolConstants;
+import org.apache.cxf.tools.common.ToolException;
+import org.apache.cxf.tools.common.toolspec.ToolSpec;
+import org.apache.cxf.tools.common.toolspec.parser.BadUsageException;
+import org.apache.cxf.tools.util.URIParserUtil;
+
+public class JAXRSContainer extends AbstractCXFToolContainer {
+
+ private static final String TOOL_NAME = "wadl2java";
+
+ public JAXRSContainer(ToolSpec toolspec) throws Exception {
+ super(TOOL_NAME, toolspec);
+ }
+
+ public void execute() throws ToolException {
+ if (hasInfoOption()) {
+ return;
+ }
+
+ buildToolContext();
+
+ processWadl();
+
+ }
+
+ public void execute(boolean exitOnFinish) throws ToolException {
+ try {
+ if (getArgument() != null) {
+ super.execute(exitOnFinish);
+ }
+ execute();
+
+ } catch (ToolException ex) {
+ if (ex.getCause() instanceof BadUsageException) {
+ printUsageException(TOOL_NAME, (BadUsageException)ex.getCause());
+ }
+ throw ex;
+ } catch (Exception ex) {
+ throw new ToolException(ex);
+ } finally {
+ tearDown();
+ }
+ }
+
+ public void buildToolContext() {
+ getContext();
+ if (context.get(ToolConstants.CFG_OUTPUTDIR) == null) {
+ context.put(ToolConstants.CFG_OUTPUTDIR, ".");
+ }
+ }
+
+ private void processWadl() {
+ File outDir = new File((String)context.get(ToolConstants.CFG_OUTPUTDIR));
+ String wadl = readWadl();
+
+ SourceGenerator sg = new SourceGenerator();
+
+ // generate
+ sg.generateSource(wadl, outDir, "proxy");
+
+ // compile
+ if (context.optionSet(ToolConstants.CFG_COMPILE)) {
+ new ClassUtils().compile(context);
+ }
+
+ }
+
+ protected String readWadl() {
+ String wadlURL = (String)context.get(ToolConstants.CFG_WSDLURL);
+ wadlURL = URIParserUtil.getAbsoluteURI(wadlURL);
+
+ try {
+ URL url = new URL(wadlURL);
+ return IOUtils.toString(url.openStream());
+ } catch (IOException e) {
+ throw new ToolException(e);
+ }
+ }
+}
Propchange: cxf/trunk/tools/wadlto/jaxrs/src/main/java/org/apache/cxf/tools/wadlto/jaxrs/JAXRSContainer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/tools/wadlto/jaxrs/src/main/java/org/apache/cxf/tools/wadlto/jaxrs/JAXRSContainer.java
------------------------------------------------------------------------------
svn:keywords = Rev Date