From 258f098ae67e514558a21b67d965bac5b579defd Mon Sep 17 00:00:00 2001 From: Olivier Lamy Date: Fri, 5 Oct 2012 13:42:38 +0000 Subject: [PATCH] [MRM-1683] Automatic generation of REST Api documentation. display doc in the webapp ! git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@1394516 13f79535-47bb-0310-9956-ffa450edef68 --- .../archiva-rest/archiva-rest-api/pom.xml | 2 +- .../archiva-rest-services/pom.xml | 6 ++ .../archiva/rest/docs/RestDocsServlet.java | 91 +++++++++++++++++++ .../src/main/webapp/WEB-INF/web.xml | 10 ++ .../src/main/webapp/css/archiva.css | 15 +++ .../src/main/webapp/index.html | 4 +- .../src/main/webapp/js/archiva/archiva.js | 1 + .../src/main/webapp/js/archiva/docs.js | 74 +++++++++++++++ .../src/main/webapp/js/archiva/main-tmpl.js | 6 +- .../src/main/webapp/js/archiva/main.js | 17 +++- .../webapp/js/templates/archiva/docs.html | 37 ++++++++ .../webapp/js/templates/archiva/menu.html | 11 +++ 12 files changed, 267 insertions(+), 7 deletions(-) create mode 100644 archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/docs/RestDocsServlet.java create mode 100644 archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/docs.js create mode 100644 archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/templates/archiva/docs.html diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/pom.xml b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/pom.xml index 199485f35..28802fdbc 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/pom.xml +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/pom.xml @@ -171,7 +171,7 @@ - ${project.build.outputDirectory}/docs + ${project.build.outputDirectory}/rest-docs-archiva-rest-api src/enunciate/enunciate.xml ${enunciate.debug} diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/pom.xml b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/pom.xml index 0ceebf065..813e1ffec 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/pom.xml +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/pom.xml @@ -97,6 +97,12 @@ archiva-maven2-model + + org.jsoup + jsoup + 1.7.1 + + org.apache.archiva.redback redback-authorization-api 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 index 000000000..993adbed7 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/docs/RestDocsServlet.java @@ -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 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 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 ); + } +} diff --git a/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/WEB-INF/web.xml b/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/WEB-INF/web.xml index bb30d5117..7f5c8acb0 100644 --- a/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/WEB-INF/web.xml +++ b/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/WEB-INF/web.xml @@ -79,6 +79,11 @@ 1 + + RestDocumentation + org.apache.archiva.rest.docs.RestDocsServlet + 3 + @@ -92,6 +97,11 @@ RssFeedServlet /feeds/* + + + RestDocumentation + /rest-docs/* + RepositoryServlet diff --git a/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/css/archiva.css b/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/css/archiva.css index c95a19e63..859c7d80c 100644 --- a/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/css/archiva.css +++ b/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/css/archiva.css @@ -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 diff --git a/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/index.html b/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/index.html index 0b8e2a898..26ba918f6 100644 --- a/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/index.html +++ b/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/index.html @@ -21,7 +21,7 @@ - + @@ -29,7 +29,7 @@ - + diff --git a/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/archiva.js b/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/archiva.js index d6ab5f443..4b6be7144 100644 --- a/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/archiva.js +++ b/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/archiva.js @@ -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 index 000000000..6c05603ed --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/docs.js @@ -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 diff --git a/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/main-tmpl.js b/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/main-tmpl.js index 46611cab8..1ca725c7c 100644 --- a/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/main-tmpl.js +++ b/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/main-tmpl.js @@ -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); diff --git a/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/main.js b/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/main.js index e17616642..885e04613 100644 --- a/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/main.js +++ b/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/main.js @@ -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 index 000000000..c1e1a9f28 --- /dev/null +++ b/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/templates/archiva/docs.html @@ -0,0 +1,37 @@ + + + + + \ No newline at end of file diff --git a/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/templates/archiva/menu.html b/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/templates/archiva/menu.html index 35e44a890..f1ab8fd68 100644 --- a/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/templates/archiva/menu.html +++ b/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/templates/archiva/menu.html @@ -52,6 +52,17 @@ + + -- 2.39.5