jmms.plugins.SwaggerDocGen Maven / Gradle / Ivy
/*
* Copyright 2018 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 jmms.plugins;
import leap.lang.Strings;
import leap.lang.Try;
import leap.lang.io.IO;
import leap.lang.json.JSON;
import leap.lang.json.JsonArray;
import leap.lang.json.JsonObject;
import leap.lang.logging.Log;
import leap.lang.logging.LogFactory;
import org.trimou.Mustache;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
class SwaggerDocGen {
private static final Log log = LogFactory.get(SwaggerDocGen.class);
private static final String DEFAULT = "Default";
private static final String DEFINITIONS = "definitions";
private static final String REQUIRED = "required";
private static final String PROPERTIES = "properties";
private static final String SECURITY_DEFINITIONS = "securityDefinitions";
private static final String SCOPES = "scopes";
private static final String PATHS = "paths";
private static final String OPERATION_ID = "operationId";
private static final String ID = "id";
private static final String NAME = "name";
private static final String TITLE = "title";
private static final String SUMMARY = "summary";
private static final String METHOD = "method";
private static final String PATH = "path";
private static final String DESCRIPTION = "description";
private static final String TAGS = "tags";
private static final String PERMISSIONS = "permissions";
private static final String GROUPS = "groups";
private final String dir;
private final Path folder;
private final String locale;
public SwaggerDocGen(String dir, String locale) {
this.dir = dir;
this.folder = Paths.get(dir);
this.locale = locale;
}
void execute(JsonObject swagger) {
Templates templates = Templates.markdown(dir, locale);
Try.throwUnchecked(() -> Files.createDirectories(folder));
Map data = data(swagger);
templates.all().forEach(template -> {
String file;
if(template.getName().indexOf('.') > 0) {
file = template.getName();
}else {
file = template.getName() + ".md";
}
renderAndWriteFile(template, data, file);
});
}
private void renderAndWriteFile(Mustache template, Map data, String filepath) {
File file = folder.resolve(filepath).toFile();
if(filepath.indexOf('/') > 0) {
Try.throwUnchecked(() -> Files.createDirectories(file.getParentFile().toPath()));
}
log.debug("Render template '{}' and write to '{}'", template.getName(), filepath);
IO.writeString(file, template.render(data));
}
private Map data(JsonObject swagger) {
Map data = JSON.decodeMap(swagger.toString());
swagger = JsonObject.of(data);
//operation groups
data.put(GROUPS, groups(swagger));
//definitions
JsonObject definitions = swagger.getObject(DEFINITIONS);
for(String key : definitions.keys()) {
JsonObject definition = definitions.getObject(key);
if(Strings.isEmpty(definition.getString(TITLE))) {
definition.asMap().put(TITLE, title(definition, key));
}
JsonArray required = definition.getArray(REQUIRED);
if(null != required) {
JsonObject props = definition.getObject(PROPERTIES);
List names = required.asList();
for(String name : names) {
JsonObject prop = props.getObject(name);
prop.asMap().put(REQUIRED, true);
}
}
}
//permissions
Map permissions = new LinkedHashMap<>();
JsonObject securities = swagger.getObject(SECURITY_DEFINITIONS);
if(null != securities) {
for(String key : securities.keys()) {
JsonObject security = securities.getObject(key);
JsonObject scopes = security.getObject(SCOPES);
if(null != scopes) {
permissions.putAll(scopes.asMap());
}
}
}
data.put(PERMISSIONS, permissions);
return data;
}
private Map groups(JsonObject swagger) {
final Map map = new LinkedHashMap<>();
prepare(map, swagger);
int index=1;
JsonObject paths = swagger.getObject(PATHS);
for(String pt : paths.keys()) {
JsonObject path = paths.getObject(pt);
for(String method : path.keys()) {
JsonObject op = path.getObject(method);
List tags = tags(op);
Map operation = op.asMap();
operation.put(ID, "op" + index++);
operation.put(METHOD, method.toUpperCase());
operation.put(PATH, pt);
String title = title(op, "");
if(Strings.isEmpty(title)) {
title = Strings.firstNotEmpty(op.getString(OPERATION_ID), method.toUpperCase() + " " + pt);
}
operation.put(TITLE, title);
for(String tag : tags) {
map.get(tag).addOperation(operation);
}
}
}
List empties = new ArrayList<>();
for(String name : map.keySet()) {
if(map.get(name).getOperations().isEmpty()) {
empties.add(name);
}
}
empties.forEach(name -> map.remove(name));
OpsGroup defaultGroup = map.remove(DEFAULT);
Map groups = new LinkedHashMap<>(map);
if(null != defaultGroup) {
groups.put(DEFAULT, defaultGroup);
}
return groups;
}
private List tags(JsonObject op) {
List tagNames;
JsonArray tags = op.getArray(TAGS);
if(null != tags) {
tagNames = tags.asList();
}else {
tagNames = new ArrayList<>();
}
if(tagNames.isEmpty()) {
tagNames.add(DEFAULT);
}
return tagNames;
}
private void prepare(Map map, JsonObject swagger) {
JsonArray tags = swagger.getArray(TAGS);
if(null == tags || tags.isEmpty()) {
map.put(DEFAULT, new OpsGroup(DEFAULT));
}else {
tags.forEach(tag -> {
OpsGroup group = new OpsGroup(tag.asJsonObject());;
map.put(group.getName(), group);
});
}
}
private static String title(JsonObject o, String defaults) {
String s = Strings.firstNotEmpty(o.getString(TITLE), o.getString("x-" + TITLE));
if(Strings.isEmpty(s)) {
s = Strings.firstNotEmpty(o.getString(SUMMARY), o.getString("x-" + SUMMARY));
}
if(Strings.isEmpty(s)) {
s = defaults;
}
return s;
}
private static String titleOrDesc(JsonObject o, String defaults) {
String s = Strings.firstNotEmpty(o.getString(TITLE), o.getString("x-" + TITLE));
if(Strings.isEmpty(s)) {
s = Strings.firstNotEmpty(o.getString(SUMMARY), o.getString("x-" + SUMMARY));
}
if(Strings.isEmpty(s)) {
s = o.getString(DESCRIPTION);
}
if(Strings.isEmpty(s)) {
s = defaults;
}
return s;
}
private static class OpsGroup {
private final String name;
private final String title;
private final String description;
private final List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy