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