Author: [email protected]
Date: Wed Mar 21 15:45:32 2012
New Revision: 2151

Log:


Added:
   
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/rest/
   
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/InvocationContext.java
   
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/OptionalParamTaglet.java
   
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/RestParameter.java
   
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/annotation/
   
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/annotation/InputTypeHint.java
   
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/annotation/OutputTypeHint.java
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/JaxbBeanHelper.java
   
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/RESTDoclet.java

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
      Wed Mar 21 15:45:32 2012
@@ -21,8 +21,13 @@
 import static javax.ws.rs.core.MediaType.TEXT_HTML;
 import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
 
+import org.amdatu.commons.restdoclet.annotation.InputTypeHint;
+import org.amdatu.commons.restdoclet.annotation.OutputTypeHint;
+
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
@@ -62,18 +67,18 @@
     // 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];
+        Map<String, String> classPath = getAnnotationValues(classDoc, 
Path.class);
+        if (classPath != null && classPath.containsKey("value")) {
+            path += "/" + classPath.get("value");
         }
         if (methodDoc != null) {
-            String[] resourcePath = getAnnotationValues(methodDoc, Path.class);
-            if (resourcePath != null && resourcePath.length == 1) {
-                if (resourcePath[0].startsWith("/")) {
-                    path += resourcePath[0];
+            Map<String, String> resourcePath = getAnnotationValues(methodDoc, 
Path.class);
+            if (resourcePath != null && resourcePath.containsKey("value")) {
+                if (resourcePath.get("value").startsWith("/")) {
+                    path += resourcePath.get("value");
                 }
                 else {
-                    path += "/" + resourcePath[0];
+                    path += "/" + resourcePath.get("value");
                 }
             }
         }
@@ -96,11 +101,11 @@
         return null;
     }
 
-    public String[] getAnnotationValues(ClassDoc classDoc, Class<?> 
annotation) {
+    public Map<String, String> getAnnotationValues(ClassDoc classDoc, Class<?> 
annotation) {
         return getAnnotationValues(classDoc.annotations(), annotation);
     }
 
-    public String[] getAnnotationValues(MethodDoc methodDoc, Class<?> 
annotation) {
+    public Map<String, String> getAnnotationValues(MethodDoc methodDoc, 
Class<?> annotation) {
         return getAnnotationValues(methodDoc.annotations(), annotation);
     }
 
@@ -111,17 +116,17 @@
 
     // Returns the consumed types
     public StringBuffer getConsumes(MethodDoc methodDoc) throws Exception {
-        String[] consumes = getAnnotationValues(methodDoc, Consumes.class);
-        if (consumes != null && consumes.length > 0) {
+        Map<String, String> consumes = getAnnotationValues(methodDoc, 
Consumes.class);
+        if (consumes != null && consumes.containsKey("value")) {
             // Build mimetypes
             StringBuffer result = new StringBuffer();
-            String[] mimeTypes = getMimeTypes(consumes[0]);
+            String[] mimeTypes = getMimeTypes(consumes.get("value"));
             result.append(getMimeTypeTable(methodDoc, mimeTypes, true));
             return result;
         }
         return null;
     }
-    
+
     private StringBuffer getMimeTypeTable(MethodDoc methodDoc, String[] 
mimeTypes, boolean input) throws Exception {
         StringBuffer result = new StringBuffer();
         result.append("<table>");
@@ -129,67 +134,75 @@
 
             result.append("<tr><td>" + mimeType + "</td><td>");
 
-            List<String> params;
+            List<String> params = new ArrayList<String>();
             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);
+                 // If the mimetype is form encoded, the parameters are 
already listed in 'Parameters'
                 } else {
-                    // First try the see tag
-                    String seeTagParam = getTypeFromSeeTag(methodDoc);
-                    if (seeTagParam != null) {
-                        params = new ArrayList<String>();
-                        params.add(seeTagParam);
+                    // First try the @OutputTypeHint and @InputTypeHint 
annotations
+                    String typeHintParam = getTypeFromTypeHint(methodDoc, 
input);
+                    if (typeHintParam != null) {
+                        params.add(typeHintParam);
                     } else {
-                        // Try to get an example from the JAXB annotated bean
-                        params = getParameters(methodDoc, null);
+                        // Now try the see tag
+                        String seeTagParam = getTypeFromSeeTag(methodDoc);
+                        if (seeTagParam != null) {
+                            params.add(seeTagParam);
+                        } else {
+                            // Finally, try to get an example from the JAXB 
annotated bean
+                            params.add(getParameters(methodDoc, 
null).get(0).getDescription());
+                        }
                     }
                 }
             }
             else {
                 Type returnType = methodDoc.returnType();
-                params = new ArrayList<String>();
+               
                 if 
(String.class.getCanonicalName().equals(returnType.qualifiedTypeName())) {
                     params.add("");
                 }
                 else if 
(Response.class.getCanonicalName().equals(returnType.qualifiedTypeName())) {
-                    // Check if there is a @see anotation that indicates the 
return type
-                    String seeTagParam = getTypeFromSeeTag(methodDoc);
-                    if (seeTagParam != null) {
-                        params.add(seeTagParam);
-                    }
-                    if (params.size() == 0) {
-                        if (mimeType.equals(TEXT_PLAIN) || 
mimeType.equals(TEXT_HTML)) {
-                            params.add("");
+                    // First try the @OutputTypeHint and @InputTypeHint 
annotations
+                    String typeHintParam = getTypeFromTypeHint(methodDoc, 
input);
+                    if (typeHintParam != null) {
+                        params.add(typeHintParam);
+                    } else {
+                        // Check if there is a @see anotation that indicates 
the return type
+                        String seeTagParam = getTypeFromSeeTag(methodDoc);
+                        if (seeTagParam != null) {
+                            params.add(seeTagParam);
                         }
-                        else {
-                            result.append(Response.class.getCanonicalName());
+                        if (params.size() == 0) {
+                            if (mimeType.equals(TEXT_PLAIN) || 
mimeType.equals(TEXT_HTML)) {
+                                params.add("");
+                            }
+                            else {
+                                
result.append(Response.class.getCanonicalName());
+                            }
                         }
                     }
                 }
             }
-            for (String param : params) {
-                if (TEXT_PLAIN.equals(mimeType)) {
-                    result.append("Some text");
-                }
-                else if (TEXT_HTML.equals(mimeType)) {
-                    result.append("Some html");
-                }
-                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, mimeType, 
getHTTPMethod(methodDoc));
-                    result.append(m_beanHelper.toXML(obj));
-                }
-                else if (APPLICATION_FORM_URLENCODED.equals(mimeType)) {
-                    List<String> formParams = getFormParameters(methodDoc);
-                    result.append("<ul>");
-                    for (String formParam : formParams) {
-                        result.append("<li>" + formParam + "</li>");
+
+            if (APPLICATION_FORM_URLENCODED.equals(mimeType)) {
+                result.append("(See Parameters)");
+            }
+            else {
+                for (String param : params) {
+                    if (TEXT_PLAIN.equals(mimeType)) {
+                        result.append("Some text");
+                    }
+                    else if (TEXT_HTML.equals(mimeType)) {
+                        result.append("Some html");
+                    }
+                    else if (APPLICATION_JSON.equals(mimeType)) {
+                        Object obj = m_beanHelper.createBean(param, new 
InvocationContext(mimeType, getHTTPMethod(methodDoc), input));
+                        result.append(m_beanHelper.toJSON(obj));
+                    }
+                    else if (APPLICATION_XML.equals(mimeType)) {
+                        Object obj = m_beanHelper.createBean(param, new 
InvocationContext(mimeType, getHTTPMethod(methodDoc), input));
+                        result.append(m_beanHelper.toXML(obj));
                     }
-                    result.append("</ul>");
                 }
             }
             result.append("</td></tr>");
@@ -197,7 +210,21 @@
         result.append("</table>");
         return result;
     }
-    
+
+    private String getTypeFromTypeHint(MethodDoc methodDoc, boolean input) {
+        Map<String, String> annotations = getAnnotationValues(methodDoc, input 
? InputTypeHint.class : OutputTypeHint.class);
+        if (annotations != null) {
+            String name = annotations.get("value").substring(0, 
annotations.get("value").indexOf(".class"));
+            if (annotations.containsKey("method")) {
+                name += "#" + annotations.get("method");
+            }
+            return name;
+        }
+
+        return null;
+    }
+
+
     private String getTypeFromSeeTag(MethodDoc methodDoc) {
         SeeTag[] seeTags = methodDoc.seeTags();
         if (seeTags != null && seeTags.length > 0) {
@@ -215,9 +242,9 @@
     }
 
     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);
+        Map<String, String> produces = getAnnotationValues(methodDoc, 
Produces.class);
+        if (produces != null && produces.containsKey("value")) {
+            return getMimeTypeTable(methodDoc, 
getMimeTypes(produces.get("value")), false);
         }
         else
             return new StringBuffer().append("-");
@@ -238,17 +265,17 @@
     }
 
     // Returns the description of all PathParam annotated parameters
-    public List<String> getPathParameters(MethodDoc methodDoc) {
+    public List<RestParameter> getPathParameters(MethodDoc methodDoc) {
         return getParameters(methodDoc, PathParam.class);
     }
 
     // Returns the description of all QueryParam annotated parameters
-    public List<String> getQueryParameters(MethodDoc methodDoc) {
+    public List<RestParameter> getQueryParameters(MethodDoc methodDoc) {
         return getParameters(methodDoc, QueryParam.class);
     }
 
     // Returns the description of all formParam annotated parameters
-    public List<String> getFormParameters(MethodDoc methodDoc) {
+    public List<RestParameter> getFormParameters(MethodDoc methodDoc) {
         return getParameters(methodDoc, FormParam.class);
     }
 
@@ -264,8 +291,8 @@
         return "-";
     }
 
-    private List<String> getParameters(MethodDoc methodDoc, Class<?> 
annotationClass) {
-        List<String> parameters = new ArrayList<String>();
+    private List<RestParameter> getParameters(MethodDoc methodDoc, Class<?> 
annotationClass) {
+        List<RestParameter> parameters = new ArrayList<RestParameter>();
         Parameter[] params = methodDoc.parameters();
         if (params != null) {
             ParamTag[] tags = methodDoc.paramTags();
@@ -277,44 +304,63 @@
                         if (annotationClass != null) {
                             if 
(type.qualifiedName().equals(annotationClass.getName())) {
                                 // This is a path parameter, find the param 
tag matching the parameter
-                                String javadoc = null;
+                                boolean required = true;
+                                String description = null;
                                 if (tags != null) {
                                     for (ParamTag tag : tags) {
                                         if 
(tag.parameterName().equals(param.name())) {
-                                            javadoc = tag.parameterComment();
+                                            description = 
tag.parameterComment();
                                         }
                                     }
                                 }
-                                String descr = param.name();
-                                if (javadoc != null) {
-                                    descr += " : " + javadoc;
+
+                                if (description == null) {
+                                    Tag optionalParam = 
OptionalParamTaglet.get(methodDoc, param.name());
+                                    if (optionalParam != null) {
+                                        description = 
OptionalParamTaglet.getParameterComment(optionalParam);
+                                        required = false;
+                                    }
                                 }
-                                parameters.add(descr);
+
+                                parameters.add(new RestParameter(param.name(), 
description, getParameterTypeDescription(annotationClass), required));
                             }
                         }
                     }
                 }
                 else if (annotationClass == null) {
                     // No annotations, this must be a JAXB annotated bean
-                    parameters.add(param.type().toString());
+                    parameters.add(new RestParameter(param.name(), 
param.type().toString(), "?", true));
                 }
             }
         }
         return parameters;
     }
 
-    private String[] getAnnotationValues(AnnotationDesc[] annotationDescs, 
Class<?> annotation) {
+    private String getParameterTypeDescription(Class<?> annotationClass) {
+        if (QueryParam.class.isAssignableFrom(annotationClass)) {
+            return "query";
+        }
+        if (FormParam.class.isAssignableFrom(annotationClass)) {
+            return "form";
+        }
+        if (PathParam.class.isAssignableFrom(annotationClass)) {
+            return "path";
+        }
+        return "unknown";
+    }
+
+    private Map<String, 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;
+                    HashMap<String, String> map = new HashMap<String, 
String>();
                     for (ElementValuePair value : 
annotationDesc.elementValues()) {
-                        vals[i] = omitQuotes(value.value().toString());
-                        i++;
+                        String val = omitQuotes(value.value().toString());
+
+                        map.put(value.element().name(), val);
                     }
-                    return vals;
+                    return map;
                 }
             }
         }

Added: 
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/InvocationContext.java
==============================================================================
--- (empty file)
+++ 
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/InvocationContext.java
  Wed Mar 21 15:45:32 2012
@@ -0,0 +1,43 @@
+package org.amdatu.commons.restdoclet;
+
+/**
+ * Represents the context of the REST invocation. For example: output of a GET 
for
+ * mimetype JSON.
+ * 
+ * @author <a href="mailto:[email protected]";>Amdatu Project 
Team</a>
+ */
+public class InvocationContext {
+    private String m_mimeType;
+    private String m_httpMethod;
+    private boolean m_input;
+
+    public InvocationContext(String mimeType, String httpMethod, boolean 
input) {
+        m_mimeType = mimeType;
+        m_httpMethod = httpMethod;
+        m_input = input;
+    }
+    
+    public String getMimeType() {
+        return m_mimeType;
+    }
+
+    public void setMimeType(String mimeType) {
+        m_mimeType = mimeType;
+    }
+
+    public String getHttpMethod() {
+        return m_httpMethod;
+    }
+
+    public void setHttpMethod(String httpMethod) {
+        m_httpMethod = httpMethod;
+    }
+
+    public boolean isInput() {
+        return m_input;
+    }
+
+    public void setInput(boolean input) {
+        m_input = input;
+    }
+}

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
     Wed Mar 21 15:45:32 2012
@@ -18,6 +18,7 @@
 import java.io.IOException;
 import java.io.StringWriter;
 import java.io.Writer;
+import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.List;
@@ -26,6 +27,8 @@
 import javax.xml.bind.Marshaller;
 import javax.xml.bind.annotation.XmlRootElement;
 
+import com.google.gson.FieldNamingPolicy;
+import com.google.gson.FieldNamingStrategy;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 
@@ -49,7 +52,7 @@
         }
     }
 
-    public Object createBean(String classMethod, String mimeType, String 
httpMethod) throws Exception {
+    public Object createBean(String classMethod, InvocationContext context) 
throws Exception {
         String className = classMethod;
         String methodName = null;
         if (classMethod.indexOf("#") != -1) {
@@ -57,38 +60,30 @@
             methodName = classMethod.substring(classMethod.indexOf("#") + 1);
         }
         Class<?> clazz = m_sourceClassLoader.loadClass(className);
-        return createBean(clazz, 1, methodName, mimeType, httpMethod);
+        return createBean(clazz, 1, methodName,context);
     }
 
-    public Object createBean(Class<?> clazz, int index, String methodName, 
String mimeType, String httpMethod)
+    public Object createBean(Class<?> clazz, int index, String methodName, 
InvocationContext context)
         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
+            // 1. Try invocation with invocation context
             try {
-                Method method = clazz.getDeclaredMethod(mName, new Class<?>[] 
{String.class, String.class});
+                Method method = clazz.getDeclaredMethod(mName, new Class<?>[] 
{InvocationContext.class});
                 if (method.getReturnType().isAssignableFrom(clazz)) {
-                    return method.invoke(null, mimeType, httpMethod);
+                    return method.invoke(null, context);
                 }
             }
             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
+            
+            // 2. Try invocation with no parameters
             Method method = clazz.getDeclaredMethod(mName, new Class<?>[0]);
             if (method.getReturnType().isAssignableFrom(clazz)) {
                 return method.invoke(null);
@@ -123,8 +118,8 @@
                         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, null, mimeType, 
httpMethod);
-                        Object val2 = createBean(listClass, 2, null, mimeType, 
httpMethod);
+                        Object val1 = createBean(listClass, 1, null, context);
+                        Object val2 = createBean(listClass, 2, null, context);
                         List values = new ArrayList();
                         values.add(val1);
                         values.add(val2);
@@ -134,7 +129,7 @@
                         // Another bean type
                         String type = paramType.getName();
                         Class listClass = m_sourceClassLoader.loadClass(type);
-                        Object val = createBean(listClass, 1, null, mimeType, 
httpMethod);
+                        Object val = createBean(listClass, 1, null, context);
                         method.invoke(obj, val);
                     }
                 }
@@ -149,7 +144,18 @@
         if (rootElement != null) {
             name = rootElement.name();
         }
-        String json = GSON.toJson(bean);
+        FieldNamingStrategy fnStrategy = new FieldNamingStrategy() {
+            public String translateName(Field f) {
+                String name = f.getName();
+                if (name.startsWith("m_")) {
+                    name = name.substring(2);
+                }
+                return name.toLowerCase();
+            }
+            
+        };
+        Gson gson = new 
GsonBuilder().disableHtmlEscaping().setPrettyPrinting().setFieldNamingStrategy(fnStrategy).create();
+        String json = gson.toJson(bean);
 
         json = "{\"" + name + "\": " + json + "}";
         json = json.replace(" ", "&nbsp;").replace("\n", "<br/>");

Added: 
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/OptionalParamTaglet.java
==============================================================================
--- (empty file)
+++ 
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/OptionalParamTaglet.java
        Wed Mar 21 15:45:32 2012
@@ -0,0 +1,54 @@
+package org.amdatu.commons.restdoclet;
+
+import java.util.Map;
+
+import com.sun.javadoc.MethodDoc;
+import com.sun.javadoc.Tag;
+import com.sun.tools.doclets.Taglet;
+import com.sun.tools.doclets.internal.toolkit.taglets.ParamTaglet;
+
+public class OptionalParamTaglet extends ParamTaglet {
+    private final static String NAME = "optparam";
+    
+    /**
+     * Construct a ParamTaglet.
+     */
+    public OptionalParamTaglet() {
+        name = NAME;
+    }
+    
+    /**
+     * Register this Taglet.
+     * @param tagletMap  the map to register this tag to.
+     */
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    public static void register(Map tagletMap) {
+        OptionalParamTaglet tag = new OptionalParamTaglet();
+        Taglet t = (Taglet) tagletMap.get(tag.getName());
+        if (t != null) {
+            tagletMap.remove(tag.getName());
+        }
+        tagletMap.put(tag.getName(), tag);
+    }
+    
+    public static String getParameterName(Tag tag) {
+        return tag.text().trim().substring(0, tag.text().trim().indexOf(" "));
+    }
+    
+    public static String getParameterComment(Tag tag) {
+        return tag.text().trim().substring(tag.text().trim().indexOf(" ") + 1);
+    }
+
+    public static Tag get(MethodDoc methodDoc, String name) {
+        Tag[] tags = methodDoc.tags(NAME);
+        if (tags != null) {
+            for (Tag tag : tags) {
+                final String paramName = 
OptionalParamTaglet.getParameterName(tag);
+                if (paramName.equals(name)) {
+                    return tag;
+                }
+            }
+        }
+        return null;
+    }
+}

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
 Wed Mar 21 15:45:32 2012
@@ -25,6 +25,7 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 
 import javax.ws.rs.Path;
 
@@ -34,6 +35,18 @@
 import com.sun.javadoc.MethodDoc;
 import com.sun.javadoc.RootDoc;
 
+/**
+ * To run the REST Doclet from Eclipse:
+ * - Open 'Debug Configurations' window
+ * - Create a new 'Java Application'
+ * - Define:
+ *  - Main class = org.amdatu.commons.restdoclet.RESTDoclet
+ *  - Program arguments = @options
+ *  - Working directory = The target/restdocs folder of the artifact for which 
you want to generate the documentation. 
+ *    For example: 
D:\Amdatu-svn\trunk\amdatu-opensocial\opensocial-gadgetmanagement\target\restdocs
+ * 
+ * @author <a href="mailto:[email protected]";>Amdatu Project 
Team</a>
+ */
 public class RESTDoclet {
     private final static String EOL = System.getProperty("line.separator");
 
@@ -71,8 +84,8 @@
         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) {
+            Map<String, String> annotations = 
m_classAnalyzer.getAnnotationValues(docClasses[i], Path.class);
+            if (annotations != null && annotations.containsKey("value")) {
                 handle(docClasses[i]);
             }
         }
@@ -207,18 +220,13 @@
         // Description
         lines.add(getRow("Description", 
m_classAnalyzer.getDescription(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)));
-        }
-
+        // Query and Path parameters
+        List<RestParameter> parameters = new ArrayList<RestParameter>();
+        parameters.addAll(m_classAnalyzer.getPathParameters(methodDoc));
+        parameters.addAll(m_classAnalyzer.getQueryParameters(methodDoc));
+        parameters.addAll(m_classAnalyzer.getFormParameters(methodDoc));
+        
+        lines.add(getRow("Parameters", RestParameter.toTable(parameters)));
 
         // Consumes
         StringBuffer consumes = m_classAnalyzer.getConsumes(methodDoc);

