]> source.dussan.org Git - archiva.git/commitdiff
[MRM-1683] Automatic generation of REST Api documentation.
authorOlivier Lamy <olamy@apache.org>
Fri, 5 Oct 2012 13:42:38 +0000 (13:42 +0000)
committerOlivier Lamy <olamy@apache.org>
Fri, 5 Oct 2012 13:42:38 +0000 (13:42 +0000)
display doc in the webapp !

git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@1394516 13f79535-47bb-0310-9956-ffa450edef68

12 files changed:
archiva-modules/archiva-web/archiva-rest/archiva-rest-api/pom.xml
archiva-modules/archiva-web/archiva-rest/archiva-rest-services/pom.xml
archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/docs/RestDocsServlet.java [new file with mode: 0644]
archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/WEB-INF/web.xml
archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/css/archiva.css
archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/index.html
archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/archiva.js
archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/docs.js [new file with mode: 0644]
archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/main-tmpl.js
archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/main.js
archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/templates/archiva/docs.html [new file with mode: 0644]
archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/templates/archiva/menu.html

index 199485f35014e42ef8fbd0634bb2a9ea035cc480..28802fdbc2540eb2d873bbbc433ecae291b30c40 100644 (file)
          </execution>
        </executions>
        <configuration>
-         <docsDir>${project.build.outputDirectory}/docs</docsDir>
+         <docsDir>${project.build.outputDirectory}/rest-docs-archiva-rest-api</docsDir>
          <configFile>src/enunciate/enunciate.xml</configFile>
          <compileDebug>${enunciate.debug}</compileDebug>
        </configuration>
index 0ceebf065cc81eb365a8f1072e915da0db048176..813e1ffecef5c9ac8b01c50bc4dd4e52a72ae710 100644 (file)
       <artifactId>archiva-maven2-model</artifactId>
     </dependency>
 
+    <dependency>
+      <groupId>org.jsoup</groupId>
+      <artifactId>jsoup</artifactId>
+      <version>1.7.1</version>
+    </dependency>
+
     <dependency>
       <groupId>org.apache.archiva.redback</groupId>
       <artifactId>redback-authorization-api</artifactId>
diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/docs/RestDocsServlet.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/docs/RestDocsServlet.java
new file mode 100644 (file)
index 0000000..993adbe
--- /dev/null
@@ -0,0 +1,91 @@
+package org.apache.archiva.rest.docs;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.commons.lang.StringUtils;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Iterator;
+
+/**
+ * @author Olivier Lamy
+ * @since 1.4-M4
+ */
+public class RestDocsServlet
+    extends HttpServlet
+{
+    private Logger logger = LoggerFactory.getLogger( getClass() );
+
+    @Override
+    protected void doGet( HttpServletRequest req, HttpServletResponse resp )
+        throws ServletException, IOException
+    {
+
+        logger.debug( "docs request to path: {}", req.getPathInfo() );
+
+        String path = StringUtils.removeStart( req.getPathInfo(), "/" );
+        InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream( path );
+
+        String startPath = StringUtils.substringBefore( path, "/" );
+
+        // replace all links !!
+        Document document = Jsoup.parse( is, "UTF-8", "" );
+
+        Element body = document.body().child( 0 );
+
+        Elements links = body.select( "a[href]" );
+
+        for ( Iterator<Element> elementIterator = links.iterator(); elementIterator.hasNext(); )
+        {
+            Element link = elementIterator.next();
+            //link.attr( "onclick", "loadRestDocs('" + startPath + "\',\'"+ "rest-docs/" + startPath + "/" + link.attr( "href" ) + "\');" );
+            link.attr( "href", "#" + startPath + "/" + link.attr( "href" ) );
+
+        }
+
+        Elements codes = body.select( "code" );
+
+        for ( Iterator<Element> elementIterator = codes.iterator(); elementIterator.hasNext(); )
+        {
+            Element code = elementIterator.next();
+            code.attr( "class", code.attr( "class" ) + " nice-code" );
+        }
+
+        //res.appendChild( body.child( 1 ) );
+
+        Document res = new Document( "" );
+        res.appendChild( body.select( "div[id=main]" ).first() );
+
+        resp.getOutputStream().write( res.outerHtml().getBytes() );
+
+        //IOUtils.copy( is, resp.getOutputStream() );
+        //super.doGet( req, resp );
+    }
+}
index bb30d5117460d02a1c662b2fbea3f29f67cfa891..7f5c8acb047629d0e80cc01fa2a9d8c7e688ab0e 100644 (file)
     <load-on-startup>1</load-on-startup>
   </servlet>
 
