mirror of https://github.com/apache/archiva.git
[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
This commit is contained in:
parent
db59480d42
commit
258f098ae6
|
@ -171,7 +171,7 @@
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
<configuration>
|
<configuration>
|
||||||
<docsDir>${project.build.outputDirectory}/docs</docsDir>
|
<docsDir>${project.build.outputDirectory}/rest-docs-archiva-rest-api</docsDir>
|
||||||
<configFile>src/enunciate/enunciate.xml</configFile>
|
<configFile>src/enunciate/enunciate.xml</configFile>
|
||||||
<compileDebug>${enunciate.debug}</compileDebug>
|
<compileDebug>${enunciate.debug}</compileDebug>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
|
@ -97,6 +97,12 @@
|
||||||
<artifactId>archiva-maven2-model</artifactId>
|
<artifactId>archiva-maven2-model</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jsoup</groupId>
|
||||||
|
<artifactId>jsoup</artifactId>
|
||||||
|
<version>1.7.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.archiva.redback</groupId>
|
<groupId>org.apache.archiva.redback</groupId>
|
||||||
<artifactId>redback-authorization-api</artifactId>
|
<artifactId>redback-authorization-api</artifactId>
|
||||||
|
|
|
@ -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 );
|
||||||
|
}
|
||||||
|
}
|
|
@ -79,6 +79,11 @@
|
||||||
<load-on-startup>1</load-on-startup>
|
<load-on-startup>1</load-on-startup>
|
||||||
</servlet>
|
</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>
|
||||||
|
@ -92,6 +97,11 @@
|
||||||
<servlet-name>RssFeedServlet</servlet-name>
|
<servlet-name>RssFeedServlet</servlet-name>
|
||||||
<url-pattern>/feeds/*</url-pattern>
|
<url-pattern>/feeds/*</url-pattern>
|
||||||
</servlet-mapping>
|
</servlet-mapping>
|
||||||
|
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>RestDocumentation</servlet-name>
|
||||||
|
<url-pattern>/rest-docs/*</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
|
||||||
<servlet-mapping>
|
<servlet-mapping>
|
||||||
<servlet-name>RepositoryServlet</servlet-name>
|
<servlet-name>RepositoryServlet</servlet-name>
|
||||||
|
|
|
@ -160,4 +160,19 @@ footer {
|
||||||
|
|
||||||
.cursor-hand:hover {
|
.cursor-hand:hover {
|
||||||
cursor: pointer;
|
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;
|
||||||
}
|
}
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<link rel="stylesheet" href="css/prettify.css"/>
|
|
||||||
<link rel="stylesheet" href="css/jquery.fileupload-ui.css"/>
|
<link rel="stylesheet" href="css/jquery.fileupload-ui.css"/>
|
||||||
<link rel="stylesheet" href="css/jqueryFileTree.css"/>
|
<link rel="stylesheet" href="css/jqueryFileTree.css"/>
|
||||||
<link rel="stylesheet" href="css/chosen-0.9.8.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/bootstrap.2.1.1.css">
|
||||||
<link rel="stylesheet" href="css/archiva.css">
|
<link rel="stylesheet" href="css/archiva.css">
|
||||||
<link rel="shortcut icon" href="favicon.ico"/>
|
<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-1.8.1.min.js"></script>
|
||||||
<script type="text/javascript" src="js/jquery-ui-1.8.23.custom.min.js"></script>
|
<script type="text/javascript" src="js/jquery-ui-1.8.23.custom.min.js"></script>
|
||||||
|
|
|
@ -94,6 +94,7 @@ $.ajax({
|
||||||
"archiva.artifacts-management": "archiva/artifacts-management",
|
"archiva.artifacts-management": "archiva/artifacts-management",
|
||||||
"archiva.search": "archiva/search",
|
"archiva.search": "archiva/search",
|
||||||
"archiva.proxy-connectors-rules": "archiva/proxy-connectors-rules",
|
"archiva.proxy-connectors-rules": "archiva/proxy-connectors-rules",
|
||||||
|
"archiva.docs": "archiva/docs",
|
||||||
"archiva.main": "archiva/main"
|
"archiva.main": "archiva/main"
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -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");
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
|
@ -21,15 +21,17 @@ require(['jquery',"jquery.tmpl",'i18n',"utils","text!templates/archiva/menu.html
|
||||||
"text!templates/archiva/modal.html",
|
"text!templates/archiva/modal.html",
|
||||||
"text!templates/archiva/repositories.html",
|
"text!templates/archiva/repositories.html",
|
||||||
"text!templates/archiva/search.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,
|
function(jquery,jqueryTmpl,i18n,utils,menu,generics,modal,repositories,
|
||||||
search,general_admin) {
|
search,general_admin,docs) {
|
||||||
loadArchivaTemplate=function(){
|
loadArchivaTemplate=function(){
|
||||||
var htmlFragment=$("#html-fragments");
|
var htmlFragment=$("#html-fragments");
|
||||||
// template loading
|
// template loading
|
||||||
htmlFragment.append(menu);
|
htmlFragment.append(menu);
|
||||||
htmlFragment.append(generics);
|
htmlFragment.append(generics);
|
||||||
$.tmpl( modal ).appendTo(htmlFragment);
|
$.tmpl( modal ).appendTo(htmlFragment);
|
||||||
|
$.tmpl( docs ).appendTo(htmlFragment);
|
||||||
htmlFragment.append(repositories);
|
htmlFragment.append(repositories);
|
||||||
htmlFragment.append(search);
|
htmlFragment.append(search);
|
||||||
htmlFragment.append(general_admin);
|
htmlFragment.append(general_admin);
|
||||||
|
|
|
@ -20,7 +20,7 @@ define("archiva.main",["jquery","jquery.ui","sammy","jquery.tmpl",'i18n',"jquery
|
||||||
"jquery.validate","jquery.json","knockout","redback.templates","archiva.templates",
|
"jquery.validate","jquery.json","knockout","redback.templates","archiva.templates",
|
||||||
"redback.roles","redback","archiva.general-admin","archiva.repositories",
|
"redback.roles","redback","archiva.general-admin","archiva.repositories",
|
||||||
"archiva.network-proxies","archiva.proxy-connectors","archiva.repository-groups","archiva.artifacts-management",
|
"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) {
|
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.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()}}
|
{ 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();
|
this.activeMenuId = ko.observable();
|
||||||
|
|
||||||
window.sammyArchivaApplication = Sammy(function () {
|
window.sammyArchivaApplication = Sammy(function () {
|
||||||
|
@ -616,7 +623,7 @@ function(jquery,ui,sammy,tmpl) {
|
||||||
var folder = this.params.folder;
|
var folder = this.params.folder;
|
||||||
self.activeMenuId(folder);
|
self.activeMenuId(folder);
|
||||||
var baseItems = self.artifactMenuItems?self.artifactMenuItems:[];
|
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()) {
|
if ( p.href == "#"+self.activeMenuId()) {
|
||||||
screenChange();
|
screenChange();
|
||||||
p.func();
|
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);
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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>
|
|
@ -52,6 +52,17 @@
|
||||||
<!-- /ko -->
|
<!-- /ko -->
|
||||||
</ul>
|
</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>
|
</div>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue