Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ target
*.iml
*.ipr
*.iws
.idea
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>

Expand Down
45 changes: 33 additions & 12 deletions src/main/java/org/versly/rest/wsdoc/AnnotationProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,18 @@
package org.versly.rest.wsdoc;

import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.versly.rest.wsdoc.impl.*;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.*;
import javax.lang.model.type.*;
import javax.lang.model.util.AbstractTypeVisitor6;
import javax.lang.model.util.AbstractTypeVisitor7;
import javax.tools.Diagnostic;
import javax.tools.FileObject;
import javax.tools.StandardLocation;
Expand All @@ -49,12 +52,13 @@
// - plural RequestMapping value support (i.e., two paths bound to one method)
// - support for methods not marked with @RequestMapping whose class does have a @RequestMapping annotation
@SupportedAnnotationTypes({"org.springframework.web.bind.annotation.RequestMapping", "javax.ws.rs.Path"})
@SupportedSourceVersion(SourceVersion.RELEASE_7)
public class AnnotationProcessor extends AbstractProcessor {

private RestDocumentation _docs = new RestDocumentation();
private boolean _isComplete = false;
private Map<TypeMirror, JsonType> _memoizedTypeMirrors = new HashMap<TypeMirror, JsonType>();
private Map<DeclaredType, JsonType> _memoizedDeclaredTypes = new HashMap<DeclaredType, JsonType>();
private Map<TypeMirror, JsonType> _memoizedTypeMirrors = new HashMap<>();
private Map<DeclaredType, JsonType> _memoizedDeclaredTypes = new HashMap<>();

@Override
public boolean process(Set<? extends TypeElement> supportedAnnotations, RoundEnvironment roundEnvironment) {
Expand All @@ -63,7 +67,7 @@ public boolean process(Set<? extends TypeElement> supportedAnnotations, RoundEnv
if (_isComplete)
return true;

Collection<String> processedPackageNames = new LinkedHashSet<String>();
Collection<String> processedPackageNames = new LinkedHashSet<>();
processElements(roundEnvironment, processedPackageNames, new SpringMVCRestImplementationSupport());
processElements(roundEnvironment, processedPackageNames, new JaxRSRestImplementationSupport());

Expand Down Expand Up @@ -168,7 +172,7 @@ private void scanForSpringMVCMultipart(ExecutableElement executableElement, Rest

private void buildRequestBodies(ExecutableElement executableElement, RestDocumentation.Resource.Method doc,
RestImplementationSupport implementationSupport) {
List<VariableElement> requestBodies = new ArrayList<VariableElement>();
List<VariableElement> requestBodies = new ArrayList<>();
for (VariableElement var : executableElement.getParameters()) {
if (implementationSupport.isRequestBody(var))
requestBodies.add(var);
Expand Down Expand Up @@ -283,8 +287,8 @@ private String[] getClassLevelUrlPaths(TypeElement cls, RestImplementationSuppor
}
}

private class TypeVisitorImpl extends AbstractTypeVisitor6<JsonType,Void> {
private Map<Name, DeclaredType> _typeArguments = new HashMap<Name, DeclaredType>();
private class TypeVisitorImpl extends AbstractTypeVisitor7<JsonType,Void> {
private Map<Name, DeclaredType> _typeArguments = new HashMap<>();
private Collection<String> _typeRecursionDetector;
private DeclaredType _type;

Expand Down Expand Up @@ -319,7 +323,7 @@ private void loadTypeElements(DeclaredType type, List<? extends TypeMirror> type

@Override
public JsonType visitPrimitive(PrimitiveType primitiveType, Void o) {
return jsonTypeFromTypeMirror(primitiveType, new HashSet<String>(_typeRecursionDetector));
return jsonTypeFromTypeMirror(primitiveType, new HashSet<>(_typeRecursionDetector));
}

@Override
Expand Down Expand Up @@ -371,7 +375,7 @@ public JsonType visitDeclared(DeclaredType declaredType, Void o) {
} else {
TypeElement element = (TypeElement) declaredType.asElement();
if (element.getKind() == ElementKind.ENUM) {
List<String> enumConstants = new ArrayList<String>();
List<String> enumConstants = new ArrayList<>();
for (Element e : element.getEnclosedElements()) {
if (e.getKind() == ElementKind.ENUM_CONSTANT) {
enumConstants.add(e.toString());
Expand Down Expand Up @@ -427,6 +431,13 @@ private void buildTypeContents(JsonObject o, TypeElement element) {
return;
}

JsonIgnoreProperties jsonIgnoreProperties = element.getAnnotation(JsonIgnoreProperties.class);
if (jsonIgnoreProperties != null) {
for (String ignoreProperty : jsonIgnoreProperties.value()) {
o.ignoreProperty(ignoreProperty);
}
}

if (element.getSuperclass().getKind() != TypeKind.NONE) {
// an interface's superclass is TypeKind.NONE

Expand All @@ -452,6 +463,11 @@ private void addFieldFromBeanMethod(JsonObject o, ExecutableElement executableEl
String beanName = methodName.substring(trimLength + 1, methodName.length());
beanName = methodName.substring(trimLength, trimLength + 1).toLowerCase() + beanName;

// ignore this property if is listed as JsonIgnoreProperties
if (o.isIgnoringProperty(beanName)) {
return;
}

// replace variables with the current concrete manifestation
if (type instanceof TypeVariable) {
type = getDeclaredTypeForTypeVariable((TypeVariable) type);
Expand All @@ -465,14 +481,14 @@ private void addFieldFromBeanMethod(JsonObject o, ExecutableElement executableEl
o.addField(beanName, jsonType)
.setCommentText(docComment);
} else {
o.addField(beanName, jsonTypeFromTypeMirror(type, new HashSet<String>(_typeRecursionDetector)))
o.addField(beanName, jsonTypeFromTypeMirror(type, new HashSet<>(_typeRecursionDetector)))
.setCommentText(docComment);
}
}

private JsonType recurseForJsonType(DeclaredType type) {
// loop over the element's generic types, and build a concrete list from the owning context
List<DeclaredType> concreteTypes = new ArrayList<DeclaredType>();
List<DeclaredType> concreteTypes = new ArrayList<>();

for (TypeMirror generic : type.getTypeArguments()) {
if (generic instanceof DeclaredType)
Expand All @@ -481,7 +497,7 @@ private JsonType recurseForJsonType(DeclaredType type) {
concreteTypes.add(_typeArguments.get(((TypeVariable) generic).asElement().getSimpleName()));
}
_typeRecursionDetector.add(_type.toString());
Collection<String> types = new HashSet<String>(_typeRecursionDetector);
Collection<String> types = new HashSet<>(_typeRecursionDetector);
return jsonTypeForDeclaredType(type, concreteTypes, types);
}

Expand Down Expand Up @@ -546,6 +562,11 @@ public JsonType visitNoType(NoType noType, Void o) {
public JsonType visitUnknown(TypeMirror typeMirror, Void o) {
throw new UnsupportedOperationException(typeMirror.toString());
}

@Override
public JsonType visitUnion(UnionType unionType, Void aVoid) {
throw new UnsupportedOperationException(unionType.toString());
}
}

public interface RestImplementationSupport {
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/org/versly/rest/wsdoc/RestDocAssembler.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public static void main(String... args)
Arguments arguments = new Arguments();
new JCommander(arguments, args);

List<RestDocumentation> docs = new LinkedList<RestDocumentation>();
List<RestDocumentation> docs = new LinkedList<>();
for (String input : arguments.inputs) {
File inputFile = new File(input);
if (inputFile.isDirectory()) {
Expand All @@ -60,7 +60,7 @@ public static void main(String... args)
}

if (docs.size() > 0) {
List<Pattern> excludePatterns = new ArrayList<Pattern>();
List<Pattern> excludePatterns = new ArrayList<>();
for (String pattern : arguments.excludes)
excludePatterns.add(Pattern.compile(pattern));
new RestDocAssembler(arguments.outputFileName).writeDocumentation(docs, excludePatterns);
Expand All @@ -76,7 +76,7 @@ void writeDocumentation(List<RestDocumentation> docs, Iterable<Pattern> excludeP

List<RestDocumentation> filteredDocs;
if (excludePatterns != null) {
filteredDocs = new ArrayList<RestDocumentation>();
filteredDocs = new ArrayList<>();
for (RestDocumentation doc : docs)
filteredDocs.add(doc.filter(excludePatterns));
} else {
Expand All @@ -89,7 +89,7 @@ void writeDocumentation(List<RestDocumentation> docs, Iterable<Pattern> excludeP
Writer out = null;
try {
Template template = conf.getTemplate("RestDocumentation.ftl");
Map<String, List<RestDocumentation>> root = new HashMap<String, List<RestDocumentation>>();
Map<String, List<RestDocumentation>> root = new HashMap<>();
root.put("docs", filteredDocs);
File file = getOutputFile();
out = new FileWriter(file);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public String[] getRequestPaths(TypeElement cls) {

@Override
public String getRequestMethod(ExecutableElement executableElement, TypeElement contextClass) {
List<String> methods = new ArrayList<String>();
List<String> methods = new ArrayList<>();

gatherMethod(executableElement, methods, GET.class);
gatherMethod(executableElement, methods, PUT.class);
Expand Down
14 changes: 12 additions & 2 deletions src/main/java/org/versly/rest/wsdoc/impl/JsonObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,20 @@

public class JsonObject implements JsonType, Serializable {

private List<JsonField> _fields = new ArrayList();
private transient Set<String> ignoreProperties = new HashSet<>();

public void ignoreProperty(String name) {
ignoreProperties.add(name);
}

public boolean isIgnoringProperty(String name) {
return ignoreProperties.contains(name);
}

private List<JsonField> _fields = new ArrayList<>();

public <T extends JsonType> JsonField addField(String fieldName, T value) {
JsonField<T> field = new JsonField(fieldName, value);
JsonField<T> field = new JsonField<>(fieldName, value);
if (_fields.contains(field))
throw new IllegalStateException("field " + fieldName + " is already defined");
_fields.add(field);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

public class JsonPrimitive implements JsonType, Serializable {

private static final Map<String, String> _primitiveTypeNamesByJavaTypeName = new HashMap();
private static final Map<String, String> _primitiveTypeNamesByJavaTypeName = new HashMap<>();

static {
_primitiveTypeNamesByJavaTypeName.put(Object.class.getName(), "object");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

public class RestDocumentation implements Serializable {

private Map<String, Resource> _resources = new LinkedHashMap();
private Map<String, Resource> _resources = new LinkedHashMap<>();

public Collection<Resource> getResources() {
return _resources.values();
Expand Down Expand Up @@ -71,7 +71,7 @@ public RestDocumentation filter(Iterable<Pattern> excludePatterns) {
public class Resource implements Serializable {

private String path;
private Collection<Method> _methods = new LinkedList<Method>();
private Collection<Method> _methods = new LinkedList<>();

public Resource(String path) {
this.path = path;
Expand Down Expand Up @@ -168,7 +168,7 @@ public String getKey() {

public class UrlFields implements Serializable {

private Map<String, JsonType> _jsonTypes = new LinkedHashMap();
private Map<String, JsonType> _jsonTypes = new LinkedHashMap<>();

public Map<String, JsonType> getFields() {
return _jsonTypes;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
div.resource-docs { padding-bottom: 20px; }

div.url-info { padding-bottom: 20px; }
div.url-info table { width: 400px; border-spacing: 0px; }
div.url-info table { width: 400px; border-spacing: 0; }
div.url-info thead td { border-bottom: 1px dashed gray; }
.url-info-key { font-family: monospace; }
.url-info-expected-type { font-family: monospace; }
Expand Down Expand Up @@ -66,7 +66,7 @@
<#list docs as doc>
<#list doc.resources as resource>
<#list resource.requestMethodDocs as methodDoc>
<a id="${methodDoc.key}"/>
<a id="${methodDoc.key}"></a>
<div class="resource">
<div class="resource-header">
<span class="method">${methodDoc.requestMethod}</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package org.versly.rest.wsdoc.springmvc;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
Expand All @@ -32,6 +33,7 @@ public SnowReport getReportForMountain(
}


@JsonIgnoreProperties({"mountainName"})
public interface SnowReport {
public String getMountainName();
public double getTemperatureInFahrenheit();
Expand Down