usergrid-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From snoopd...@apache.org
Subject [1/4] incubator-usergrid git commit: Add support for API docs generation to HTML format.
Date Tue, 04 Aug 2015 12:27:42 GMT
Repository: incubator-usergrid
Updated Branches:
  refs/heads/ug2-doc-update acae95913 -> 146a46cc1


http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/146a46cc/docs/src/main/groovy/ApiDocGenerator.groovy
----------------------------------------------------------------------
diff --git a/docs/src/main/groovy/ApiDocGenerator.groovy b/docs/src/main/groovy/ApiDocGenerator.groovy
deleted file mode 100644
index 810ca53..0000000
--- a/docs/src/main/groovy/ApiDocGenerator.groovy
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Generates API docs from Swagger.
- */
-
-// Depdency management with Grape:
-//    http://docs.groovy-lang.org/latest/html/documentation/grape.html
-
-import io.swagger.models.parameters.RefParameter
-@Grab(group = 'io.swagger', module = 'swagger-parser', version = '1.0.8')
-@Grab(group = 'io.swagger', module = 'swagger-compat-spec-parser', version = '1.0.8')
-@Grab(group = 'com.github.spullara.mustache.java', module = 'compiler', version = '0.8.18-SNAPSHOT')
-
-import io.swagger.parser.*;
-import io.swagger.models.*;
-import com.github.mustachejava.*;
-
-
-public class ApiDocGenerator {
-    
-    def parser = new SwaggerParser();
-    def swagger = parser.read("src/main/resources/usergrid-swagger.yaml");
-   
-    // Mustache reference: http://mustache.github.io/mustache.5.html
-    // mustache.java info: https://github.com/spullara/mustache.java
-    def writer = new OutputStreamWriter(new FileOutputStream("rest-endpoints/api-docs.md"));
-    def mf = new DefaultMustacheFactory();
-
-    def mustacheBase = "src/main/resources";
-    def operationTemplate = mf.compile(new FileReader("${mustacheBase}/operation.mustache"),
"operation");
-    def modelTemplate = mf.compile(new FileReader("${mustacheBase}/model.mustache"), "operation");
-    
-
-    public static void main( String[] args ) {
-        def adg = new ApiDocGenerator();
-        adg.generate();
-    }
-    
-    def generate() {
-
-        // organize methods by tag
-        def tagsToUrlOps = [:]
-        
-        swagger.getPaths().each { pathEntry ->
-            def url = pathEntry.key;
-            def path = pathEntry.value;
-           
-            def tag; // assume each opeation has only one tag
-            def method;
-            def operation;
-            
-            if (path.get != null) {
-                tag = path.get.tags[0];
-                method = "GET";
-                operation = path.get;
-            }
-            if (path.post != null) {
-                tag = path.post.tags[0];
-                method = "POST";
-                operation = path.post;
-            }
-            if (path.delete != null) {
-                tag = path.delete.tags[0];
-                method = "DELETE";
-                operation = path.delete;
-            }
-            if (path.put != null) {
-                tag = path.put.tags[0];
-                method = "PUT";
-                operation = path.put;
-            }
-
-            def urlOps = tagsToUrlOps[tag];
-            if ( urlOps == null ) {
-                urlOps = [];
-                tagsToUrlOps[tag] = urlOps;
-            }
-            def urlOp = [:];
-            urlOp.url = url;
-            urlOp.method = method;
-            urlOp.operation = operation;
-            urlOps.add(urlOp); 
-        }
-
-        writer.println "\n# Methods";
-        
-        tagsToUrlOps.each { entry -> 
-            def tag = entry.key;
-            def urlOps = entry.value;
-//            writer.println "\n<div class='hr'/>";
-            writer.println "\n## ${tag} Methods";
-            urlOps.each { urlOp ->
-                formatOperation( urlOp );
-            };
-        };
-
-        writer.println "\n# Models";
-        
-        swagger.getDefinitions().each { definitionEntry -> 
-            def name = definitionEntry.key;
-            def model = definitionEntry.value;
-            formatModel( name, model );
-        };
-    }
-
-    def formatOperation( urlOp ) {
-
-        def url = urlOp.url;
-        def method = urlOp.method;
-        def op = urlOp.operation;
-        
-        // put responses in array form, mustache doesn't play nice with associative arrays
-        def responses = [];
-        op.getResponses().each { responseEntry -> 
-            def response = [:];
-            response.status = responseEntry.key;
-            response.description = responseEntry.value.description;
-            if ( responseEntry.value.schema != null) {
-                response.schema = responseEntry.value.schema.ref;
-                response.schemaAnchor = responseEntry.value.schema.ref.toLowerCase();
-            }
-            responses.add(response);
-        }
-
-        def params = [];
-        op.getParameters().each { parameter -> 
-            def param = [:];
-            param.name = parameter.name;
-            param.required = parameter.required;
-            param.description = parameter.description;
-            param.in = parameter.in;
-            if (parameter.in == "body" && parameter.schema != null) {
-                param.schemaRef = parameter.schema.ref;
-                param.schemaAnchor = parameter.schema.ref.toLowerCase();
-            } else if (parameter.in == "path") {
-                param.type = parameter.type;
-            }
-            params.add(param);
-        }
-        
-        def scope = [:];
-        scope.url = url;
-        scope.method = method;
-        scope.description = op.getDescription();
-        scope.summary = op.getSummary();
-        scope.tags = op.getTags();
-        scope.responses = responses;
-        scope.parameters = params;
-       
-        operationTemplate.execute(writer, scope);
-        writer.flush();
-    }
-    
-    def formatModel(String name, Model model) {
-
-        // put properties in array form, mustache doesn't play nice with associative arrays
-        def props = [];
-        model.getProperties().each { property -> 
-            def prop = [:];
-            prop.name = property.key;
-            prop.type = property.value.type;
-            prop.title = property.value.title;
-            prop.description = property.value.description;
-            prop.access = property.value.access;
-            prop.readOnly = property.value.readOnly;
-            prop.required = property.value.required;
-            prop.position = property.value.position;
-            props.add(prop);   
-        };
-        def scope = [:];
-        scope.name = name;
-        scope.properties = props;
-        modelTemplate.execute(writer, scope);
-        writer.flush(); 
-    }
-}
-

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/146a46cc/docs/src/main/groovy/usergrid/ApiDocGenerator.groovy
----------------------------------------------------------------------
diff --git a/docs/src/main/groovy/usergrid/ApiDocGenerator.groovy b/docs/src/main/groovy/usergrid/ApiDocGenerator.groovy
new file mode 100644
index 0000000..ccc0b7b
--- /dev/null
+++ b/docs/src/main/groovy/usergrid/ApiDocGenerator.groovy
@@ -0,0 +1,278 @@
+/*
+ * Generates Markdown representation of 
+ */
+
+// Depdency management with Grape:
+//    http://docs.groovy-lang.org/latest/html/documentation/grape.html
+
+package usergrid;
+
+@Grab(group = 'io.swagger', module = 'swagger-parser', version = '1.0.8')
+@Grab(group = 'io.swagger', module = 'swagger-compat-spec-parser', version = '1.0.8')
+@Grab(group = 'com.github.spullara.mustache.java', module = 'compiler', version = '0.8.18-SNAPSHOT')
+
+import io.swagger.parser.*;
+import io.swagger.models.*;
+import com.github.mustachejava.*
+import org.apache.commons.lang3.RandomStringUtils;
+
+
+public class ApiDocGenerator {
+    
+    def parser = new SwaggerParser();
+    def swagger = parser.read("src/main/resources/usergrid-swagger.yaml");
+   
+    // Mustache reference: http://mustache.github.io/mustache.5.html
+    // mustache.java info: https://github.com/spullara/mustache.java
+    def writer;
+    def mf = new DefaultMustacheFactory();
+
+    def mustacheBase = "src/main/resources";
+    
+    def operationTemplate;
+    def modelTemplate;
+    def fileStartTemplate;
+    def fileEndTemplate;
+    
+    def allTags = [];
+    def allModels = [];
+
+
+    public ApiDocGenerator() {
+        writer = new OutputStreamWriter(new FileOutputStream("rest-endpoints/api-docs.md"));
+        operationTemplate = mf.compile(
+                new FileReader("${mustacheBase}/operation.mustache"), "operation");
+        modelTemplate = mf.compile(
+                new FileReader("${mustacheBase}/model.mustache"), "model");
+    }
+    
+    public static void main( String[] args ) {
+        
+        def htmlgen = new HtmlApiDocGenerator();
+        htmlgen.generate();
+        
+        def mdgen = new ApiDocGenerator();
+        mdgen.generate();
+    }
+    
+    def generate() {
+       
+        // build up scope and generate via Mustache template
+        
+        // organize methods by tag
+        def tagsToUrlOps = new TreeMap();
+        
+        swagger.getPaths().each { pathEntry ->
+            def url = pathEntry.key;
+            def path = pathEntry.value;
+           
+            if (path.get != null) {
+                addOperation(tagsToUrlOps, "GET", url, path.get);
+            }
+            if (path.post != null) {
+                addOperation(tagsToUrlOps, "POST", url, path.post);
+            }
+            if (path.put != null) {
+                addOperation(tagsToUrlOps, "PUT", url, path.put);
+            }
+            if (path.delete != null) {
+                addOperation(tagsToUrlOps, "DELETE", url, path.delete);
+            }
+        };
+
+        tagsToUrlOps.each { entry -> allTags.add(entry.key) };
+
+        def definitions = new TreeMap();
+        swagger.getDefinitions().each { entry ->
+            definitions.put( entry.key, entry.value );
+        };
+        definitions.each { entry -> allModels.add(entry.key); };
+       
+        // generate
+        
+        generateFileStart();
+        generateMethodsSectionTitle();
+        tagsToUrlOps.each { entry -> 
+            def tag = entry.key;
+            def urlOps = entry.value;
+            generateMethodsTitle(tag);
+            urlOps.each { urlOp -> formatOperation( urlOp ); };
+        };
+        
+        generateModelsTitle();
+        definitions.each { entry ->
+            def name = entry.key;
+            def model = entry.value;
+            formatModel( name, model );
+        };
+        generateFileEnd();
+    }
+    
+    def addOperation( Map tagsToUrlOps, String method, String url, Operation operation )
{
+       
+        // assume each operation has one tag
+        def tag = operation.tags[0];
+        
+        def urlOps = tagsToUrlOps[tag];
+        if ( urlOps == null ) {
+            urlOps = [];
+            tagsToUrlOps[tag] = urlOps;
+        }
+
+        def urlOp = new HashMap();
+        urlOp.url = url;
+        urlOp.method = method;
+        urlOp.operation = operation;
+        urlOps.add(urlOp);
+    }
+
+    def formatOperation( urlOp ) {
+        
+        // build up a scope and then call a mustache template
+        // makes some assumptions based on the Usergrid Swagger file
+
+        def url = urlOp.url;
+        def method = urlOp.method;
+        def op = urlOp.operation;
+        
+        // put responses in array form, mustache doesn't play nice with associative arrays
+        def responses = [];
+        op.getResponses().each { responseEntry -> 
+            def response = [:];
+            response.status = responseEntry.key;
+            response.description = responseEntry.value.description;
+            
+            // if parameter has a schema, assume that it is a reference
+            if ( responseEntry.value.schema != null) {
+                response.schema = responseEntry.value.schema.ref;
+                response.schemaAnchor = responseEntry.value.schema.ref.toLowerCase();
+            }
+            responses.add(response);
+        }
+
+        def params = [];
+        op.getParameters().each { parameter -> 
+            def param = [:];
+            param.name = parameter.name;
+            param.required = parameter.required;
+            param.description = parameter.description;
+            param.in = parameter.in;
+            
+            // assume that body parameters have a schema that is a reference
+            if (parameter.in == "body" && parameter.schema != null) {
+                param.schemaRef = parameter.schema.ref;
+                param.schemaAnchor = parameter.schema.ref.toLowerCase();
+            } else if (parameter.in == "path") {
+                param.type = parameter.type;
+            }
+            params.add(param);
+        }
+        
+        def scope = [:];
+        scope.url = url;
+        scope.method = method;
+        scope.description = op.getDescription();
+        scope.summary = op.getSummary();
+        scope.tags = op.getTags();
+        scope.responses = responses;
+        scope.parameters = params;
+        scope.opid = RandomStringUtils.randomAlphanumeric(10);
+       
+        operationTemplate.execute(writer, scope);
+        writer.flush();
+    }
+    
+    def formatModel(String name, Model model) {
+
+        // put properties in array form, mustache doesn't play nice with associative arrays
+        def props = [];
+        model.getProperties().each { property -> 
+            def prop = [:];
+            prop.name = property.key;
+            prop.type = property.value.type;
+            prop.title = property.value.title;
+            prop.description = property.value.description;
+            prop.access = property.value.access;
+            prop.readOnly = property.value.readOnly;
+            prop.required = property.value.required;
+            prop.position = property.value.position;
+            props.add(prop);   
+        };
+        def scope = [:];
+        scope.name = name;
+        scope.properties = props;
+        scope.modelid = RandomStringUtils.randomAlphanumeric(10);
+        modelTemplate.execute(writer, scope);
+        writer.flush(); 
+    }
+    
+    def generateFileStart() {
+        // no op
+    }
+    
+    def generateMethodsSectionTitle() {
+        writer.println "## Methods";
+    }
+    
+    def generateMethodsTitle(String tag) {
+        writer.println "## ${tag} Methods>";
+    }
+    
+    def generateModelsTitle() {
+        writer.println "\n## Models";
+        writer.println "Properties for Usergrid default entities.";
+    }
+    
+    def generateFileEnd() {
+        // no op
+    }
+}
+
+
+class HtmlApiDocGenerator extends ApiDocGenerator {
+    
+    public HtmlApiDocGenerator() {
+        writer = new OutputStreamWriter(
+                new FileOutputStream("rest-endpoints/api-docs.html"));
+        operationTemplate = mf.compile(
+                new FileReader("${mustacheBase}/operation-html.mustache"), "operation");
+        modelTemplate = mf.compile(
+                new FileReader("${mustacheBase}/model-html.mustache"), "operation");
+        fileStartTemplate = mf.compile(
+                new FileReader("${mustacheBase}/file-start-html.mustache"), "file-start");
+        fileEndTemplate = mf.compile(
+                new FileReader("${mustacheBase}/file-end-html.mustache"), "file-end");
+    }
+
+    def generateFileStart() {
+        def scope = [:];
+        scope.title = "Usergrid API Reference";
+        fileStartTemplate.execute(writer, scope);
+        writer.flush();
+    }
+
+    def generateMethodsSectionTitle() {
+        writer.println "<h2>Methods</h2>" +
+                "<p>API methods are organized by the tags.</p>";
+        writer.println "<p>Following the methods is a listing of all " +
+                "<a href='#models'>Default Entity Models.</p>"
+    }
+
+    def generateMethodsTitle(String tag) {
+        writer.println "<a name='${tag}-method'></a>";
+        writer.println "<h2>${tag} Methods</h2>";
+    }
+
+    def generateModelsTitle() {
+        writer.println "<a name='models'></a>";
+        writer.println "<h2>Default Entity Models</h2>" +
+                "<p>This section lists the properties for the following Usergrid Default
Entities:</p>";
+    }
+
+    def generateFileEnd() {
+        def scope = [:];
+        fileEndTemplate.execute(writer, scope);
+        writer.flush();
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/146a46cc/docs/src/main/resources/file-end-html.mustache
----------------------------------------------------------------------
diff --git a/docs/src/main/resources/file-end-html.mustache b/docs/src/main/resources/file-end-html.mustache
new file mode 100644
index 0000000..28d75b5
--- /dev/null
+++ b/docs/src/main/resources/file-end-html.mustache
@@ -0,0 +1,13 @@
+
+    </div>
+    <div class="col-md-1"></div>
+</div>
+
+<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
+<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
+    
+<!-- Latest compiled and minified JavaScript -->
+<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
+
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/146a46cc/docs/src/main/resources/file-start-html.mustache
----------------------------------------------------------------------
diff --git a/docs/src/main/resources/file-start-html.mustache b/docs/src/main/resources/file-start-html.mustache
new file mode 100644
index 0000000..642bf42
--- /dev/null
+++ b/docs/src/main/resources/file-start-html.mustache
@@ -0,0 +1,21 @@
+<html>
+<head>
+    <title>{{title}}</title>
+    
+    <!-- Latest compiled and minified CSS -->
+    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
+    
+    <!-- Optional theme -->
+    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
+
+    <link rel="stylesheet" href="api-docs.css">
+    
+</head>
+<body>
+
+<div class="row">
+    <div class="col-md-1"></div>
+    <div class="col-md-10">
+    
+    <h1>{{title}}</h1>
+    <p>Generated from Swagger.</p>

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/146a46cc/docs/src/main/resources/model-html.mustache
----------------------------------------------------------------------
diff --git a/docs/src/main/resources/model-html.mustache b/docs/src/main/resources/model-html.mustache
new file mode 100644
index 0000000..8672641
--- /dev/null
+++ b/docs/src/main/resources/model-html.mustache
@@ -0,0 +1,38 @@
+
+<div>
+    <a name="{{name}}"/>
+</div>
+
+<div class="panel panel-default">
+    
+    <div class="panel-heading">
+        <h2 class="panel-title model-heading">{{name}}
+            <a data-toggle="collapse" data-target="#collapse-{{modelid}}"
+               href="#collapse-{{modelid}}" class="collapsed collapse-button"> </a>
+        </h2>
+    </div>
+    
+    <div id="collapse-{{modelid}}" class="panel-body collapse">
+        
+        <h3>Properties</h3>
+
+        <table width="80%" class="table table-striped">
+            <tr>
+                <th>Name</th>
+                <th>Type</th>
+                <th>Description</th>
+                <th>Required</th>
+            </tr>
+            {{#properties}}
+                <tr>
+                    <td>{{name}}</td>
+                    <td>{{type}}</td>
+                    <td>{{description}}</td>
+                    <td>{{required}}</td>
+                </tr>
+            {{/properties}}
+        </table>
+
+    </div>
+    
+</div>

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/146a46cc/docs/src/main/resources/operation-html.mustache
----------------------------------------------------------------------
diff --git a/docs/src/main/resources/operation-html.mustache b/docs/src/main/resources/operation-html.mustache
new file mode 100644
index 0000000..6e15b1f
--- /dev/null
+++ b/docs/src/main/resources/operation-html.mustache
@@ -0,0 +1,43 @@
+
+<div class="panel panel-default">
+    
+    <div class="panel-heading {{method}}">
+        <h2 class="panel-title {{method}}-heading">{{method}} {{url}} 
+            <a data-toggle="collapse" data-target="#collapse-{{opid}}"
+                href="#collapse-{{opid}}" class="collapsed collapse-button"> </a>
+        </h2>
+    </div>
+    
+    <div id="collapse-{{opid}}" class="panel-body collapse">
+
+        <p>{{description}}</p>
+
+        <h3>Parameters</h3>
+
+        <ul>
+            {{#parameters}}
+                <li>
+                    <b>{{name}}</b> ({{#type}}{{type}}{{/type}}{{#schemaRef}}
+                    <a href="#{{schemaAnchor}}">{{schemaRef}}</a>{{/schemaRef}})
<br>
+                    {{description}} (Specified in {{in}}).
+                </li>
+            {{/parameters}}
+        </ul>
+
+        <h3>Responses</h3>
+
+        <ul>
+            {{#responses}}
+                <li>
+                    <b>{{#status}}{{status}}{{/status}}{{^status}}Default{{/status}}</b>
+                    <ul>
+                        <li>Description: {{description}}</li>
+                        <li>Schema: [<a href="#{{schemaAnchor}}">{{schema}}</a>]</li>
+                    </ul>
+                </li>
+            {{/responses}}
+        </ul>     
+        
+    </div>
+    <!--<div class="panel-footer"></div>-->
+</div>

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/146a46cc/docs/src/main/resources/usergrid-swagger.yaml
----------------------------------------------------------------------
diff --git a/docs/src/main/resources/usergrid-swagger.yaml b/docs/src/main/resources/usergrid-swagger.yaml
index 6aceb32..b4af7c4 100644
--- a/docs/src/main/resources/usergrid-swagger.yaml
+++ b/docs/src/main/resources/usergrid-swagger.yaml
@@ -381,7 +381,7 @@ paths:
           schema:
             $ref: CreateApp   
       tags:
-        - Action
+        - Admin
       responses:
         "200":
           description: "An array of complete messages."

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/146a46cc/docs/user-management/tbd.md
----------------------------------------------------------------------
diff --git a/docs/user-management/tbd.md b/docs/user-management/tbd.md
index f65681d..279d128 100644
--- a/docs/user-management/tbd.md
+++ b/docs/user-management/tbd.md
@@ -1 +1 @@
-# Coming soon...
\ No newline at end of file
+# COMING SOON...
\ No newline at end of file


Mime
View raw message