Skip to content

Commit

Permalink
update for #736 use the plugin called api as we may as well unify swa…
Browse files Browse the repository at this point in the history
…gger, wadl and WSDL into the same plugin; we can then use consistent CSS across all three. Here's an initial WADL view that reuses the swagger-ui style markup so it looks familiar to folks using swagger
  • Loading branch information
jstrachan committed Nov 14, 2013
1 parent 1040fe8 commit 87228ec
Show file tree
Hide file tree
Showing 13 changed files with 1,481 additions and 27 deletions.
976 changes: 976 additions & 0 deletions hawtio-web/src/main/webapp/app/api/css/style.css

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions hawtio-web/src/main/webapp/app/api/doc/help.md
@@ -0,0 +1,3 @@
### API

This plugin supports viewing the APIs of [WSDL](http://www.w3.org/TR/wsdl) and [WADL](https://wadl.java.net/) documents on [Apache CXF](http://cxf.apache.org/) based web service endpoints
192 changes: 192 additions & 0 deletions hawtio-web/src/main/webapp/app/api/html/wadl.html
@@ -0,0 +1,192 @@
<link rel="stylesheet" href="app/api/css/style.css" type="text/css"/>

<div class="row-fluid" ng-controller="API.WadlViewController">

<div class="span12 page-padded">
<div class="section-header">

<div class="section-filter">
<input type="text" class="search-query" placeholder="Filter..." ng-model="searchText">
<i class="icon-remove clickable" title="Clear Filter" ng-click="searchFilter = ''"></i>
</div>

</div>
</div>


<div class="log-main">
<div ng-class="isInDashboardClass()">

<div class="swagger-ui-wrap">
<div class="info">
<div ng-repeat="root in apidocs.resources | filter:searchText">
<div ng-repeat="resource in root.resource | filter:searchText">
<ng-include src="'resourceTemplate'"/>
</div>

<div class="footer">
<br>
<br>
<h4 style="color: #999">[ <span style="font-variant: small-caps">base url</span>: {{root.base}},
<!--
<span style="font-variant: small-caps">api version</span>: 1.0.0
-->
]</h4>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

<script type="text/ng-template" id="resourceTemplate">
<ul class="resources">
<li class="resource active">
<div class="heading">
<h2>
<a ng-click="toggleResourcesFor(resource)">{{resource.path}}</a>
</h2>
<ul class="options">
<li>
<a ng-click="showHide(resource)">Show/Hide</a>
</li>
<li>
<a ng-click="showOperations(resource)">
List Operations
</a>
</li>
<li>
<a ng-click="showOperations(resource)">
Expand Operations
</a>
</li>
<li>
<a target="raw" href="{{url}}">Raw</a>
</li>
</ul>
</div>

<ul class="endpoints" style="display: block;">
<li class="endpoint">
<ul class="operations">
<li ng-repeat="method in resource.method" class="{{method.name | lowercase}} operation expandable">
<div class="expandable" model="method">
<div class="heading title">
<h3>
<span class="http_method">{{method.name}}</span>
<span class="path">{{resource.path}}</span>
</h3>
<ul class="options">
<li>
<a href="#" class="toggleOperation">{{method.description}}</a>
</li>
</ul>
</div>

<div class="content expandable-body">
<div class="parameters" ng-show="resource.param.length">
<form accept-charset="UTF-8" class="sandbox">
<div style="margin:0;padding:0;display:inline"></div>

<h4>Parameters</h4>
<table class="fullwidth">
<thead>
<tr>
<th style="width: 100px; max-width: 100px">Parameter</th>
<th style="width: 310px; max-width: 310px">Value</th>
<th style="width: 200px; max-width: 200px">Description</th>
<th style="width: 100px; max-width: 100px">Parameter Type</th>
<th style="width: 220px; max-width: 230px">Data Type</th>
</tr>
</thead>
<tbody class="operation-params">

<tr ng-repeat="param in resource.param">
<td class="code required">{{param.name}}</td>
<td>
<input class="parameter required" minlength="1" name="{{param.name}}"
placeholder="(required)"
type="text" value="">
</td>
<td>
<strong>{{param.description}}</strong>
</td>
<td>{{param.style}}</td>
<td><span class="model-signature">{{param.type}}</span></td>
</tr>
</tbody>
</table>

<div class="requests" ng-show="method.request.length">
<h4>Request</h4>
<ul>
<li class="request" ng-repeat="request in method.request">
<div ng-repeat="rep in request.representation">
{{rep.mediaType}}
</div>
</li>
</ul>
</div>

<div class="responses" ng-show="method.response.length">
<h4>Response</h4>
<ul>
<li class="response" ng-repeat="response in method.response">
<div ng-repeat="rep in response.representation">
{{rep.mediaType}}
</div>
</li>
</ul>
</div>

<!--
TODO

<div class="errorCodes">
<h4>Error Status Codes</h4>
<table class="fullwidth">
<thead>
<tr>
<th>HTTP Status Code</th>
<th>Reason</th>
</tr>
</thead>
<tbody class="operation-status">

<tr>
<td width="15%" class="code">400</td>
<td>Invalid username supplied</td>
</tr>
<tr>
<td width="15%" class="code">404</td>
<td>User not found</td>
</tr>
</tbody>
</table>
</div>


<div class="sandbox_header">
<input class="submit" name="commit" type="button" value="Try it out!">
<a href="#" class="response_hider" style="display:none">Hide Response</a>
<img alt="Throbber" class="response_throbber" src="images/throbber.gif" style="display:none">
</div>
</form>
-->
</div>
</div>
</div>
</li>
</ul>
<ul>
<li class="resource" ng-repeat="resource in resource.resource">
<ng-include src="'resourceTemplate'"/>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</script>

@@ -1,4 +1,4 @@
<div class="row-fluid" ng-controller="Wsdl.WsdlViewController">
<div class="row-fluid" ng-controller="API.WsdlViewController">

<div class="span12 page-padded">
<div class="section-header">
Expand Down
@@ -1,13 +1,14 @@
module Wsdl {
var pluginName = 'wsdl';
angular.module(pluginName, ['bootstrap', 'hawtioCore']).
module API {
var pluginName = 'api';
angular.module(pluginName, ['bootstrap', 'hawtioCore', 'hawtio-ui']).
config(($routeProvider) => {
$routeProvider.
when('/wsdl/view', {templateUrl: 'app/wsdl/html/view.html'})
when('/api/wsdl', {templateUrl: 'app/api/html/wsdl.html'}).
when('/api/wadl', {templateUrl: 'app/api/html/wadl.html'});
}).
run(($location:ng.ILocationService, workspace:Workspace, viewRegistry, layoutFull, helpRegistry) => {

viewRegistry['wsdl'] = layoutFull;
viewRegistry['api'] = layoutFull;
/*
helpRegistry.addUserDoc('log', 'app/wsdl/doc/help.md', () => {
return workspace.treeContainsDomainAndProperties('org.fusesource.insight', {type: 'LogQuery'});
Expand Down
155 changes: 155 additions & 0 deletions hawtio-web/src/main/webapp/app/api/js/helpers.ts
@@ -0,0 +1,155 @@
module API {

var log:Logging.Logger = Logger.get("API");

/**
* Loads the XML for the given url if its defined or ignore if not valid
*/
export function loadXml(url, onXml) {
if (url) {
log.info("Loading XML: " + url);

$.ajax({
type: "GET",
url: url,
dataType: "xml",
success: onXml
});
}
}


var wadlXmlToJavaConfig = {
/*
elementToPropertyName: (owner, element) => {
},
attributeToPropertyName: (owner, attribute) => {
}
*/
};

/**
* When a WADL XML document is loaded, lets convert it to JSON and return it
*/
export function onWadlXmlLoaded(response) {
var root = response.documentElement;
var output = {};
return API.convertWadlToJson(root, output);
}


/**
* Converts the given XML element from WADL to JSON
*/
export function convertWadlToJson(element, object = {}) {
return API.convertXmlToJson(element, object, wadlXmlToJavaConfig);
}

export function convertWadlJsonToSwagger(object) {
// now lets convert to swagger style json
var apis = [];
var basePath:string = null;
var resourcePath:string = null;

var resources = Core.pathGet(object, ["resources", 0]);
if (resources) {
basePath = resources.base;
angular.forEach(resources.resource, (resource) => {
var path = resource.path;
var operations = [];
angular.forEach(resource.method, (method) => {
var name = method.name;
var responseMessages = [];
/*
{
"code": 404,
"message": "There are no businesses"
}
*/

var parameters = [];
/*
{
"name": "query",
"description": "a text query to search across facilities",
"required": false,
"allowMultiple": false,
"dataType": "string",
"paramType": "query"
}
*/

operations.push({
"method": method.name,
"summary": method.summary,
"notes": method.notes,
"nickname": method.nickname,
"type": method.type,
"parameters": parameters,
"produces": [
"application/json"
],
"responseMessages": responseMessages
});
});

apis.push({
path: path,
operations: operations
});
});
}
return {
"apiVersion": "1.0",
"swaggerVersion": "1.2",
"basePath": basePath,
"resourcePath": resourcePath,
"produces": [
"application/json"
],
apis: apis
};
}

function nodeName(owner, node) {
return node ? node.localName : null;
}

/**
* Converts the given child elements or attributes into properties on the object
* to convert the XML into JSON using the given config to customise which properties should
* be considered singular
*/
export function convertXmlToJson(element, object, config) {

var elementProperyFn = config.elementToPropertyName || nodeName;
var attributeProperyFn = config.attributeToPropertyName || nodeName;

angular.forEach(element.children, (child) => {
if (child.nodeType === 1) {
var propertyName = elementProperyFn(element, child);
if (propertyName) {
// TODO should we assume everything is a list and then flatten later?
var array = object[propertyName] || [];
if (!angular.isArray(array)) {
array = [array];
}
var value = {};
convertXmlToJson(child, value, config);
array.push(value);
object[propertyName] = array;
}
}
});
angular.forEach(element.attributes, (attr) => {
var propertyName = attributeProperyFn(element, attr);
if (propertyName) {
var value = attr.nodeValue;
object[propertyName] = value;
}
});
return object;
};

}
18 changes: 18 additions & 0 deletions hawtio-web/src/main/webapp/app/api/js/wadl.ts
@@ -0,0 +1,18 @@
module API {

export function WadlViewController($scope, $location, jolokia) {

$scope.url = $location.search()["wadl"];
var log:Logging.Logger = Logger.get("API3");

var wadlNamespace = "http://schemas.xmlsoap.org/wsdl/";

loadXml($scope.url, onWsdl);

function onWsdl(response) {
$scope.apidocs = API.onWadlXmlLoaded(response);
log.info("API docs: " + JSON.stringify($scope.apidocs, null, " "));
Core.$apply($scope);
}
}
}

0 comments on commit 87228ec

Please sign in to comment.