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>
|
||||
</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>
|
||||
|
|
|
@ -97,6 +97,12 @@
|
|||
<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>
|
||||
|
|
|
@ -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>
|
||||
</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>
|
||||
|
@ -92,6 +97,11 @@
|
|||
<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>
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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>
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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/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);
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -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 -->
|
||||
</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>
|
||||
|
||||
|
|
Loading…
Reference in New Issue