Author: [email protected]
Date: Mon Feb 27 08:53:53 2012
New Revision: 2113

Log:
Improvements for bean instantiation

Modified:
   sandbox/ivol/amdatu-commons/rest-doclet/pom.xml
   
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/ClassAnalyzer.java
   
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/JaxbBeanHelper.java
   
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/RESTDoclet.java

Modified: sandbox/ivol/amdatu-commons/rest-doclet/pom.xml
==============================================================================
--- sandbox/ivol/amdatu-commons/rest-doclet/pom.xml     (original)
+++ sandbox/ivol/amdatu-commons/rest-doclet/pom.xml     Mon Feb 27 08:53:53 2012
@@ -24,7 +24,7 @@
   </parent>
   <artifactId>org.amdatu.commons.restdoclet</artifactId>
   <packaging>jar</packaging>
-  <version>1.0.3</version>
+  <version>1.0.4-SNAPSHOT</version>
   <name>Amdatu Commons - REST Doclet</name>
   <description>A doclet to generate REST documentation</description>
 
@@ -44,7 +44,7 @@
     <dependency>
       <groupId>com.google.code.gson</groupId>
       <artifactId>gson</artifactId>
-      <version>1.4</version>
+      <version>2.1</version>
       <scope>compile</scope>
     </dependency>
     <dependency>

Modified: 
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/ClassAnalyzer.java
==============================================================================
--- 
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/ClassAnalyzer.java
      (original)
+++ 
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/ClassAnalyzer.java
      Mon Feb 27 08:53:53 2012
@@ -15,6 +15,12 @@
  */
 package org.amdatu.commons.restdoclet;
 
+import static javax.ws.rs.core.MediaType.APPLICATION_FORM_URLENCODED;
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static javax.ws.rs.core.MediaType.APPLICATION_XML;
+import static javax.ws.rs.core.MediaType.TEXT_HTML;
+import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -104,30 +110,41 @@
     }
 
     // Returns the consumed types