Added: 
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/RestParameter.java
==============================================================================
--- (empty file)
+++ 
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/RestParameter.java
      Wed Mar 21 15:45:32 2012
@@ -0,0 +1,73 @@
+package org.amdatu.commons.restdoclet;
+
+import java.util.List;
+
+public class RestParameter {
+    private String m_name;
+    private String m_description;
+    private String m_type;
+    private boolean m_required;
+
+    public RestParameter() {
+    }
+
+    public RestParameter(String name, String description, String type, boolean 
required) {
+        m_name = name;
+        m_description = description;
+        m_type = type;
+        m_required = required;
+    }
+
+    public String getName() {
+        return m_name;
+    }
+
+    public void setName(String name) {
+        m_name = name;
+    }
+
+    public String getDescription() {
+        return m_description;
+    }
+
+    public void setDescription(String description) {
+        m_description = description;
+    }
+
+    public String getType() {
+        return m_type;
+    }
+
+    public void setType(String type) {
+        m_type = type;
+    }
+
+    public boolean isRequired() {
+        return m_required;
+    }
+
+    public void setRequired(boolean required) {
+        m_required = required;
+    }
+
+    public static String toTable(List<RestParameter> params) {
+        if (params == null || params.size() == 0) {
+            return "-";
+        }
+        StringBuffer table = new StringBuffer();
+        table.append("<table>");
+        
table.append("<tr><th>Name</th><th>Description</th><th>Type</th><th>Required</th></tr>");
+        for (RestParameter param : params) {
+            table.append(param.toRow());
+        }
+        table.append("</table>");
+        return table.toString();
+    }
+    
+    public String toRow() {
+        return "<tr><td>" + getName() + "</td>" +
+            "<td>" + getDescription() + "</td>" +
+            "<td>" + getType() + "</td>" +
+            "<td>" + isRequired() + "</td></tr>";
+    }
+}