+  <servlet>
+    <servlet-name>RestDocumentation</servlet-name>
+    <servlet-class>org.apache.archiva.rest.docs.RestDocsServlet</servlet-class>
+    <load-on-startup>3</load-on-startup>
+  </servlet>
 
 
   <servlet>
     <servlet-name>RssFeedServlet</servlet-name>
     <url-pattern>/feeds/*</url-pattern>
   </servlet-mapping>
+  
+  <servlet-mapping>
+    <servlet-name>RestDocumentation</servlet-name>
+    <url-pattern>/rest-docs/*</url-pattern>
+  </servlet-mapping>
 
   <servlet-mapping>
     <servlet-name>RepositoryServlet</servlet-name>
index c95a19e63a057d510bd985e40c6fcf2aa1e3aacb..859c7d80cf280f8608730e6e92df9f7dbb537ce9 100644 (file)
@@ -160,4 +160,19 @@ footer {
 
 .cursor-hand:hover {
     cursor: pointer;
+}
+
+
+code {
+    background: none repeat scroll 0 0 #EEEEEE;
+    border: 1px solid #DDDDDD;
+    color: #555555;
+    display: block;
+    font: 1.1em "Lucida Sans Unicode",serif;
+    margin-bottom: 12px;
+    max-height: 300px;
+    overflow: auto;
+    padding: 8px 10px;
+    white-space: pre;
+    vertical-align: baseline;
 }
\ No newline at end of file
index 0b8e2a8986944a7d40a5dbc1ec3b4645b07ff4bd..26ba918f679c58a271d4285cb96db2f337ab6ddc 100644 (file)
@@ -21,7 +21,7 @@
 
 <html>
 <head>
-  <link rel="stylesheet" href="css/prettify.css"/>
+
   <link rel="stylesheet" href="css/jquery.fileupload-ui.css"/>
   <link rel="stylesheet" href="css/jqueryFileTree.css"/>
   <link rel="stylesheet" href="css/chosen-0.9.8.css"/>
@@ -29,7 +29,7 @@
   <link rel="stylesheet" href="css/bootstrap.2.1.1.css">
   <link rel="stylesheet" href="css/archiva.css">
   <link rel="shortcut icon" href="favicon.ico"/>
-
+    <link rel="stylesheet" href="css/prettify.css"/>
 
   <script type="text/javascript" src="js/jquery-1.8.1.min.js"></script>
   <script type="text/javascript" src="js/jquery-ui-1.8.23.custom.min.js"></script>
index d6ab5f443e5b72af61717f34ffce384f76936abe..4b6be7144e7ec1d53e13cb3cb94f7963cdf7d295 100644 (file)
@@ -94,6 +94,7 @@ $.ajax({
                     "archiva.artifacts-management": "archiva/artifacts-management",
                     "archiva.search": "archiva/search",
                     "archiva.proxy-connectors-rules": "archiva/proxy-connectors-rules",
+                    "archiva.docs": "archiva/docs",
                     "archiva.main": "archiva/main"
                 }
             });
diff --git a/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/docs.js b/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/docs.js
new file mode 100644 (file)
index 0000000..6c05603
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define("archiva.docs",["jquery","i18n","jquery.tmpl","bootstrap"], function() {
+
+  displayRestDocs=function(){
+    $.log("displayRestDocs");
+    screenChange();
+    $("#main-content" ).html($("#rest_docs").tmpl());
+  }
+
+  goToArchivaRestDoc=function(target){
+    $("#main-content" ).html(mediumSpinnerImg());
+    $.ajax({
+      url:"rest-docs/rest-docs-archiva-rest-api/"+target,
+      type:"get",
+      dataType: "html",
+      success: function(data){
+        $("#main-content" ).html($("#rest_docs").tmpl());
+        $("#main-content" ).find("#rest_docs_content" ).html(data);
+        prettyPrint();
+      }
+    });
+  }
+
+  displayArchivaRestDocs=function(){
+    $.log("displayArchivaRestDocs");
+    $("#main-content" ).html(mediumSpinnerImg());
+    $.ajax({
+      url:"rest-docs/rest-docs-archiva-rest-api/index.html",
+      type:"get",
+      dataType: "html",
+      success: function(data){
+        $("#main-content" ).html($("#rest_docs").tmpl());
+        $("#main-content" ).find("#rest_docs_content" ).html(data);
+      }
+    });
+  }
+
+  loadRestDocs=function(docType, fullPath){
+    $.log("loadRestDocs:"+docType+","+fullPath);
+    //if (docType=='rest-docs-archiva-rest-api'){
+      $.ajax({
+        url:fullPath,
+        type:"get",
+        dataType: "html",
+        success: function(data){
+          $("#main-content" ).find("#rest_docs_content" ).html(data);
+          prettyPrint();
+        }
+      });
+    //}
+  }
+
+  displayUsersDocs=function(){
+    $.log("displayUsersDocs");
+  }
+
+});
\ No newline at end of file
index 46611cab8251c96578da7e27c8ec1324ec67fc27..1ca725c7cdae562da03b30e36099ebe4642ea795 100644 (file)
@@ -21,15 +21,17 @@ require(['jquery',"jquery.tmpl",'i18n',"utils","text!templates/archiva/menu.html
           "text!templates/archiva/modal.html",
           "text!templates/archiva/repositories.html",
           "text!templates/archiva/search.html",
-          "text!templates/archiva/general-admin.html"],
+          "text!templates/archiva/general-admin.html",
+          "text!templates/archiva/docs.html"],
   function(jquery,jqueryTmpl,i18n,utils,menu,generics,modal,repositories,
-           search,general_admin) {
+           search,general_admin,docs) {
     loadArchivaTemplate=function(){
       var htmlFragment=$("#html-fragments");
       // template loading
       htmlFragment.append(menu);
       htmlFragment.append(generics);
       $.tmpl( modal ).appendTo(htmlFragment);
+      $.tmpl( docs ).appendTo(htmlFragment);
       htmlFragment.append(repositories);
       htmlFragment.append(search);
       htmlFragment.append(general_admin);
index e17616642571aaac12a991cfeab9b70d5957e70e..885e04613b57a7c9f7201324d1ff9b4e645e5693 100644 (file)
@@ -20,7 +20,7 @@ define("archiva.main",["jquery","jquery.ui","sammy","jquery.tmpl",'i18n',"jquery
          "jquery.validate","jquery.json","knockout","redback.templates","archiva.templates",
           "redback.roles","redback","archiva.general-admin","archiva.repositories",
           "archiva.network-proxies","archiva.proxy-connectors","archiva.repository-groups","archiva.artifacts-management",
-          "archiva.proxy-connectors-rules"],
+          "archiva.proxy-connectors-rules","archiva.docs"],
 function(jquery,ui,sammy,tmpl) {
 
   /**
@@ -195,6 +195,13 @@ function(jquery,ui,sammy,tmpl) {
               {  text : $.i18n.prop('menu.users.manage')    , id: "menu-users-list-a", href: "#users" , redback: "{permissions: ['archiva-manage-users']}", func: function(){displayUsersGrid()}},
               {  text : $.i18n.prop('menu.users.roles')     , id: "menu-roles-list-a", href: "#roles" , redback: "{permissions: ['archiva-manage-users']}", func: function(){displayRolesGrid()}}
       ];
+
+      this.docsMenuItems = [
+              {  text : $.i18n.prop('menu.docs') , id: null},
+              {  text : $.i18n.prop('menu.docs.rest')    , id: "menu-docs-rest-list-a", href: "#docs-rest", func: function(){displayRestDocs()}},
+              {  text : $.i18n.prop('menu.docs.users')   , id: "menu-docs-users-list-a", href: "#docs-users" , func: function(){displayUsersDocs()}}
+      ];
+
       this.activeMenuId = ko.observable();
           
       window.sammyArchivaApplication = Sammy(function () {
@@ -616,7 +623,7 @@ function(jquery,ui,sammy,tmpl) {
           var folder = this.params.folder;
           self.activeMenuId(folder);
           var baseItems = self.artifactMenuItems?self.artifactMenuItems:[];
-          ko.utils.arrayFirst(baseItems.concat(self.usersMenuItems, self.administrationMenuItems), function(p) {
+          ko.utils.arrayFirst(baseItems.concat(self.usersMenuItems, self.administrationMenuItems,self.docsMenuItems), function(p) {
             if ( p.href == "#"+self.activeMenuId()) {
               screenChange();
               p.func();
@@ -624,6 +631,12 @@ function(jquery,ui,sammy,tmpl) {
           });
         });
 
+        this.get("#rest-docs-archiva-rest-api/:target",function(){
+          var target=this.params.target;
+          $.log("archiva-rest-docs, target:"+target);
+          goToArchivaRestDoc(target);
+        });
+
       });
   };
 
diff --git a/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/templates/archiva/docs.html b/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/templates/archiva/docs.html
new file mode 100644 (file)
index 0000000..c1e1a9f
--- /dev/null
@@ -0,0 +1,37 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~   http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+-->
+
+<script id="rest_docs" type="text/html">
+    <div>
+      <div class="page-header">
+        <div><b>${$.i18n.prop('docs.rest.header')}</b></div>
+      </div>
+      <div id="docs_rest_choice">
+        <ul>
+          <li><a onclick="displayArchivaRestDocs();">Archiva Rest Api Docs</a></li>
+        </ul>
+      </div>
+    </div>
+    <div id="rest_docs_content">
+    </div>
+</script>
+
+<script id="users_docs" type="text/html">
+         rest docs
+</script>
\ No newline at end of file
index 35e44a8909ab0c5eb087a0259a12f2599debd3e3..f1ab8fd68565a7bde928eb523295acb765c3e314 100644 (file)
       <!-- /ko -->
     </ul>
 
+    <ul class="nav nav-list" data-bind="foreach: docsMenuItems">
+      <!-- ko ifnot: id -->
+      <li class="nav-header archiva-nav-header" data-bind="text: text"></li>
+      <!-- /ko -->
+      <!-- ko if: id -->
+      <li data-bind='redbackP: $data.redback, css: { active: $data.href == "#"+$root.activeMenuId() }'>
+        <a data-bind="text: text, attr: { id: id, href: href}"></a>
+      </li>
+      <!-- /ko -->
+    </ul>
+
   </div>
 </script>