Author: [email protected]
Date: Fri Jan 13 09:16:55 2012
New Revision: 1910

Log:


Added:
   
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/
   
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/RESTDoclet.java

Added: 
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/ClassAnalyzer.java
==============================================================================
--- (empty file)
+++ 
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/ClassAnalyzer.java
      Fri Jan 13 09:16:55 2012
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2010, 2011 The Amdatu Foundation
+ *
+ * Licensed 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.amdatu.commons.restdoclet;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.ws.rs.DELETE;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.GET;
+import javax.ws.rs.HEAD;
+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.QueryParam;
+
+import com.sun.javadoc.AnnotationDesc;
+import com.sun.javadoc.AnnotationDesc.ElementValuePair;
+import com.sun.javadoc.AnnotationTypeDoc;
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.MethodDoc;
+import com.sun.javadoc.ParamTag;
+import com.sun.javadoc.Parameter;
+import com.sun.javadoc.Tag;
+
+public class ClassAnalyzer {
+    private static final Class<?>[] HTTP_METHODS = new Class[] { GET.class, 
POST.class, PUT.class, DELETE.class,
+        HEAD.class, OPTIONS.class };
+
+    // Returns the REST Path
+    public String getPath(ClassDoc classDoc, MethodDoc methodDoc) {
+        String path = "/rest";
+        String[] classPath = getAnnotationValues(classDoc, Path.class);
+        if (classPath != null && classPath.length == 1) {
+            path += "/" + classPath[0];
+        }
+        String[] resourcePath = getAnnotationValues(methodDoc, Path.class);
+        if (resourcePath != null && resourcePath.length == 1) {
+            if (resourcePath[0].startsWith("/")) {
+                path += resourcePath[0];
+            }
+            else {
+                path += "/" + resourcePath[0];
+            }
+        }
+        return path;
+    }
+
+    // Returns the HTTP Method annotation
+    public String getHTTPMethod(MethodDoc methodDoc) {
+        AnnotationDesc[] annotationDescs = methodDoc.annotations();
+        if (annotationDescs != null) {
+            for (AnnotationDesc annotationDesc : annotationDescs) {
+                AnnotationTypeDoc type = annotationDesc.annotationType();
+                for (Class<?> httpMethod : HTTP_METHODS) {
+                    if (type.qualifiedName().equals(httpMethod.getName())) {
+                        return 
type.qualifiedName().substring(type.qualifiedName().lastIndexOf(".") + 1);
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    public String[] getAnnotationValues(ClassDoc classDoc, Class<?> 
annotation) {
+        return getAnnotationValues(classDoc.annotations(), annotation);
+    }
+
+    public String[] getAnnotationValues(MethodDoc methodDoc, Class<?> 
annotation) {
+        return getAnnotationValues(methodDoc.annotations(), annotation);
+    }
+
+    // Returns the descriptive javadoc
+    public String getDescription(MethodDoc methodDoc) {
+        return methodDoc.commentText();
+    }
+
+    // Returns the description of all PathParam annotated parameters
+    public List<String> getPathParameters(MethodDoc methodDoc) {
+        return getParameters(methodDoc, PathParam.class);
+    }
+
+    // Returns the description of all QueryParam annotated parameters
+    public List<String> getQueryParameters(MethodDoc methodDoc) {
+        return getParameters(methodDoc, QueryParam.class);
+    }
+
+    // Returns the description of all formParam annotated parameters
+    public List<String> getFormParameters(MethodDoc methodDoc) {
+        return getParameters(methodDoc, FormParam.class);
+    }
+
+    public String getReturn(MethodDoc methodDoc) {
+        Tag[] tags = methodDoc.tags();
+        if (tags != null) {
+            for (Tag tag : tags) {
+                if ("@return".equals(tag.kind())) {
+                    return tag.text();
+                }
+            }
+        }
+        return "-";
+    }
+
+    private List<String> getParameters(MethodDoc methodDoc, Class<?> 
annotationClass) {
+        List<String> pathParameters = new ArrayList<String>();
+        Parameter[] params = methodDoc.parameters();
+        if (params != null) {
+            ParamTag[] tags = methodDoc.paramTags();
+            for (Parameter param : params) {
+                AnnotationDesc[] annotationDescs = param.annotations();
+                if (annotationDescs != null) {
+                    for (AnnotationDesc annotationDesc : annotationDescs) {
+                        AnnotationTypeDoc type = 
annotationDesc.annotationType();
+                        if 
(type.qualifiedName().equals(annotationClass.getName())) {
+                            // This is a path parameter, find the param tag 
matching the parameter
+                            String javadoc = null;
+                            if (tags != null) {
+                                for (ParamTag tag : tags) {
+                                    if 
(tag.parameterName().equals(param.name())) {
+                                        javadoc = tag.parameterComment();
+                                    }
+                                }
+                            }
+                            String descr = param.toString();
+                            if (javadoc != null) {
+                                descr += " : " + javadoc;
+                            }
+                            pathParameters.add(descr);
+                        }
+                    }
+                }
+            }
+        }
+        return pathParameters;
+    }
+
+    private String[] getAnnotationValues(AnnotationDesc[] annotationDescs, 
Class<?> annotation) {
+        if (annotationDescs != null) {
+            for (AnnotationDesc annotationDesc : annotationDescs) {
+                AnnotationTypeDoc type = annotationDesc.annotationType();
+                if (type.qualifiedName().equals(annotation.getName())) {
+                    String[] vals = new 
String[annotationDesc.elementValues().length];
+                    int i = 0;
+                    for (ElementValuePair value : 
annotationDesc.elementValues()) {
+                        vals[i] = omitQuotes(value.value().toString());
+                        i++;
+                    }
+                    return vals;
+                }
+            }
+        }
+        return null;
+    }
+
+    private String omitQuotes(String value) {
+        String result = value;
+        if (result.startsWith("\"")) {
+            result = result.substring(1);
+        }
+        if (result.endsWith("\"")) {
+            result = result.substring(0, result.length() - 1);
+        }
+        return result;
+    }
+}

Added: 
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/RESTDoclet.java
==============================================================================
--- (empty file)
+++ 
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/RESTDoclet.java
 Fri Jan 13 09:16:55 2012
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2010, 2011 The Amdatu Foundation
+ *
+ * Licensed 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.amdatu.commons.restdoclet;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import javax.ws.rs.Path;
+
+import org.apache.commons.io.FileUtils;
+
+import com.sun.javadoc.ClassDoc;
+import com.sun.javadoc.MethodDoc;
+import com.sun.javadoc.RootDoc;
+
+public class RESTDoclet {
+
+    private final static String EOL = System.getProperty("line.separator");
+
+    private static File m_file = null;
+
+    private static ClassAnalyzer m_classAnalyzer = new ClassAnalyzer();
+
+    public static void main(String[] args) {
+        com.sun.tools.javadoc.Main.execute(new String[] { "@options", 
"@packages" });
+    }
+
+    public static boolean start(RootDoc root) throws IOException {
+        System.out.println("***** Generating REST dcoumentation for " + 
root.getClass().toString() + " *****");
+        
+        // Ensure /html exists
+        new File("html").mkdir();
+        
+        ClassDoc[] docClasses = root.classes();
+        for (int i = 0; i < docClasses.length; ++i) {
+            // Detect if the JAX-RS @Path annotation is present, this makes it 
a REST service
+            String[] annotations = 
m_classAnalyzer.getAnnotationValues(docClasses[i], Path.class);
+            if (annotations != null && annotations.length > 0) {
+                handle(docClasses[i]);
+            }
+        }
+        System.out.println("***** DONE ****");
+        return true;
+    }
+
+    private static void handle(ClassDoc classDoc) throws IOException {
+        System.out.println("> Generating documentation for REST resource " + 
classDoc);
+
+        // Initialize the result .html file
+        initFile(classDoc);
+
+        MethodDoc[] methodDocs = classDoc.methods();
+        if (methodDocs != null) {
+            for (MethodDoc methodDoc : methodDocs) {
+                // Check if the method is annotated with GET, POST
+                if (m_classAnalyzer.getHTTPMethod(methodDoc) != null) {
+                    handle(classDoc, methodDoc);
+                }
+            }
+        }
+    }
+
+    private static void initFile(ClassDoc classDoc) throws IOException {
+        m_file = new File("html" + File.separator + classDoc + "-api.html");
+        if (m_file.exists()) {
+            m_file.delete();
+        }
+        m_file.createNewFile();
+        Collection<String> lines = new ArrayList<String>();
+        lines.add("<html>");
+        lines.add("<body>");
+    }
+
+    private static void handle(ClassDoc classDoc, MethodDoc methodDoc) throws 
IOException {
+        System.out.println("> Generating documentation for HTTP method " + 
methodDoc);
+
+        Collection<String> lines = new ArrayList<String>();
+        lines.add("<br/><table border='1'>");
+        lines.add(getRow("URI", m_classAnalyzer.getPath(classDoc, methodDoc)));
+        lines.add(getRow("Method", m_classAnalyzer.getHTTPMethod(methodDoc)));
+        lines.add(getRow("Description", 
m_classAnalyzer.getDescription(methodDoc)));
+        lines.add(getRow("Path parameters", 
toUl(m_classAnalyzer.getPathParameters(methodDoc))));
+        lines.add(getRow("Query parameters", 
toUl(m_classAnalyzer.getQueryParameters(methodDoc))));
+        lines.add(getRow("Body parameters", 
toUl(m_classAnalyzer.getFormParameters(methodDoc))));
+        lines.add(getRow("Response", m_classAnalyzer.getReturn(methodDoc)));
+        lines.add("</table>");
+        FileUtils.writeLines(m_file, lines, EOL, true);
+    }
+
+    private static String getRow(String key, String value) {
+        return "<tr><th align='left' valign='top'>" + key + "</th><td 
align='left' valign='top'>" + value
+            + "</td></tr>";
+    }
+    
+    private static String toUl(List<String> values) {
+        if (values != null && values.size() > 0) {
+            String ul = "<ul>";
+            for (String value : values) {
+                ul += "<li>" + value + "</li>";
+            }
+            ul += "</ul>";
+            return ul;
+        }
+        return "-";
+    }
+}
\ No newline at end of file
_______________________________________________
Amdatu-commits mailing list
[email protected]
http://lists.amdatu.org/mailman/listinfo/amdatu-commits

Reply via email to