diff --git a/pom.xml b/pom.xml index 3e5abf2..fbc0fc3 100644 --- a/pom.xml +++ b/pom.xml @@ -27,6 +27,15 @@ + + + com.sun + tools + 1.8 + system + ${java.home}/../lib/tools.jar + + javax javaee-api diff --git a/src/main/java/com/sebastian_daschner/jaxrs_analyzer/JAXRSAnalyzer.java b/src/main/java/com/sebastian_daschner/jaxrs_analyzer/JAXRSAnalyzer.java index 21c3150..60dbaa4 100644 --- a/src/main/java/com/sebastian_daschner/jaxrs_analyzer/JAXRSAnalyzer.java +++ b/src/main/java/com/sebastian_daschner/jaxrs_analyzer/JAXRSAnalyzer.java @@ -21,7 +21,8 @@ */ public class JAXRSAnalyzer { - private final Set projectPaths = new HashSet<>(); + private final Set projectClassPaths = new HashSet<>(); + private final Set projectSourcePaths = new HashSet<>(); private final Set classPaths = new HashSet<>(); private final String projectName; private final String projectVersion; @@ -31,25 +32,28 @@ public class JAXRSAnalyzer { /** * Constructs a JAX-RS Analyzer. * - * @param projectPaths The paths of the projects to be analyzed (can either be directories or jar-files, at least one is mandatory) - * @param classPaths The additional class paths (can either be directories or jar-files) - * @param projectName The project name - * @param projectVersion The project version - * @param backend The backend to render the output - * @param outputLocation The location of the output file (output will be printed to standard out if {@code null}) + * @param projectClassPaths The paths of the projects classes to be analyzed (can either be directories or jar-files, at least one is mandatory) + * @param projectSourcePaths The paths of the projects sources to be analyzed (can either be directories or jar-files, optional) + * @param classPaths The additional class paths (can either be directories or jar-files) + * @param projectName The project name + * @param projectVersion The project version + * @param backend The backend to render the output + * @param outputLocation The location of the output file (output will be printed to standard out if {@code null}) */ - public JAXRSAnalyzer(final Set projectPaths, final Set classPaths, final String projectName, final String projectVersion, + public JAXRSAnalyzer(final Set projectClassPaths, final Set projectSourcePaths, final Set classPaths, final String projectName, final String projectVersion, final Backend backend, final Path outputLocation) { - Objects.requireNonNull(projectPaths); + Objects.requireNonNull(projectClassPaths); + Objects.requireNonNull(projectSourcePaths); Objects.requireNonNull(classPaths); Objects.requireNonNull(projectName); Objects.requireNonNull(projectVersion); Objects.requireNonNull(backend); - if (projectPaths.isEmpty()) + if (projectClassPaths.isEmpty()) throw new IllegalArgumentException("At least one project path is mandatory"); - this.projectPaths.addAll(projectPaths); + this.projectClassPaths.addAll(projectClassPaths); + this.projectSourcePaths.addAll(projectSourcePaths); this.classPaths.addAll(classPaths); this.projectName = projectName; this.projectVersion = projectVersion; @@ -61,7 +65,7 @@ public JAXRSAnalyzer(final Set projectPaths, final Set classPaths, f * Analyzes the JAX-RS project at the class path and produces the output as configured. */ public void analyze() { - final Resources resources = new ProjectAnalyzer(classPaths.toArray(new Path[classPaths.size()])).analyze(projectPaths.toArray(new Path[projectPaths.size()])); + final Resources resources = new ProjectAnalyzer(classPaths).analyze(projectClassPaths, projectSourcePaths); if (resources.isEmpty()) { LogProvider.info("Empty JAX-RS analysis result, omitting output"); diff --git a/src/main/java/com/sebastian_daschner/jaxrs_analyzer/Main.java b/src/main/java/com/sebastian_daschner/jaxrs_analyzer/Main.java index c18485f..607047b 100644 --- a/src/main/java/com/sebastian_daschner/jaxrs_analyzer/Main.java +++ b/src/main/java/com/sebastian_daschner/jaxrs_analyzer/Main.java @@ -39,7 +39,8 @@ public class Main { private static final String DEFAULT_NAME = "project"; private static final String DEFAULT_VERSION = "0.1-SNAPSHOT"; - private static final Set projectPaths = new HashSet<>(); + private static final Set projectClassPaths = new HashSet<>(); + private static final Set projectSourcePaths = new HashSet<>(); private static final Set classPaths = new HashSet<>(); private static String name = DEFAULT_NAME; private static String version = DEFAULT_VERSION; @@ -61,6 +62,7 @@ public class Main { *
    *
  • {@code -b backend} The backend to choose: {@code swagger} (default), {@code plaintext}, {@code asciidoc}
  • *
  • {@code -cp class path[:class paths...]} The additional class paths which contain classes which are used in the project
  • + *
  • {@code -sp source path[:source paths...]} The optional source paths needed for JavaDoc analysis
  • *
  • {@code -X} Debug enabled (prints error debugging information on Standard error out)
  • *
  • {@code -n project name} The name of the project
  • *
  • {@code -v project version} The version of the project
  • @@ -93,7 +95,7 @@ public static void main(final String... args) { final Backend backend = constructBackend(); - final JAXRSAnalyzer jaxrsAnalyzer = new JAXRSAnalyzer(projectPaths, classPaths, name, version, backend, outputFileLocation); + final JAXRSAnalyzer jaxrsAnalyzer = new JAXRSAnalyzer(projectClassPaths, projectSourcePaths, classPaths, name, version, backend, outputFileLocation); jaxrsAnalyzer.analyze(); } @@ -108,6 +110,9 @@ private static void extractArgs(String[] args) { case "-cp": extractClassPaths(args[++i]).forEach(classPaths::add); break; + case "-sp": + extractClassPaths(args[++i]).forEach(projectSourcePaths::add); + break; case "-X": LogProvider.injectDebugLogger(System.err::println); break; @@ -141,7 +146,7 @@ private static void extractArgs(String[] args) { System.err.println("Location " + path.toFile() + " doesn't exist\n"); printUsageAndExit(); } - projectPaths.add(path); + projectClassPaths.add(path); } } } catch (IndexOutOfBoundsException e) { @@ -201,7 +206,7 @@ private static void validateArgs() { printUsageAndExit(); } - if (projectPaths.isEmpty()) { + if (projectClassPaths.isEmpty()) { System.err.println("Please provide at least one project path\n"); printUsageAndExit(); } @@ -244,6 +249,7 @@ private static void printUsageAndExit() { System.err.println("Following available options:\n"); System.err.println(" -b The backend to choose: swagger (default), plaintext, asciidoc"); System.err.println(" -cp [:class paths] Additional class paths (separated with colon) which contain classes used in the project (may be directories or jar-files)"); + System.err.println(" -sp [:source paths] Optional source paths (separated with colon) needed for JavaDoc analysis (may be directories or jar-files)"); System.err.println(" -X Debug enabled (enabled error debugging information)"); System.err.println(" -n The name of the project"); System.err.println(" -v The version of the project"); diff --git a/src/main/java/com/sebastian_daschner/jaxrs_analyzer/analysis/ProjectAnalyzer.java b/src/main/java/com/sebastian_daschner/jaxrs_analyzer/analysis/ProjectAnalyzer.java index 9b632ae..1527997 100644 --- a/src/main/java/com/sebastian_daschner/jaxrs_analyzer/analysis/ProjectAnalyzer.java +++ b/src/main/java/com/sebastian_daschner/jaxrs_analyzer/analysis/ProjectAnalyzer.java @@ -19,6 +19,7 @@ import com.sebastian_daschner.jaxrs_analyzer.LogProvider; import com.sebastian_daschner.jaxrs_analyzer.analysis.bytecode.BytecodeAnalyzer; import com.sebastian_daschner.jaxrs_analyzer.analysis.classes.JAXRSClassVisitor; +import com.sebastian_daschner.jaxrs_analyzer.analysis.javadoc.JavaDocAnalyzer; import com.sebastian_daschner.jaxrs_analyzer.analysis.results.ResultInterpreter; import com.sebastian_daschner.jaxrs_analyzer.model.rest.Resources; import com.sebastian_daschner.jaxrs_analyzer.model.results.ClassResult; @@ -41,7 +42,6 @@ import java.util.concurrent.locks.ReentrantLock; import java.util.jar.JarEntry; import java.util.jar.JarFile; -import java.util.stream.Stream; import static com.sebastian_daschner.jaxrs_analyzer.model.JavaUtils.isAnnotationPresent; @@ -60,8 +60,10 @@ public class ProjectAnalyzer { private final Lock lock = new ReentrantLock(); private final Set classes = new HashSet<>(); + private final Set packages = new HashSet<>(); private final ResultInterpreter resultInterpreter = new ResultInterpreter(); private final BytecodeAnalyzer bytecodeAnalyzer = new BytecodeAnalyzer(); + private final JavaDocAnalyzer javaDocAnalyzer = new JavaDocAnalyzer(); private final URLClassLoader urlClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader(); /** @@ -69,20 +71,22 @@ public class ProjectAnalyzer { * * @param classPaths The locations of additional class paths (can be directories or jar-files) */ - public ProjectAnalyzer(final Path... classPaths) { - Stream.of(classPaths).forEach(this::addToClassPool); + public ProjectAnalyzer(final Set classPaths) { + classPaths.forEach(this::addToClassPool); + addToClassPool(Paths.get(System.getProperty("java.home"), "..", "lib", "tools.jar")); } /** * Analyzes all classes in the given project path. * - * @param projectPaths The project paths + * @param projectClassPaths The project class paths + * @param projectSourcePaths The project source file paths * @return The REST resource representations */ - public Resources analyze(final Path... projectPaths) { + public Resources analyze(final Set projectClassPaths, final Set projectSourcePaths) { lock.lock(); try { - Stream.of(projectPaths).forEach(this::addProjectPath); + projectClassPaths.forEach(this::addProjectPath); // analyze relevant classes final JobRegistry jobRegistry = JobRegistry.getInstance(); @@ -100,6 +104,8 @@ public Resources analyze(final Path... projectPaths) { bytecodeAnalyzer.analyzeBytecode(classResult); } + javaDocAnalyzer.analyze(classResults, packages, projectSourcePaths); + return resultInterpreter.interpret(classResults); } finally { lock.unlock(); @@ -172,9 +178,12 @@ private void addJarClasses(final Path location) { try (final JarFile jarFile = new JarFile(location.toFile())) { final Enumeration entries = jarFile.entries(); while (entries.hasMoreElements()) { - final String entryName = entries.nextElement().getName(); + final JarEntry entry = entries.nextElement(); + final String entryName = entry.getName(); if (entryName.endsWith(".class")) - classes.add(convertToQualifiedName(entryName)); + classes.add(toQualifiedClassName(entryName)); + else if (entry.isDirectory()) + packages.add(entryName); } } catch (IOException e) { throw new IllegalArgumentException("Could not read jar-file '" + location + "', reason: " + e.getMessage()); @@ -192,8 +201,9 @@ private void addDirectoryClasses(final Path location, final Path subPath) { if (file.isDirectory()) addDirectoryClasses(location.resolve(file.getName()), subPath.resolve(file.getName())); else if (file.isFile() && file.getName().endsWith(".class")) { + packages.add(toQualifiedPackageName(subPath.toString())); final String classFileName = subPath.resolve(file.getName()).toString(); - classes.add(convertToQualifiedName(classFileName)); + classes.add(toQualifiedClassName(classFileName)); } } } @@ -204,9 +214,19 @@ else if (file.isFile() && file.getName().endsWith(".class")) { * @param fileName The file name (e.g. a/package/AClass.class) * @return The fully-qualified class name (e.g. a.package.AClass) */ - private static String convertToQualifiedName(final String fileName) { + private static String toQualifiedClassName(final String fileName) { final String replacedSeparators = fileName.replace(File.separatorChar, '.'); return replacedSeparators.substring(0, replacedSeparators.length() - ".class".length()); } + /** + * Converts the given path name of a directory to the fully-qualified package name. + * + * @param pathName The directory name (e.g. a/package/) + * @return The fully-qualified package name (e.g. a.package) + */ + private static String toQualifiedPackageName(final String pathName) { + return pathName.replace(File.separatorChar, '.'); + } + } diff --git a/src/main/java/com/sebastian_daschner/jaxrs_analyzer/analysis/javadoc/JAXRSDoclet.java b/src/main/java/com/sebastian_daschner/jaxrs_analyzer/analysis/javadoc/JAXRSDoclet.java new file mode 100644 index 0000000..c8e97cc --- /dev/null +++ b/src/main/java/com/sebastian_daschner/jaxrs_analyzer/analysis/javadoc/JAXRSDoclet.java @@ -0,0 +1,73 @@ +package com.sebastian_daschner.jaxrs_analyzer.analysis.javadoc; + +import com.sebastian_daschner.jaxrs_analyzer.model.JavaUtils; +import com.sebastian_daschner.jaxrs_analyzer.model.methods.MethodIdentifier; +import com.sun.javadoc.ClassDoc; +import com.sun.javadoc.MethodDoc; +import com.sun.javadoc.RootDoc; + +import java.util.stream.Stream; + +import static com.sebastian_daschner.jaxrs_analyzer.model.JavaUtils.getMethodSignature; +import static com.sebastian_daschner.jaxrs_analyzer.model.Types.*; +import static com.sebastian_daschner.jaxrs_analyzer.model.methods.MethodIdentifier.of; + +/** + * @author Sebastian Daschner + */ +public class JAXRSDoclet { + + public static boolean start(RootDoc rootDoc) { + Stream.of(rootDoc.classes()).forEach(JAXRSDoclet::handleClassDoc); + return true; + } + + private static void handleClassDoc(final ClassDoc classDoc) { + final String className = toClassName(classDoc.qualifiedName()); + JavaDocAnalyzer.put(className, classDoc); + Stream.of(classDoc.methods()).forEach(m -> handleMethodDoc(m, className)); + } + + private static void handleMethodDoc(final MethodDoc methodDoc, final String className) { + final String[] parameterTypes = Stream.of(methodDoc.parameters()) + .map(p -> p.type().qualifiedTypeName()) + .map(JAXRSDoclet::toType) + .toArray(String[]::new); + + final String returnType = toType(methodDoc.returnType().qualifiedTypeName()); + final String signature = getMethodSignature(returnType, parameterTypes); + + final MethodIdentifier identifier = of(className, methodDoc.name(), signature, methodDoc.isStatic()); + JavaDocAnalyzer.put(identifier, methodDoc); + } + + private static String toClassName(final String qualifiedName) { + return qualifiedName.replace('.', '/'); + } + + private static String toType(final String qualifiedName) { + switch (qualifiedName) { + case CLASS_PRIMITIVE_VOID: + return PRIMITIVE_VOID; + case CLASS_PRIMITIVE_BOOLEAN: + return PRIMITIVE_BOOLEAN; + case CLASS_PRIMITIVE_CHAR: + return PRIMITIVE_CHAR; + case CLASS_PRIMITIVE_INT: + return PRIMITIVE_INT; + case CLASS_PRIMITIVE_BYTE: + return PRIMITIVE_BYTE; + case CLASS_PRIMITIVE_SHORT: + return PRIMITIVE_SHORT; + case CLASS_PRIMITIVE_DOUBLE: + return PRIMITIVE_DOUBLE; + case CLASS_PRIMITIVE_FLOAT: + return PRIMITIVE_FLOAT; + case CLASS_PRIMITIVE_LONG: + return PRIMITIVE_LONG; + default: + return JavaUtils.toType(toClassName(qualifiedName)); + } + } + +} diff --git a/src/main/java/com/sebastian_daschner/jaxrs_analyzer/analysis/javadoc/JavaDocAnalyzer.java b/src/main/java/com/sebastian_daschner/jaxrs_analyzer/analysis/javadoc/JavaDocAnalyzer.java new file mode 100644 index 0000000..0e392c8 --- /dev/null +++ b/src/main/java/com/sebastian_daschner/jaxrs_analyzer/analysis/javadoc/JavaDocAnalyzer.java @@ -0,0 +1,85 @@ +package com.sebastian_daschner.jaxrs_analyzer.analysis.javadoc; + +import com.sebastian_daschner.jaxrs_analyzer.model.methods.MethodIdentifier; +import com.sebastian_daschner.jaxrs_analyzer.model.results.ClassResult; +import com.sebastian_daschner.jaxrs_analyzer.model.results.MethodResult; +import com.sun.javadoc.ClassDoc; +import com.sun.javadoc.MethodDoc; + +import java.nio.file.Path; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * @author Sebastian Daschner + */ +public class JavaDocAnalyzer { + + private static final Map METHOD_DOCS = new ConcurrentHashMap<>(); + private static final Map CLASS_DOCS = new ConcurrentHashMap<>(); + + public void analyze(final Set classResults, final Set packages, final Set projectSourcePaths) { + invokeDoclet(packages, projectSourcePaths); + + combineResults(classResults); + } + + private void invokeDoclet(final Set packages, final Set projectSourcePaths) { + final String[] args = Stream.concat( + Stream.of("-sourcepath", + projectSourcePaths.stream().map(Path::toString).collect(Collectors.joining(":")), + "-quiet", + "-doclet", + "com.sebastian_daschner.jaxrs_analyzer.analysis.javadoc.JAXRSDoclet"), + packages.stream()) + .toArray(String[]::new); + + com.sun.tools.javadoc.Main.execute(args); + } + + private void combineResults(final Set classResults) { + + // TODO handle class docs as well + + METHOD_DOCS.entrySet().forEach(e -> classResults.stream() + .map(c -> findMethodResult(e.getKey(), c)) + .filter(Objects::nonNull) + .findAny() + .ifPresent(m -> m.setMethodDoc(e.getValue()))); + } + + private MethodResult findMethodResult(final MethodIdentifier identifier, final ClassResult classResult) { + if (classResult.getOriginalClass().equals(identifier.getContainingClass())) + return classResult.getMethods().stream() + .filter(methodResult -> methodResult.getOriginalMethodSignature().equals(identifier.getSignature())) + .findAny().orElse(null); + + return classResult.getMethods().stream() + .map(MethodResult::getSubResource) + .filter(Objects::nonNull) + .map(c -> findMethodResult(identifier, c)) + .filter(Objects::nonNull) + .findAny().orElse(null); + } + + public static void put(final MethodIdentifier identifier, final MethodDoc methodDoc) { + METHOD_DOCS.put(identifier, methodDoc); + } + + public static void put(final String className, final ClassDoc classDoc) { + CLASS_DOCS.put(className, classDoc); + } + + public static MethodDoc get(final MethodIdentifier identifier) { + return METHOD_DOCS.get(identifier); + } + + public static ClassDoc get(final String className) { + return CLASS_DOCS.get(className); + } + +} diff --git a/src/main/java/com/sebastian_daschner/jaxrs_analyzer/analysis/results/ResultInterpreter.java b/src/main/java/com/sebastian_daschner/jaxrs_analyzer/analysis/results/ResultInterpreter.java index f81be9a..c974780 100644 --- a/src/main/java/com/sebastian_daschner/jaxrs_analyzer/analysis/results/ResultInterpreter.java +++ b/src/main/java/com/sebastian_daschner/jaxrs_analyzer/analysis/results/ResultInterpreter.java @@ -24,6 +24,7 @@ import com.sebastian_daschner.jaxrs_analyzer.model.rest.Response; import com.sebastian_daschner.jaxrs_analyzer.model.results.ClassResult; import com.sebastian_daschner.jaxrs_analyzer.model.results.MethodResult; +import com.sebastian_daschner.jaxrs_analyzer.utils.StringUtils; import java.util.Optional; import java.util.Set; @@ -96,7 +97,9 @@ private void interpretMethodResult(final MethodResult methodResult, final ClassR */ private ResourceMethod interpretResourceMethod(final MethodResult methodResult, final ClassResult classResult) { // HTTP method and method parameters - final ResourceMethod resourceMethod = new ResourceMethod(methodResult.getHttpMethod()); + final String description = methodResult.getMethodDoc() == null || StringUtils.isBlank(methodResult.getMethodDoc().commentText()) ? + null : methodResult.getMethodDoc().commentText(); + final ResourceMethod resourceMethod = new ResourceMethod(methodResult.getHttpMethod(), description); updateMethodParameters(resourceMethod.getMethodParameters(), classResult.getClassFields()); updateMethodParameters(resourceMethod.getMethodParameters(), methodResult.getMethodParameters()); stringParameterResolver.replaceParametersTypes(resourceMethod.getMethodParameters()); diff --git a/src/main/java/com/sebastian_daschner/jaxrs_analyzer/backend/swagger/SwaggerBackend.java b/src/main/java/com/sebastian_daschner/jaxrs_analyzer/backend/swagger/SwaggerBackend.java index 147f447..1f4ae7f 100644 --- a/src/main/java/com/sebastian_daschner/jaxrs_analyzer/backend/swagger/SwaggerBackend.java +++ b/src/main/java/com/sebastian_daschner/jaxrs_analyzer/backend/swagger/SwaggerBackend.java @@ -138,13 +138,18 @@ private JsonObjectBuilder buildForMethod(final ResourceMethod method, final Stri final JsonArrayBuilder produces = Json.createArrayBuilder(); method.getResponseMediaTypes().stream().sorted().forEach(produces::add); - final JsonObjectBuilder methodDescription = Json.createObjectBuilder().add("consumes", consumes).add("produces", produces) + final JsonObjectBuilder builder = Json.createObjectBuilder(); + + if (method.getDescription() != null) + builder.add("description", method.getDescription()); + + builder.add("consumes", consumes).add("produces", produces) .add("parameters", buildParameters(method)).add("responses", buildResponses(method)); if (options.isRenderTags()) - Optional.ofNullable(extractTag(s)).ifPresent(t -> methodDescription.add("tags", Json.createArrayBuilder().add(t))); + Optional.ofNullable(extractTag(s)).ifPresent(t -> builder.add("tags", Json.createArrayBuilder().add(t))); - return methodDescription; + return builder; } private JsonArrayBuilder buildParameters(final ResourceMethod method) { diff --git a/src/main/java/com/sebastian_daschner/jaxrs_analyzer/model/JavaUtils.java b/src/main/java/com/sebastian_daschner/jaxrs_analyzer/model/JavaUtils.java index dbc5740..6346599 100644 --- a/src/main/java/com/sebastian_daschner/jaxrs_analyzer/model/JavaUtils.java +++ b/src/main/java/com/sebastian_daschner/jaxrs_analyzer/model/JavaUtils.java @@ -27,6 +27,7 @@ import java.lang.reflect.Method; import java.lang.reflect.TypeVariable; import java.util.*; +import java.util.stream.Collectors; import java.util.stream.Stream; import static com.sebastian_daschner.jaxrs_analyzer.model.Types.*; @@ -397,6 +398,11 @@ public static Method findMethod(final Class loadedClass, final String methodN ).findAny().orElse(null); } + public static String getMethodSignature(final String returnType, final String... parameterTypes) { + final String parameters = Stream.of(parameterTypes).collect(Collectors.joining()); + return '(' + parameters + ')' + returnType; + } + public static String getMethodSignature(final Method method) { try { final Field signatureField = method.getClass().getDeclaredField("signature"); diff --git a/src/main/java/com/sebastian_daschner/jaxrs_analyzer/model/rest/ResourceMethod.java b/src/main/java/com/sebastian_daschner/jaxrs_analyzer/model/rest/ResourceMethod.java index d37e73e..d9163d9 100644 --- a/src/main/java/com/sebastian_daschner/jaxrs_analyzer/model/rest/ResourceMethod.java +++ b/src/main/java/com/sebastian_daschner/jaxrs_analyzer/model/rest/ResourceMethod.java @@ -29,13 +29,15 @@ public class ResourceMethod { private final Set responseMediaTypes = new HashSet<>(); private final Map responses = new HashMap<>(); private final Set methodParameters = new HashSet<>(); + private final String description; private final HttpMethod method; private TypeIdentifier requestBody; - public ResourceMethod(final HttpMethod method) { + public ResourceMethod(final HttpMethod method, final String description) { Objects.requireNonNull(method); this.method = method; + this.description = description; } public HttpMethod getMethod() { @@ -66,6 +68,10 @@ public Map getResponses() { return responses; } + public String getDescription() { + return description; + } + @Override public boolean equals(final Object o) { if (this == o) return true; @@ -78,6 +84,7 @@ public boolean equals(final Object o) { if (!responses.equals(that.responses)) return false; if (!methodParameters.equals(that.methodParameters)) return false; if (method != that.method) return false; + if (description != null ? !description.equals(that.description) : that.description != null) return false; return requestBody != null ? requestBody.equals(that.requestBody) : that.requestBody == null; } @@ -89,6 +96,7 @@ public int hashCode() { result = 31 * result + responses.hashCode(); result = 31 * result + methodParameters.hashCode(); result = 31 * result + method.hashCode(); + result = 31 * result + (description != null ? description.hashCode() : 0); result = 31 * result + (requestBody != null ? requestBody.hashCode() : 0); return result; } @@ -101,6 +109,7 @@ public String toString() { ", responseMediaTypes=" + responseMediaTypes + ", responses=" + responses + ", methodParameters=" + methodParameters + + ", description=" + description + ", requestBody=" + requestBody + '}'; } diff --git a/src/main/java/com/sebastian_daschner/jaxrs_analyzer/model/results/MethodResult.java b/src/main/java/com/sebastian_daschner/jaxrs_analyzer/model/results/MethodResult.java index 830e185..5ebc037 100644 --- a/src/main/java/com/sebastian_daschner/jaxrs_analyzer/model/results/MethodResult.java +++ b/src/main/java/com/sebastian_daschner/jaxrs_analyzer/model/results/MethodResult.java @@ -20,6 +20,7 @@ import com.sebastian_daschner.jaxrs_analyzer.model.instructions.Instruction; import com.sebastian_daschner.jaxrs_analyzer.model.rest.HttpMethod; import com.sebastian_daschner.jaxrs_analyzer.model.rest.MethodParameter; +import com.sun.javadoc.MethodDoc; import java.util.ArrayList; import java.util.HashSet; @@ -44,6 +45,7 @@ public class MethodResult { private HttpMethod httpMethod; private ClassResult subResource; private ClassResult parentResource; + private MethodDoc methodDoc; public Set getRequestMediaTypes() { return requestMediaTypes; @@ -114,6 +116,14 @@ public void setParentResource(final ClassResult parentResource) { this.parentResource = parentResource; } + public MethodDoc getMethodDoc() { + return methodDoc; + } + + public void setMethodDoc(final MethodDoc methodDoc) { + this.methodDoc = methodDoc; + } + @Override public boolean equals(final Object o) { if (this == o) return true; @@ -132,6 +142,7 @@ public boolean equals(final Object o) { return false; if (httpMethod != that.httpMethod) return false; if (subResource != null ? !subResource.equals(that.subResource) : that.subResource != null) return false; + if (methodDoc != null ? !methodDoc.equals(that.methodDoc) : that.methodDoc != null) return false; return true; } @@ -146,6 +157,7 @@ public int hashCode() { result = 31 * result + (requestBodyType != null ? requestBodyType.hashCode() : 0); result = 31 * result + (httpMethod != null ? httpMethod.hashCode() : 0); result = 31 * result + (subResource != null ? subResource.hashCode() : 0); + result = 31 * result + (methodDoc != null ? methodDoc.hashCode() : 0); return result; } @@ -161,6 +173,7 @@ public String toString() { ", requestBodyType='" + requestBodyType + '\'' + ", httpMethod=" + httpMethod + ", subResource=" + subResource + + ", methodDoc=" + methodDoc + ", parentResource=" + (parentResource == null ? "null" : "notNull") + '}'; } diff --git a/src/test/java/com/sebastian_daschner/jaxrs_analyzer/analysis/ProjectAnalyzerTest.java b/src/test/java/com/sebastian_daschner/jaxrs_analyzer/analysis/ProjectAnalyzerTest.java index 32611f0..42fb529 100644 --- a/src/test/java/com/sebastian_daschner/jaxrs_analyzer/analysis/ProjectAnalyzerTest.java +++ b/src/test/java/com/sebastian_daschner/jaxrs_analyzer/analysis/ProjectAnalyzerTest.java @@ -35,7 +35,7 @@ import java.util.*; import java.util.stream.Stream; -import static java.util.Collections.singletonList; +import static java.util.Collections.*; import static org.junit.Assert.*; public class ProjectAnalyzerTest { @@ -58,13 +58,13 @@ public void setUp() throws MalformedURLException { assertTrue("Could not compile test project", compilationTask.call()); path = Paths.get(testClassPath).toAbsolutePath(); - classUnderTest = new ProjectAnalyzer(path); + classUnderTest = new ProjectAnalyzer(singleton(path)); } @Test public void test() { final long startTime = System.currentTimeMillis(); - final Resources actualResources = classUnderTest.analyze(path); + final Resources actualResources = classUnderTest.analyze(singleton(path), emptySet()); System.out.println("Project analysis took " + (System.currentTimeMillis() - startTime) + " ms"); final Resources expectedResources = getResources(); @@ -76,7 +76,7 @@ public void test() { } private static void assertResourceEquals(final Resources expectedResources, final Resources actualResources) { - actualResources.getResources().stream().forEach(r -> { + actualResources.getResources().forEach(r -> { final Set expectedMethods = expectedResources.getMethods(r); final Set actualMethods = actualResources.getMethods(r); final String resourceText = "Compared resource " + r; diff --git a/src/test/java/com/sebastian_daschner/jaxrs_analyzer/builder/ResourceMethodBuilder.java b/src/test/java/com/sebastian_daschner/jaxrs_analyzer/builder/ResourceMethodBuilder.java index 174d68c..c0f7013 100644 --- a/src/test/java/com/sebastian_daschner/jaxrs_analyzer/builder/ResourceMethodBuilder.java +++ b/src/test/java/com/sebastian_daschner/jaxrs_analyzer/builder/ResourceMethodBuilder.java @@ -25,7 +25,7 @@ public class ResourceMethodBuilder { private final ResourceMethod method; private ResourceMethodBuilder(final HttpMethod method) { - this.method = new ResourceMethod(method); + this.method = new ResourceMethod(method, null); } public static ResourceMethodBuilder withMethod(final HttpMethod method) {