use of com.fasterxml.jackson.module.jsonSchema.JsonSchema in project graylog2-server by Graylog2.
the class Generator method generateForRoute.
public Map<String, Object> generateForRoute(String route, String basePath) {
Map<String, Object> result = Maps.newHashMap();
Set<Class<?>> modelTypes = Sets.newHashSet();
List<Map<String, Object>> apis = Lists.newArrayList();
for (Class<?> clazz : getAnnotatedClasses()) {
Path path = clazz.getAnnotation(Path.class);
if (path == null) {
LOG.debug("Skipping REST resource with no Api or Path annotation: <{}>", clazz.getCanonicalName());
continue;
}
final String prefixedPath = prefixedPath(clazz, path.value());
if (cleanRoute(route).equals(cleanRoute(prefixedPath))) {
// This is the class representing the given route. Get all methods.
LOG.debug("Found corresponding REST resource class: <{}>", clazz.getCanonicalName());
Method[] methods = clazz.getDeclaredMethods();
if (methods == null || methods.length == 0) {
LOG.debug("REST resource <{}> has no methods. Skipping.", clazz.getCanonicalName());
break;
}
for (Method method : methods) {
if (!method.isAnnotationPresent(ApiOperation.class)) {
LOG.debug("Method <{}> has no ApiOperation annotation. Skipping.", method.toGenericString());
continue;
}
ApiOperation apiOperation = method.getAnnotation(ApiOperation.class);
Map<String, Object> api = Maps.newHashMap();
List<Map<String, Object>> operations = Lists.newArrayList();
String methodPath;
if (method.isAnnotationPresent(Path.class)) {
// Method has annotated Path.
methodPath = cleanRoute(method.getAnnotation(Path.class).value());
if (clazz.isAnnotationPresent(Path.class)) {
// The class has a Path, too. Prepend.
String classPath = cleanRoute(prefixedPath(clazz, clazz.getAnnotation(Path.class).value()));
methodPath = classPath + methodPath;
}
} else {
// Method has no annotated Path. We read from it's class.
if (clazz.isAnnotationPresent(Path.class)) {
methodPath = cleanRoute(prefixedPath(clazz, clazz.getAnnotation(Path.class).value()));
} else {
LOG.debug("Method <{}> has no Path annotation. Skipping.", method.toGenericString());
continue;
}
}
Produces produces = null;
if (clazz.isAnnotationPresent(Produces.class) || method.isAnnotationPresent(Produces.class)) {
produces = clazz.getAnnotation(Produces.class);
if (method.isAnnotationPresent(Produces.class)) {
produces = method.getAnnotation(Produces.class);
}
}
api.put("path", methodPath);
Map<String, Object> operation = Maps.newHashMap();
operation.put("method", determineHttpMethod(method));
operation.put("summary", apiOperation.value());
operation.put("notes", apiOperation.notes());
operation.put("nickname", method.getName());
if (produces != null) {
operation.put("produces", produces.value());
}
// skip Response.class because we can't reliably infer any schema information from its payload anyway.
if (!method.getReturnType().isAssignableFrom(Response.class)) {
operation.put("type", method.getReturnType().getSimpleName());
modelTypes.add(method.getReturnType());
}
List<Parameter> parameters = determineParameters(method);
if (parameters != null && !parameters.isEmpty()) {
operation.put("parameters", parameters);
}
for (Parameter parameter : parameters) {
final Class type = parameter.getType();
if (Primitives.unwrap(type).isPrimitive() || type.equals(String.class)) {
continue;
}
modelTypes.add(type);
}
operation.put("responseMessages", determineResponses(method));
operations.add(operation);
api.put("operations", operations);
apis.add(api);
}
}
}
if (basePath.endsWith("/")) {
basePath = basePath.substring(0, basePath.length() - 1);
}
Collections.sort(apis, (o1, o2) -> ComparisonChain.start().compare(o1.get("path").toString(), o2.get("path").toString()).result());
// generate the json schema for the auto-mapped return types
Map<String, Object> models = Maps.newHashMap();
for (Class<?> type : modelTypes) {
// skip non-jackson mapped classes (like Response)
if (!type.isAnnotationPresent(JsonAutoDetect.class)) {
continue;
}
try {
SchemaFactoryWrapper visitor = new SchemaFactoryWrapper();
mapper.acceptJsonFormatVisitor(mapper.constructType(type), visitor);
final JsonSchema schema = visitor.finalSchema();
models.put(type.getSimpleName(), schema);
} catch (JsonMappingException e) {
LOG.error("Error generating model schema. Ignoring this model, this will likely break the API browser.", e);
}
}
result.put("apis", apis);
result.put("basePath", basePath);
result.put("models", models);
result.put("resourcePath", cleanRoute(route));
result.put("apiVersion", ServerVersion.VERSION.toString());
result.put("swaggerVersion", EMULATED_SWAGGER_VERSION);
return result;
}
Aggregations