Added: 
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/annotation/InputTypeHint.java
==============================================================================
--- (empty file)
+++ 
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/annotation/InputTypeHint.java
   Wed Mar 21 15:45:32 2012
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2012 GX Software B.V.
+ *
+ * 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.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * The InputTypeHint annotation can be used to Hint the REST doclet about the 
type being consumed
+ * by the class. Usually, the input type is input parameter of the method, 
marshalled from XML or JSON
+ * by JAXB. This annotation can be added to hint the doclet about the class of 
the bean being consumed
+ * if this input argument is missing or to specify a particular method to 
invoke on the bean to retrieve
+ * an example. 
+ * 
+ * @author ivol
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface InputTypeHint {
+    /**
+     * Class of the bean being consumed by this REST method.
+     * @return Class of the bean being consumed by this REST method.
+     */
+    Class<?> value();
+    
+    /**
+     * Public static Method to invoke on the bean class to retrieve an example 
bean instance
+     * for the input type of this REST method.
+     * @return Method name to invoke on the bean class to retrieve an example 
bean instance
+     * for the input type of this REST method.
+     */
+    String method();
+}

Added: 
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/annotation/OutputTypeHint.java
==============================================================================
--- (empty file)
+++ 
sandbox/ivol/amdatu-commons/rest-doclet/src/main/java/org/amdatu/commons/restdoclet/annotation/OutputTypeHint.java
  Wed Mar 21 15:45:32 2012
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2012 GX Software B.V.
+ *
+ * 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.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * The InputTypeHint annotation can be used to Hint the REST doclet about the 
type being returned
+ * by the class. Usually, the return type is a Response object and marshalling 
the bean to XML or JSON
+ * is handles by JAXB. This annotation can be added to hint the doclet about 
the class of the bean
+ * returned. 
+ * 
+ * @author ivol
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface OutputTypeHint {
+    /**
+     * Class of the bean being returned by this REST method.
+     * @return Class of the bean being returned by this REST method.
+     */
+    Class<?> value();
+    
+    /**
+     * Public static Method to invoke on the bean class to retrieve an example 
bean instance
+     * for the return type of this REST method.
+     * @return Method name to invoke on the bean class to retrieve an example 
bean instance
+     * for the return type of this REST method.
+     */
+    String method();
+}
+
+
+
_______________________________________________
Amdatu-commits mailing list
[email protected]
http://lists.amdatu.org/mailman/listinfo/amdatu-commits

Reply via email to