From fcf7e3d722e55524e5c178363e789c7374aa15b0 Mon Sep 17 00:00:00 2001 From: Martin Wiesner Date: Mon, 25 Nov 2024 21:10:49 +0100 Subject: [PATCH] OPENNLP-1658: Enhance JavaDoc of code in opennlp-tools-models (#696) --- .../models/AbstractClassPathModelFinder.java | 15 +++--- .../opennlp/tools/models/ClassPathModel.java | 16 ++++++ .../tools/models/ClassPathModelEntry.java | 7 +++ .../tools/models/ClassPathModelFinder.java | 5 +- .../tools/models/ClassPathModelLoader.java | 4 +- .../classgraph/ClassgraphModelFinder.java | 17 +++++-- .../simple/SimpleClassPathModelFinder.java | 49 +++++++++++-------- 7 files changed, 77 insertions(+), 36 deletions(-) diff --git a/opennlp-tools-models/src/main/java/opennlp/tools/models/AbstractClassPathModelFinder.java b/opennlp-tools-models/src/main/java/opennlp/tools/models/AbstractClassPathModelFinder.java index eeaa43d90..ea2b4c4c1 100644 --- a/opennlp-tools-models/src/main/java/opennlp/tools/models/AbstractClassPathModelFinder.java +++ b/opennlp-tools-models/src/main/java/opennlp/tools/models/AbstractClassPathModelFinder.java @@ -36,7 +36,7 @@ public abstract class AbstractClassPathModelFinder implements ClassPathModelFind private Set models; /** - * By default, it scans for "opennlp-models-*.jar". + * By default, it scans for {@link #OPENNLP_MODEL_JAR_PREFIX}. */ public AbstractClassPathModelFinder() { this(OPENNLP_MODEL_JAR_PREFIX); @@ -47,7 +47,7 @@ public AbstractClassPathModelFinder() { * May contain a wildcard glob ("opennlp-*.jar"). It must not be {@code null}. */ public AbstractClassPathModelFinder(String jarModelPrefix) { - Objects.requireNonNull(jarModelPrefix, "modelJarPrefix must not be null"); + Objects.requireNonNull(jarModelPrefix, "jarModelPrefix must not be null"); this.jarModelPrefix = jarModelPrefix; } @@ -76,19 +76,20 @@ public Set findModels(boolean reloadCache) { } /** + * @apiNote * Subclasses can implement this method to provide additional context to * {@link AbstractClassPathModelFinder#getMatchingURIs(String, Object)}. * - * @return a context information. May be {@code null}. + * @return A context information object. May be {@code null}. */ protected abstract Object getContext(); /** - * Return matching classpath URIs for the given pattern. + * Retrieve matching classpath {@link URI URIs} for the given {@code wildcardPattern}. * - * @param wildcardPattern the pattern. Must not be {@code null}. - * @param context an object holding context information. It might be {@code null}. - * @return a list of matching classpath URIs. + * @param wildcardPattern The pattern to use for scanning. Must not be {@code null}. + * @param context An object holding context information. It might be {@code null}. + * @return A list of matching classpath URIs. */ protected abstract List getMatchingURIs(String wildcardPattern, Object context); diff --git a/opennlp-tools-models/src/main/java/opennlp/tools/models/ClassPathModel.java b/opennlp-tools-models/src/main/java/opennlp/tools/models/ClassPathModel.java index 97c214388..f22fb9016 100644 --- a/opennlp-tools-models/src/main/java/opennlp/tools/models/ClassPathModel.java +++ b/opennlp-tools-models/src/main/java/opennlp/tools/models/ClassPathModel.java @@ -20,18 +20,34 @@ public record ClassPathModel(Properties properties, byte[] model) { + /** + * @return Retrieves the value of the {@code model.version} property + * or {@code "unknown"} if it could not be read. + */ public String getModelVersion() { return properties != null ? properties.getProperty("model.version", "unknown") : "unknown"; } + /** + * @return Retrieves the value of the {@code model.name} property + * or {@code "unknown"} if it could not be read. + */ public String getModelName() { return properties != null ? properties.getProperty("model.name", "unknown") : "unknown"; } + /** + * @return Retrieves the value of the {@code model.sha256} property + * or {@code "unknown"} if it could not be read. + */ public String getModelSHA256() { return properties != null ? properties.getProperty("model.sha256", "unknown") : "unknown"; } + /** + * @return Retrieves the value of the {@code model.language} property + * or {@code "unknown"} if it could not be read. + */ public String getModelLanguage() { return properties != null ? properties.getProperty("model.language", "unknown") : "unknown"; } diff --git a/opennlp-tools-models/src/main/java/opennlp/tools/models/ClassPathModelEntry.java b/opennlp-tools-models/src/main/java/opennlp/tools/models/ClassPathModelEntry.java index ef09f4143..7a34432e4 100644 --- a/opennlp-tools-models/src/main/java/opennlp/tools/models/ClassPathModelEntry.java +++ b/opennlp-tools-models/src/main/java/opennlp/tools/models/ClassPathModelEntry.java @@ -19,6 +19,13 @@ import java.net.URI; import java.util.Optional; +/** + * Encapsulates a classpath entry that is associated with an {@link URI model URI} + * and optional {@code properties}. + * + * @param model A valid {@link URI} associated with the model's location. + * @param properties Optional properties to use. + */ public record ClassPathModelEntry(URI model, Optional properties) { } diff --git a/opennlp-tools-models/src/main/java/opennlp/tools/models/ClassPathModelFinder.java b/opennlp-tools-models/src/main/java/opennlp/tools/models/ClassPathModelFinder.java index 5603d325b..6b0358ff0 100644 --- a/opennlp-tools-models/src/main/java/opennlp/tools/models/ClassPathModelFinder.java +++ b/opennlp-tools-models/src/main/java/opennlp/tools/models/ClassPathModelFinder.java @@ -25,8 +25,9 @@ public interface ClassPathModelFinder { /** * Finds OpenNLP models within the classpath. * - * @param reloadCache {@code true}, if the internal cache should explicitly be reloaded - * @return A Set of {@link ClassPathModelEntry ClassPathModelEntries}. It might be empty. + * @param reloadCache {@code true}, if the internal cache should explicitly be reloaded, + * {@code false} otherwise. + * @return A Set of {@link ClassPathModelEntry model entries}. It might be empty if none were found. */ Set findModels(boolean reloadCache); } diff --git a/opennlp-tools-models/src/main/java/opennlp/tools/models/ClassPathModelLoader.java b/opennlp-tools-models/src/main/java/opennlp/tools/models/ClassPathModelLoader.java index a236fa346..1b67bb2d2 100644 --- a/opennlp-tools-models/src/main/java/opennlp/tools/models/ClassPathModelLoader.java +++ b/opennlp-tools-models/src/main/java/opennlp/tools/models/ClassPathModelLoader.java @@ -29,8 +29,8 @@ public class ClassPathModelLoader { /** * Loads a {@link ClassPathModel} from a {@link ClassPathModelEntry} * - * @param entry must not be {@code null}. - * @return a {@link ClassPathModel} containing the model resources. + * @param entry A valid {@link ClassPathModelEntry}, it must not be {@code null}. + * @return A {@link ClassPathModel} containing the model resources. * @throws IOException thrown if something went wrong during reading resources from the classpath. */ public ClassPathModel load(ClassPathModelEntry entry) throws IOException { diff --git a/opennlp-tools-models/src/main/java/opennlp/tools/models/classgraph/ClassgraphModelFinder.java b/opennlp-tools-models/src/main/java/opennlp/tools/models/classgraph/ClassgraphModelFinder.java index 642dc20be..13dae9215 100644 --- a/opennlp-tools-models/src/main/java/opennlp/tools/models/classgraph/ClassgraphModelFinder.java +++ b/opennlp-tools-models/src/main/java/opennlp/tools/models/classgraph/ClassgraphModelFinder.java @@ -31,6 +31,10 @@ * Enables the detection of OpenNLP models in the classpath via classgraph. * By default, this class will search for JAR files starting with "opennlp-models-*". * This wildcard pattern can be adjusted by using the alternative constructor of this class. + * + * @implNote This implementation relies on the Classgraph library. + * When using this class, you have to take care of Classgraph being in the classpath + * of your application, as it is declared as an optional dependency for opennlp-tools-models. */ public class ClassgraphModelFinder extends AbstractClassPathModelFinder implements ClassPathModelFinder { @@ -50,7 +54,9 @@ public ClassgraphModelFinder(String modelJarPrefix) { } /** - * @return a {@link ScanResult} ready for consumption. Caller is responsible for closing it. + * @apiNote The caller is responsible for closing it. + * + * @return A {@link ScanResult} ready for consumption. */ @Override protected Object getContext() { @@ -58,9 +64,11 @@ protected Object getContext() { } /** - * @param wildcardPattern the pattern. Must not be {@code null}. - * @param context an object holding context information. It might be {@code null}. - * @return a list of matching classpath uris. + * Attempts to obtain {@link URI URIs} from the classpath. + * + * @param wildcardPattern The pattern to use for scanning. Must not be {@code null}. + * @param context An object holding context information. It might be {@code null}. + * @return A list of matching classpath {@link URI URIs}. It may be empty if nothing is found. */ @Override protected List getMatchingURIs(String wildcardPattern, Object context) { @@ -71,5 +79,4 @@ protected List getMatchingURIs(String wildcardPattern, Object context) { } return Collections.emptyList(); } - } diff --git a/opennlp-tools-models/src/main/java/opennlp/tools/models/simple/SimpleClassPathModelFinder.java b/opennlp-tools-models/src/main/java/opennlp/tools/models/simple/SimpleClassPathModelFinder.java index 8e1589521..bfe9902ae 100644 --- a/opennlp-tools-models/src/main/java/opennlp/tools/models/simple/SimpleClassPathModelFinder.java +++ b/opennlp-tools-models/src/main/java/opennlp/tools/models/simple/SimpleClassPathModelFinder.java @@ -45,19 +45,25 @@ * Enables the detection of OpenNLP models in the classpath via JDK classes * By default, this class will search for JAR files starting with "opennlp-models-*". * This wildcard pattern can be adjusted by using the alternative constructor of this class. - *

+ * + * @implNote * It is a rather simple implementation of scanning the classpath by trying to obtain {@link URL urls} * from the actual classpath via a chain of possible options. It might not work for every use-case * since it relies on JDK internals only and doesn't account for classloader hierarchies or edge-cases. *

- * It will - * (1) Try to see if we have a {@link URLClassLoader} available in the current thread. - * (2) Try to obtain URLs via the build in classloader via reflections - * (requires {@code --add-opens java.base/jdk.internal.loader=ALL-UNNAMED} as JVM argument) - * (3) Try to use the bootstrap classpath via {@code java.class.path}. + * It will: + *

    + *
  1. Try to see if we have a {@link URLClassLoader} available in the current thread.
  2. + *
  3. Try to obtain URLs via the build in classloader via reflections. + *
    (requires {@code --add-opens java.base/jdk.internal.loader=ALL-UNNAMED} as JVM argument)
  4. + *
  5. Try to use the bootstrap classpath via {@code java.class.path}.
  6. + *
+ * *

- * If you need a more sophisticated solution, + * If you need a more sophisticated implementation, * use {@link opennlp.tools.models.classgraph.ClassgraphModelFinder}. + * + * @see ClassPathModelFinder */ public class SimpleClassPathModelFinder extends AbstractClassPathModelFinder implements ClassPathModelFinder { @@ -68,7 +74,7 @@ public class SimpleClassPathModelFinder extends AbstractClassPathModelFinder imp // ; for Windows, : for Linux/OSX /** - * By default, it scans for "opennlp-models-*.jar". + * By default, it scans for {@link #OPENNLP_MODEL_JAR_PREFIX}. */ public SimpleClassPathModelFinder() { this(OPENNLP_MODEL_JAR_PREFIX); @@ -83,7 +89,7 @@ public SimpleClassPathModelFinder(String modelJarPrefix) { } /** - * @return always {@code NULL} as it is not needed for the simple case. + * @return Always {@code null} as it is not needed for the simple case. */ @Override protected Object getContext() { @@ -91,10 +97,10 @@ protected Object getContext() { } /** - * @param wildcardPattern the pattern. Must not be {@code null}. - * @param context an object holding context information. + * @param wildcardPattern The pattern to use for scanning. Must not be {@code null}. + * @param context An object holding context information. It might be {@code null}. * It is unused within this implementation. - * @return a list of matching classpath uris. + * @return A list of matching classpath {@link URI URIs}. It may be an empty list if nothing is found. */ @Override protected List getMatchingURIs(String wildcardPattern, Object context) { @@ -126,10 +132,10 @@ protected List getMatchingURIs(String wildcardPattern, Object context) { } /** - * Escapes a wildcard expressions for usage as a Java regular expression. + * Escapes a {@code wildcard} expressions for usage as a Java regular expression. * - * @param wildcard must not be {@code null}. - * @return the escaped regex. + * @param wildcard A valid expression. It must not be {@code null}. + * @return The escaped regex. */ private String asRegex(String wildcard) { return wildcard @@ -173,13 +179,16 @@ private boolean isWindows() { } /** - * Try to obtain URLs from the classpath in the following order: + * Attempts to obtain {@link URL URLs} from the classpath in the following order: *

- * (1) Try to see if we have a {@link URLClassLoader}. - * (2) Try to obtain URLs via the build in classloader via reflections (requires an add opens JVM argument) - * (3) Try to use the bootstrap classpath via {@code java.class.path}. + *

    + *
  1. Try to see if we have a {@link URLClassLoader} available in the current thread.
  2. + *
  3. Try to obtain URLs via the build in classloader via reflections. + *
    (requires {@code --add-opens java.base/jdk.internal.loader=ALL-UNNAMED} as JVM argument)
  4. + *
  5. Try to use the bootstrap classpath via {@code java.class.path}.
  6. + *
* - * @return a list of URLs within the classpath. + * @return A list of {@link URL URLs} within the classpath. */ private List getClassPathElements() { final ClassLoader cl = Thread.currentThread().getContextClassLoader();