Skip to content

Commit

Permalink
Add resource discovery to swagger ui webjar
Browse files Browse the repository at this point in the history
- Changing webjar layout to match the webjar standard
- Added gitter/circleci integration
  • Loading branch information
adrianbk committed Apr 7, 2015
1 parent db5a6ae commit 647fc40
Show file tree
Hide file tree
Showing 9 changed files with 219 additions and 13 deletions.
4 changes: 3 additions & 1 deletion circle.yml
Expand Up @@ -15,4 +15,6 @@ deployment:
owner: springfox
commands:
- ./gradlew snapshot -PbintrayUsername=${bintrayUsername} -PbintrayPassword=${bintrayPassword} -i -x check

notify:
webhooks:
- url: https://webhooks.gitter.im/e/b30a7db820817acfc6d8
3 changes: 2 additions & 1 deletion gradle/idea.gradle
Expand Up @@ -22,10 +22,11 @@ idea {
def copyrightManager = node.component.find { it.'@name' == 'CopyrightManager' }
copyrightManager.@default = "ASL2"
def aslCopyright = copyrightManager.copyright.find { it.option.find { it.@name == "myName" }?.@value == "ASL2" }
def copyRightFile = file("$rootDir/config/apache-copyright.header")
if (aslCopyright == null) {
copyrightManager.append(new XmlParser().parseText("""
<copyright>
<option name="notice" value="Copyright \${today.year} the original author or authors.&#10;&#10;Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);&#10;you may not use this file except in compliance with the License.&#10;You may obtain a copy of the License at&#10;&#10; http://www.apache.org/licenses/LICENSE-2.0&#10;&#10;Unless required by applicable law or agreed to in writing, software&#10;distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#10;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#10;See the License for the specific language governing permissions and&#10;limitations under the License." />
<option name="notice" value="${copyRightFile.text}" />
<option name="keyword" value="Copyright" />
<option name="allowReplaceKeyword" value="" />
<option name="myName" value="ASL2" />
Expand Down
Expand Up @@ -21,6 +21,7 @@

import springfox.documentation.service.Documentation;

import java.util.Collection;
import java.util.Map;

import static com.google.common.collect.Maps.*;
Expand All @@ -36,4 +37,7 @@ public Documentation documentationByGroup(String groupName) {
return documentationLookup.get(groupName);
}

public Collection<Documentation> all() {
return documentationLookup.values();
}
}
16 changes: 5 additions & 11 deletions springfox-swagger-ui/build.gradle
Expand Up @@ -37,7 +37,8 @@ ext {
}

dependencies {
compile "org.webjars:jquery:2.1.1"
compile project(':springfox-spring-web')
compile 'org.webjars:jquery:2.1.3'
}


Expand All @@ -61,16 +62,9 @@ task unzip(type: Copy) {
* Creates the jsp from index.html
*/
task sdoc(type: Copy) {
from("${buildDir}/${swaggerUiExplodedDir}/index.html")
from("${projectDir}/src/jsps/sdoc.jsp")
from("${projectDir}/src/jsps/swaggerResources.jsp")
into("${buildDir}/${swaggerUiExplodedDir}")

filter { String line ->
line.replaceAll("\"http://petstore.swagger.io/v2/swagger.json\"", replacePath)
.replaceAll('/\\*', '')
.replaceAll('\\*/', '')
}

rename('index.html', 'sdoc.jsp')
}

task removeHtmlIndex(type: Delete) {
Expand All @@ -80,7 +74,7 @@ task removeHtmlIndex(type: Delete) {

jar {
from("${buildDir}/${swaggerUiExplodedDir}") {
into "META-INF/resources"
into "META-INF/resources/webjars/${project.name}/${project.version}"

manifest {
attributes(
Expand Down
98 changes: 98 additions & 0 deletions springfox-swagger-ui/src/jsps/sdoc.jsp
@@ -0,0 +1,98 @@
<!DOCTYPE html>
<html>
<head>
<title>Swagger UI</title>
<link href='css/typography.css' media='screen' rel='stylesheet' type='text/css'/>
<link href='css/reset.css' media='screen' rel='stylesheet' type='text/css'/>
<link href='css/screen.css' media='screen' rel='stylesheet' type='text/css'/>
<link href='css/reset.css' media='print' rel='stylesheet' type='text/css'/>
<link href='css/screen.css' media='print' rel='stylesheet' type='text/css'/>
<script type="text/javascript" src="lib/shred.bundle.js"></script>
<script src='lib/jquery-1.8.0.min.js' type='text/javascript'></script>
<script src='lib/jquery.slideto.min.js' type='text/javascript'></script>
<script src='lib/jquery.wiggle.min.js' type='text/javascript'></script>
<script src='lib/jquery.ba-bbq.min.js' type='text/javascript'></script>
<script src='lib/handlebars-2.0.0.js' type='text/javascript'></script>
<script src='lib/underscore-min.js' type='text/javascript'></script>
<script src='lib/backbone-min.js' type='text/javascript'></script>
<script src='lib/swagger-client.js' type='text/javascript'></script>
<script src='swagger-ui.js' type='text/javascript'></script>
<script src='lib/highlight.7.3.pack.js' type='text/javascript'></script>
<script src='lib/marked.js' type='text/javascript'></script>

<!-- enabling this will enable oauth2 implicit scope support -->
<script src='lib/swagger-oauth.js' type='text/javascript'></script>
<script type="text/javascript">
$(function () {
var url = window.location.search.match(/url=([^&]+)/);
if (url && url.length > 1) {
url = decodeURIComponent(url[1]);
} else {
url = window.location.origin + "${pageContext.request.contextPath}/api-docs";
}
window.swaggerUi = new SwaggerUi({
url: url,
dom_id: "swagger-ui-container",
supportedSubmitMethods: ['get', 'post', 'put', 'delete', 'patch'],
onComplete: function (swaggerApi, swaggerUi) {
if (typeof initOAuth == "function") {
initOAuth({
clientId: "your-client-id",
realm: "your-realms",
appName: "your-app-name"
});
}
$('pre code').each(function (i, e) {
hljs.highlightBlock(e)
});
},
onFailure: function (data) {
log("Unable to Load SwaggerUI");
},
docExpansion: "none",
sorter: "alpha"
});
function addApiKeyAuthorization() {
var key = $('#input_apiKey')[0].value;
log("key: " + key);
if (key && key.trim() != "") {
log("added key " + key);
window.authorizations.add("api_key", new ApiKeyAuthorization("api_key", key, "query"));
}
}
$('#input_apiKey').change(function () {
addApiKeyAuthorization();
});
var apiKey = "myApiKeyXXXX123456789";
$('#input_apiKey').val(apiKey);
addApiKeyAuthorization();
window.swaggerUi.load();
});
</script>
</head>

<body class="swagger-section">
<div id='header'>
<div class="swagger-ui-wrap">
<a id="logo" href="http://swagger.io">swagger</a>

<form id='api_selector'>
<div class='input'><input placeholder="http://example.com/api" id="input_baseUrl" name="baseUrl" type="text"/></div>
<div class='input'><input placeholder="api_key" id="input_apiKey" name="apiKey" type="text"/></div>
<div class='input'><a id="explore" href="#">Explore</a></div>
</form>
</div>
<div>
<jsp:include page="swaggerResources.jsp"/>
</div>
</div>

<div id="message-bar" class="swagger-ui-wrap">&nbsp;</div>
<div id="swagger-ui-container" class="swagger-ui-wrap"></div>
</body>
</html>
18 changes: 18 additions & 0 deletions springfox-swagger-ui/src/jsps/swaggerResources.jsp
@@ -0,0 +1,18 @@
<%@ page import="org.springframework.context.ApplicationContext" %>
<%@ page import="org.springframework.web.context.support.WebApplicationContextUtils" %>
<%@ page import="springfox.documentation.swagger.ui.ApiResourceLocator" %>
<%@ page import="springfox.documentation.swagger.ui.SwaggerApi" %>
<ol>
<%
ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(request.getServletContext());
ApiResourceLocator apiResourceLocator = (ApiResourceLocator) context.getBean("apiResourceLocator");
for (SwaggerApi swaggerApi : apiResourceLocator.resources()) {
%>
<li>
<%=swaggerApi.getTitle() + "-" + swaggerApi.getUri()%>
</li>

<%
}
%>
</ol>
@@ -0,0 +1,48 @@
/*
*
* Copyright 2015 the original author or authors.
*
* Licensed 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.
*
*
*/
package springfox.documentation.swagger.ui;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import springfox.documentation.service.Documentation;
import springfox.documentation.spring.web.DocumentationCache;

import java.util.ArrayList;
import java.util.List;

@Component
public class ApiResourceLocator {

private final DocumentationCache documentationCache;

@Autowired
public ApiResourceLocator(DocumentationCache documentationCache) {
this.documentationCache = documentationCache;
}

public List<SwaggerApi> resources() {
List<SwaggerApi> swaggerApis = new ArrayList<SwaggerApi>();
for (Documentation documentation : documentationCache.all()) {
SwaggerApi swaggerApi = new SwaggerApi();
swaggerApi.setUri(documentation.getBasePath());
swaggerApi.setTitle(documentation.getGroupName());
}
return swaggerApis;
}
}
@@ -0,0 +1,40 @@
/*
*
* Copyright 2015 the original author or authors.
*
* Licensed 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.
*
*
*/
package springfox.documentation.swagger.ui;

public class SwaggerApi {
private String uri;
private String title;

public String getUri() {
return uri;
}

public void setUri(String uri) {
this.uri = uri;
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}
}
Expand Up @@ -59,6 +59,7 @@ ResponseEntity<Swagger> getDocumentation(
return new ResponseEntity<Swagger>(HttpStatus.NOT_FOUND);
}
Swagger swagger = mapper.mapDocumentation(documentation);
//TODO - this will be problematic when behind a proxy or w
swagger.host(String.format("%s:%s", request.getServerName(), request.getServerPort()));
return new ResponseEntity<Swagger>(swagger, HttpStatus.OK);
}
Expand Down

0 comments on commit 647fc40

Please sign in to comment.