-    public String getConsumes(MethodDoc methodDoc) throws Exception {
-        String result = "";
+    public StringBuffer getConsumes(MethodDoc methodDoc) throws Exception {
         String[] consumes = getAnnotationValues(methodDoc, Consumes.class);
         if (consumes != null && consumes.length > 0) {
             // Build mimetypes
+            StringBuffer result = new StringBuffer();
             String[] mimeTypes = getMimeTypes(consumes[0]);
-            result += getMimeTypeTable(methodDoc, mimeTypes, true);
-        }
-        else {
-            result = "-";
+            result.append(getMimeTypeTable(methodDoc, mimeTypes, true));
+            return result;
         }
-        return result;
+        return null;
     }
-
-    private String getMimeTypeTable(MethodDoc methodDoc, String[] mimeTypes, 
boolean in) throws Exception {
-        String result = "<table>";
+    
+    private StringBuffer getMimeTypeTable(MethodDoc methodDoc, String[] 
mimeTypes, boolean input) throws Exception {
+        StringBuffer result = new StringBuffer();
+        result.append("<table>");
         for (String mimeType : mimeTypes) {
 
-            result += "<tr><td>" + mimeType + "</td><td>";
+            result.append("<tr><td>" + mimeType + "</td><td>");
 
             List<String> params;
-            if (in) {
-                // Get example, find the JAXB annotated bean
-                params = getParameters(methodDoc, null);
+            if (input) {
+                // If the mimetype is form encoded, we must try to retrieve 
FormParam annotated parameters
+                if (APPLICATION_FORM_URLENCODED.equals(mimeType)) {
+                    params = getParameters(methodDoc, FormParam.class);
+                } else {
+                    // First try the see tag
+                    String seeTagParam = getTypeFromSeeTag(methodDoc);
+                    if (seeTagParam != null) {
+                        params = new ArrayList<String>();
+                        params.add(seeTagParam);
+                    } else {
+                        // Try to get an example from the JAXB annotated bean
+                        params = getParameters(methodDoc, null);
+                    }
+                }
             }
             else {
                 Type returnType = methodDoc.returnType();
@@ -137,61 +154,73 @@
                 }
                 else if 
(Response.class.getCanonicalName().equals(returnType.qualifiedTypeName())) {
                     // Check if there is a @see anotation that indicates the 
return type
-                    SeeTag[] seeTags = methodDoc.seeTags();
-                    if (seeTags != null && seeTags.length > 0) {
-                        for (SeeTag seeTag : seeTags) {
-                            if (seeTag.referencedClass() != null) {
-                                
params.add(seeTag.referencedClass().qualifiedTypeName());
-                            }
-                        }
+                    String seeTagParam = getTypeFromSeeTag(methodDoc);
+                    if (seeTagParam != null) {
+                        params.add(seeTagParam);
                     }
                     if (params.size() == 0) {
-                        if (mimeType.equals("text/plain") || 
mimeType.equals("text/html")) {
+                        if (mimeType.equals(TEXT_PLAIN) || 
mimeType.equals(TEXT_HTML)) {
                             params.add("");
                         }
                         else {
-                            result += Response.class.getCanonicalName();
+                            result.append(Response.class.getCanonicalName());
                         }
                     }
                 }
             }
             for (String param : params) {
-                if ("text/plain".equals(mimeType)) {
-                    result += "Some text";
+                if (TEXT_PLAIN.equals(mimeType)) {
+                    result.append("Some text");
                 }
-                else if ("text/html".equals(mimeType)) {
-                    result += "Some html";
+                else if (TEXT_HTML.equals(mimeType)) {
+                    result.append("Some html");
                 }
-                else if ("application/json".equals(mimeType)) {
-                    Object obj = m_beanHelper.createBean(param);
-                    result += m_beanHelper.toJSON(obj);
+                else if (APPLICATION_JSON.equals(mimeType)) {
+                    Object obj = m_beanHelper.createBean(param, mimeType, 
getHTTPMethod(methodDoc));
+                    result.append(m_beanHelper.toJSON(obj));
                 }
-                else if ("application/xml".equals(mimeType)) {
-                    Object obj = m_beanHelper.createBean(param);
-                    result += m_beanHelper.toXML(obj);
+                else if (APPLICATION_XML.equals(mimeType)) {
+                    Object obj = m_beanHelper.createBean(param, mimeType, 
getHTTPMethod(methodDoc));
+                    result.append(m_beanHelper.toXML(obj));
                 }
-                else if ("application/x-www-form-urlencoded".equals(mimeType)) 
{
+                else if (APPLICATION_FORM_URLENCODED.equals(mimeType)) {
                     List<String> formParams = getFormParameters(methodDoc);
-                    result += "<ul>";
+                    result.append("<ul>");
                     for (String formParam : formParams) {
-                        result += "<li>" + formParam + "</li>";
+                        result.append("<li>" + formParam + "</li>");
                     }
-                    result += "</ul>";
+                    result.append("</ul>");
                 }
             }
-            result += "</td></tr>";
+            result.append("</td></tr>");
         }
-        result += "</table>";
+        result.append("</table>");
         return result;
     }
+    
+    private String getTypeFromSeeTag(MethodDoc methodDoc) {
+        SeeTag[] seeTags = methodDoc.seeTags();
+        if (seeTags != null && seeTags.length > 0) {
+            for (SeeTag seeTag : seeTags) {
+                if (seeTag.referencedClass() != null) {
+                    String name = seeTag.referencedClass().qualifiedTypeName();
+                    if (seeTag.referencedMemberName() != null) {
+                        name += "#" + seeTag.referencedMemberName();
+                    } 
+                    return name;
+                }
+            }
+        }
+        return null;
+    }
 
-    public String getProduces(MethodDoc methodDoc) throws Exception {
+    public StringBuffer getProduces(MethodDoc methodDoc) throws Exception {
         String[] produces = getAnnotationValues(methodDoc, Produces.class);
         if (produces != null && produces.length > 0) {
             return getMimeTypeTable(methodDoc, getMimeTypes(produces[0]), 
false);
         }
         else
-            return "-";
+            return new StringBuffer().append("-");
     }
 
     private String[] getMimeTypes(String mimeTypeString) {
@@ -236,7 +265,7 @@
     }
 
     private List<String> getParameters(MethodDoc methodDoc, Class<?> 
annotationClass) {
-        List<String> pathParameters = new ArrayList<String>();
+        List<String> parameters = new ArrayList<String>();
         Parameter[] params = methodDoc.parameters();
         if (params != null) {
             ParamTag[] tags = methodDoc.paramTags();
@@ -260,18 +289,18 @@
                                 if (javadoc != null) {
                                     descr += " : " + javadoc;
                                 }
-                                pathParameters.add(descr);
+                                parameters.add(descr);
                             }
                         }
                     }
                 }
                 else if (annotationClass == null) {
                     // No annotations, this must be a JAXB annotated bean
-                    pathParameters.add(param.type().toString());
+                    parameters.add(param.type().toString());
                 }
             }
         }
-        return pathParameters;
+        return parameters;
     }
 
     private String[] getAnnotationValues(AnnotationDesc[] annotationDescs, 
Class<?> annotation) {

Modified: 
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/JaxbBeanHelper.java
==============================================================================
--- 
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/JaxbBeanHelper.java
     (original)
+++ 
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/JaxbBeanHelper.java
     Mon Feb 27 08:53:53 2012
@@ -15,6 +15,7 @@
  */
 package org.amdatu.commons.restdoclet;
 
+import java.io.IOException;
 import java.io.StringWriter;
 import java.io.Writer;
 import java.lang.reflect.Method;
@@ -23,6 +24,7 @@
 
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.Marshaller;
+import javax.xml.bind.annotation.XmlRootElement;
 
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
@@ -30,7 +32,7 @@
 @SuppressWarnings({"restriction", "rawtypes", "unchecked"})
 public class JaxbBeanHelper {
     private final static Gson GSON = new 
GsonBuilder().setPrettyPrinting().create();
-    
+
     private ClassLoader m_sourceClassLoader;
 
     public JaxbBeanHelper(ClassLoader cl) {
@@ -43,16 +45,58 @@
             return true;
         }
         catch (ClassNotFoundException e) {
-           return false;
+            return false;
         }
     }
-    
-    public Object createBean(String className) throws Exception {
+
+    public Object createBean(String classMethod, String mimeType, String 
httpMethod) throws Exception {
+        String className = classMethod;
+        String methodName = null;
+        if (classMethod.indexOf("#") != -1) {
+            className = classMethod.substring(0, classMethod.indexOf("#"));
+            methodName = classMethod.substring(classMethod.indexOf("#") + 1);
+        }
         Class<?> clazz = m_sourceClassLoader.loadClass(className);
-        return createBean(clazz, 1);
+        return createBean(clazz, 1, methodName, mimeType, httpMethod);
     }
-    
-    public Object createBean(Class<?> clazz, int index) throws Exception {
+
+    public Object createBean(Class<?> clazz, int index, String methodName, 
String mimeType, String httpMethod)
+        throws Exception {
+        // By conventions, the class may contain a static method 
getExampleInstance() which returns
+        // an example instance of this bean for the purpose of documentation. 
Try to find this method,
+        // otherwise we generate our own instance
+        try {
+            String mName = methodName != null ? methodName : 
"getExampleInstance";
+
+            // 1. Try invocation with mimetype and http method
+            try {
+                Method method = clazz.getDeclaredMethod(mName, new Class<?>[] 
{String.class, String.class});
+                if (method.getReturnType().isAssignableFrom(clazz)) {
+                    return method.invoke(null, mimeType, httpMethod);
+                }
+            }
+            catch (NoSuchMethodException e) {
+            }
+
+            // 2. Try invocation with only mimetype
+            try {
+                Method method = clazz.getDeclaredMethod(mName, new Class<?>[] 
{String.class});
+                if (method.getReturnType().isAssignableFrom(clazz)) {
+                    return method.invoke(null, mimeType);
+                }
+            }
+            catch (NoSuchMethodException e) {
+            }
+
+            // 3. Try invocation with no parameters
+            Method method = clazz.getDeclaredMethod(mName, new Class<?>[0]);
+            if (method.getReturnType().isAssignableFrom(clazz)) {
+                return method.invoke(null);
+            }
+        }
+        catch (Exception e) {
+        }
+
         // Invoke default constructor
         Object obj = clazz.newInstance();
 
@@ -79,17 +123,18 @@
                         String type = 
method.getGenericParameterTypes()[0].toString();
                         String cls = type.substring(type.indexOf("<") + 1, 
type.indexOf(">"));
                         Class listClass = m_sourceClassLoader.loadClass(cls);
-                        Object val1 = createBean(listClass, 1);
-                        Object val2 = createBean(listClass, 2);
+                        Object val1 = createBean(listClass, 1, null, mimeType, 
httpMethod);
+                        Object val2 = createBean(listClass, 2, null, mimeType, 
httpMethod);
                         List values = new ArrayList();
                         values.add(val1);
                         values.add(val2);
                         method.invoke(obj, values);
-                    } else {
+                    }
+                    else {
                         // Another bean type
                         String type = paramType.getName();
                         Class listClass = m_sourceClassLoader.loadClass(type);
-                        Object val = createBean(listClass, 1);
+                        Object val = createBean(listClass, 1, null, mimeType, 
httpMethod);
                         method.invoke(obj, val);
                     }
                 }
@@ -97,27 +142,34 @@
         }
         return obj;
     }
-    
-    public String toJSON(Object bean) {
+
+    public String toJSON(Object bean) throws IOException {
+        XmlRootElement rootElement = 
bean.getClass().getAnnotation(XmlRootElement.class);
+        String name = null;
+        if (rootElement != null) {
+            name = rootElement.name();
+        }
         String json = GSON.toJson(bean);
+
+        json = "{\"" + name + "\": " + json + "}";
         json = json.replace(" ", "&nbsp;").replace("\n", "<br/>");
         return json;
     }
-    
+
     public String toXML(Object bean) throws Exception {
         JAXBContext context = JAXBContext.newInstance(bean.getClass());
         Marshaller marshaller = context.createMarshaller();
         marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
-        
+
         Writer sWriter = new StringWriter();
-        marshaller.marshal(bean, sWriter); 
-        
+        marshaller.marshal(bean, sWriter);
+
         String html = sWriter.toString();
         html = html.replace("<", "&lt;");
         html = html.replace(">", "&gt;");
         html = html.replace("\n", "<br/>");
         html = html.replace(" ", "&nbsp;");
-        
+
         return html;
     }
 }

Modified: 
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/RESTDoclet.java
==============================================================================
--- 
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/RESTDoclet.java
 (original)
+++ 
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/RESTDoclet.java
 Mon Feb 27 08:53:53 2012
@@ -43,19 +43,21 @@
 
     public static void main(String[] args) {
         log("Executing RESTDoclet");
-        com.sun.tools.javadoc.Main.execute(new String[] { "@options", 
"@packages" });
+        System.out.println("!!!!!!!!!!LC: " + 
RESTDoclet.class.getClassLoader().toString());
+
+        com.sun.tools.javadoc.Main.execute(new String[] {"@options"});
     }
-    
+
     private static void log(String msg) {
         System.out.println("[INFO] " + msg);
     }
 
     public static boolean start(RootDoc root) throws Exception {
         log("Generating REST dcoumentation");
-      
-        // Initialize the sourec class loader
+
+        // Initialize the source class loader
         m_classAnalyzer.setSourceClassLoader(createSourceClassLoader(root));
-        
+
         // Ensure /html exists
         new File("html").mkdir();
 
@@ -77,7 +79,7 @@
         log("Finished REST documentation");
         return true;
     }
-    
+
     private static URLClassLoader createSourceClassLoader(RootDoc root) throws 
MalformedURLException {
         String classpath = "";
         for (String[] option : root.options()) {
@@ -85,17 +87,17 @@
                 classpath = option[1];
             }
         }
-        
+
         // Depending on OS the classpath separator is ; or :
         String sep = File.pathSeparator;
         String[] classPathEntries = classpath.split(sep);
         URL[] urls = new URL[classPathEntries.length];
-        for (int i=0; i<classPathEntries.length; i++) {
+        for (int i = 0; i < classPathEntries.length; i++) {
             urls[i] = new File(classPathEntries[i]).toURL();
         }
-        
+
         log("classpath=" + classpath);
-        return new URLClassLoader(urls);
+        return new URLClassLoader(urls, RESTDoclet.class.getClassLoader());
     }
 
     private static void copyFile(String source, String target) throws 
IOException {
@@ -106,7 +108,7 @@
         if (new File("html/" + target).exists()) {
             new File("html/" + target).delete();
         }
-        
+
         InputStream is = null;
         FileOutputStream out = null;
         try {
@@ -115,7 +117,7 @@
 
             byte[] bytes = new byte[1024];
             int len;
-            while ((len  = is.read(bytes)) != -1) {
+            while ((len = is.read(bytes)) != -1) {
                 out.write(bytes, 0, len);
             }
         }
@@ -172,7 +174,7 @@
         lines.add("</head>");
         lines.add("<body>");
         lines.add("<div class='ui-state-highlight ui-corner-all' 
align='center'>");
-        lines.add("<h3>REST documentation for " +  
m_classAnalyzer.getPath(classDoc, null) + "</h3></div>");
+        lines.add("<h3>REST documentation for " + 
m_classAnalyzer.getPath(classDoc, null) + "</h3></div>");
         lines.add("<div id='accordion'>");
         FileUtils.writeLines(m_file, lines, EOL, true);
     }
@@ -189,20 +191,36 @@
         log("    Generating documentation for HTTP method " + 
methodDoc.name());
 
         Collection<String> lines = new ArrayList<String>();
-        lines.add("<h3><a href='#'>" + 
m_classAnalyzer.getHTTPMethod(methodDoc) + " " 
-                        + m_classAnalyzer.getPath(classDoc, methodDoc) + 
"</a></h3>");
+        lines.add("<h3><a href='#'>" + 
m_classAnalyzer.getHTTPMethod(methodDoc) + " "
+            + m_classAnalyzer.getPath(classDoc, methodDoc) + "</a></h3>");
         lines.add("<div><table>");
-        
+
         lines.add(getRow("Method", m_classAnalyzer.getHTTPMethod(methodDoc)));
         lines.add(getRow("URI", m_classAnalyzer.getPath(classDoc, methodDoc)));
-        lines.add(getRow("Path parameters", 
toUl(m_classAnalyzer.getPathParameters(methodDoc))));
-        lines.add(getRow("Query parameters", 
toUl(m_classAnalyzer.getQueryParameters(methodDoc))));
+
+        // Path parameters
+        List<String> pathParameters = 
m_classAnalyzer.getPathParameters(methodDoc);
+        if (pathParameters.size() > 0) {
+            lines.add(getRow("Path parameters", toUl(pathParameters)));
+        }
+
+        // Query parameters
+        List<String> queryParameters = 
m_classAnalyzer.getQueryParameters(methodDoc);
+        if (queryParameters.size() > 0) {
+            lines.add(getRow("Query parameters", toUl(queryParameters)));
+        }
         
+        // Description
         lines.add(getRow("Description", 
m_classAnalyzer.getDescription(methodDoc)));
-        
-        lines.add(getRow("Consumes", m_classAnalyzer.getConsumes(methodDoc)));
+
+        // Consumes
+        StringBuffer consumes = m_classAnalyzer.getConsumes(methodDoc);
+        if (consumes != null) {
+            lines.add(getRow("Consumes", consumes));
+        }
         lines.add(getRow("Produces", m_classAnalyzer.getProduces(methodDoc)));
-        
+
+        // Response
         lines.add(getRow("Response", m_classAnalyzer.getReturn(methodDoc)));
         lines.add("</table></div>");
         FileUtils.writeLines(m_file, lines, EOL, true);
@@ -212,6 +230,10 @@
         return "<tr><th>" + key + "</th><td>" + value + "</td></tr>";
     }
 
+    private static String getRow(String key, StringBuffer value) {
+        return "<tr><th>" + key + "</th><td>" + value.toString() + 
"</td></tr>";
+    }
+
     private static String toUl(List<String> values) {
         if (values != null && values.size() > 0) {
             String ul = "<ul>";
_______________________________________________
Amdatu-commits mailing list
[email protected]
http://lists.amdatu.org/mailman/listinfo/amdatu-commits

Reply via email to