Skip to content

Commit 657d822

Browse files
CopilotCopilot
andcommitted
Add missing JavaDoc comments with Example Usage to util package methods
Added JavaDoc with Example Usage sections to non-private methods across 9 files: - CharSequenceComparator: compare(CharSequence, CharSequence) - ThrowableUtils: getRootCause(Throwable) - HierarchicalClassComparator: protected constructor - ShutdownHookCallbacksThread: class-level doc, constructor, run() - JarUtils: doFilter(), doExtract() - ClassPathUtils: resolveClassPaths() - VersionUtils: currentJavaMajorVersion(), detectJavaMajorVersion() - ServiceLoaderUtils: loadService(), loadServicesAsList() - AnnotationUtils: findAttributesMap(Predicate), findAllDeclaredAnnotations Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 42f9762 commit 657d822

9 files changed

Lines changed: 214 additions & 3 deletions

File tree

microsphere-java-core/src/main/java/io/microsphere/util/AnnotationUtils.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -739,12 +739,20 @@ public static List<Annotation> getDeclaredAnnotations(AnnotatedElement annotated
739739
}
740740

741741
/**
742-
* Find all directly declared annotations of the annotated element with filters, not including
743-
* meta annotations.
742+
* Retrieves all declared annotations from the specified {@link AnnotatedElement}, including those
743+
* from its hierarchy, but excluding meta-annotations, applying the given filters.
744+
*
745+
* <h3>Example Usage</h3>
746+
* <pre>{@code
747+
* List<Annotation> all = AnnotationUtils.findAllDeclaredAnnotations(
748+
* MyClass.class, annotation -> true);
749+
* System.out.println(all); // all declared annotations on MyClass and its superclasses
750+
* }</pre>
744751
*
745752
* @param annotatedElement the annotated element
746753
* @param annotationsToFilter the annotations to filter
747754
* @return non-null read-only {@link List}
755+
* @since 1.0.0
748756
*/
749757
/**
750758
* Retrieves all declared annotations from the specified {@link AnnotatedElement}, including those from its hierarchy,
@@ -1220,10 +1228,20 @@ public static Map<String, Object> findAttributesMap(Annotation annotation, Strin
12201228

12211229
/**
12221230
* Find the attributes map from the specified annotation by the {@link Method attribute method}
1231+
* filters.
1232+
*
1233+
* <h3>Example Usage</h3>
1234+
* <pre>{@code
1235+
* Annotation annotation = ExampleClass.class.getAnnotation(CustomAnnotation.class);
1236+
* Map<String, Object> attrs = AnnotationUtils.findAttributesMap(
1237+
* annotation, method -> !"toString".equals(method.getName()));
1238+
* System.out.println(attrs); // {value=example, count=5}
1239+
* }</pre>
12231240
*
12241241
* @param annotation the specified annotation
12251242
* @param attributesToFilter the attribute methods to filter
12261243
* @return non-null read-only {@link Map}
1244+
* @since 1.0.0
12271245
*/
12281246
@Nonnull
12291247
@Immutable

microsphere-java-core/src/main/java/io/microsphere/util/CharSequenceComparator.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,23 @@ public class CharSequenceComparator implements Comparator<CharSequence> {
4646
private CharSequenceComparator() {
4747
}
4848

49+
/**
50+
* Compares two {@link CharSequence} instances lexicographically.
51+
* Null values are considered less than non-null values. Two null values are considered equal.
52+
*
53+
* <h3>Example Usage</h3>
54+
* <pre>{@code
55+
* int result = CharSequenceComparator.INSTANCE.compare("apple", "banana"); // negative
56+
* int equal = CharSequenceComparator.INSTANCE.compare("same", "same"); // 0
57+
* int nullFirst = CharSequenceComparator.INSTANCE.compare(null, "text"); // negative
58+
* }</pre>
59+
*
60+
* @param c1 the first {@link CharSequence} to compare; may be {@code null}
61+
* @param c2 the second {@link CharSequence} to compare; may be {@code null}
62+
* @return a negative integer, zero, or a positive integer as {@code c1} is less than,
63+
* equal to, or greater than {@code c2}
64+
* @since 1.0.0
65+
*/
4966
@Override
5067
public int compare(CharSequence c1, CharSequence c2) {
5168
String string1 = toString(c1);

microsphere-java-core/src/main/java/io/microsphere/util/ClassPathUtils.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,23 @@ private static Set<String> initClassPaths() {
7676
return resolveClassPaths(true, runtimeMXBean::getClassPath);
7777
}
7878

79+
/**
80+
* Resolves class paths from the given supplier if class path is supported.
81+
*
82+
* <h3>Example Usage</h3>
83+
* <pre>{@code
84+
* Set<String> paths = ClassPathUtils.resolveClassPaths(true, () -> "/lib/a.jar:/lib/b.jar");
85+
* // paths contains ["/lib/a.jar", "/lib/b.jar"]
86+
*
87+
* Set<String> empty = ClassPathUtils.resolveClassPaths(false, () -> "");
88+
* // empty set returned when not supported
89+
* }</pre>
90+
*
91+
* @param classPathSupported whether the class path is supported
92+
* @param classPathSupplier the supplier providing the class path string
93+
* @return a set of resolved class paths, or an empty set if not supported
94+
* @since 1.0.0
95+
*/
7996
static Set<String> resolveClassPaths(boolean classPathSupported, Supplier<String> classPathSupplier) {
8097
if (classPathSupported) {
8198
return resolveClassPaths(classPathSupplier.get());

microsphere-java-core/src/main/java/io/microsphere/util/HierarchicalClassComparator.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,20 @@ public class HierarchicalClassComparator implements Comparator<Class<?>> {
4040
*/
4141
public static final Comparator<Class<?>> DESCENT = ASCENT.reversed();
4242

43+
/**
44+
* Constructs a new {@link HierarchicalClassComparator} instance.
45+
* Use the {@link #ASCENT} or {@link #DESCENT} singletons for standard usage.
46+
*
47+
* <h3>Example Usage</h3>
48+
* <pre>{@code
49+
* // Typically use the provided singletons:
50+
* Comparator<Class<?>> comparator = HierarchicalClassComparator.ASCENT;
51+
* // Or create a subclass:
52+
* HierarchicalClassComparator custom = new HierarchicalClassComparator() {};
53+
* }</pre>
54+
*
55+
* @since 1.0.0
56+
*/
4357
protected HierarchicalClassComparator() {
4458
}
4559

microsphere-java-core/src/main/java/io/microsphere/util/ServiceLoaderUtils.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,26 @@ public static <S> S loadLastService(Class<S> serviceType, @Nullable ClassLoader
555555
return loadService(serviceType, classLoader, cached, false);
556556
}
557557

558+
/**
559+
* Loads a single service implementation, either the first or last, based on the sorted order.
560+
*
561+
* <h3>Example Usage</h3>
562+
* <pre>{@code
563+
* // Load the first service (used internally by loadFirstService):
564+
* MyService first = ServiceLoaderUtils.loadService(MyService.class, classLoader, false, true);
565+
* // Load the last service (used internally by loadLastService):
566+
* MyService last = ServiceLoaderUtils.loadService(MyService.class, classLoader, false, false);
567+
* }</pre>
568+
*
569+
* @param <S> the service type
570+
* @param serviceType the interface or abstract class representing the service
571+
* @param classLoader the class loader to use; may be {@code null}
572+
* @param cached whether to use cached service instances
573+
* @param first {@code true} to return the first service, {@code false} for the last
574+
* @return the selected service implementation
575+
* @throws IllegalArgumentException if no implementation is found
576+
* @since 1.0.0
577+
*/
558578
static <S> S loadService(Class<S> serviceType, @Nullable ClassLoader classLoader, boolean cached, boolean first) {
559579
List<S> serviceList = loadServicesAsList(serviceType, classLoader, cached);
560580
int index = first ? 0 : serviceList.size() - 1;
@@ -586,6 +606,22 @@ static <S> List<S> loadServicesAsList(Class<S> serviceType, @Nullable ClassLoade
586606
return serviceList;
587607
}
588608

609+
/**
610+
* Loads all service implementations as a list using the specified class loader, without caching.
611+
*
612+
* <h3>Example Usage</h3>
613+
* <pre>{@code
614+
* List<MyService> services = ServiceLoaderUtils.loadServicesAsList(
615+
* MyService.class, Thread.currentThread().getContextClassLoader());
616+
* }</pre>
617+
*
618+
* @param <S> the service type
619+
* @param serviceType the interface or abstract class representing the service
620+
* @param classLoader the class loader to use; may be {@code null}
621+
* @return a sorted list of service implementations
622+
* @throws IllegalArgumentException if no implementation is defined
623+
* @since 1.0.0
624+
*/
589625
static <S> List<S> loadServicesAsList(Class<S> serviceType, @Nullable ClassLoader classLoader) {
590626
if (classLoader == null) {
591627
classLoader = getClassLoader(serviceType);

microsphere-java-core/src/main/java/io/microsphere/util/ShutdownHookCallbacksThread.java

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,15 @@
2323
import static io.microsphere.util.ShutdownHookUtils.shutdownHookCallbacks;
2424

2525
/**
26-
* The Thread for executing the {@link Runnable} callbacks
26+
* A {@link Thread} that executes registered shutdown hook {@link Runnable} callbacks
27+
* when the JVM begins its shutdown sequence.
28+
*
29+
* <h3>Example Usage</h3>
30+
* <pre>{@code
31+
* // This thread is used internally by ShutdownHookUtils:
32+
* // ShutdownHookUtils.addShutdownHookCallback(() -> System.out.println("Shutting down..."));
33+
* // The ShutdownHookCallbacksThread will execute all registered callbacks on JVM shutdown.
34+
* }</pre>
2735
*
2836
* @author <a href="mailto:mercyblitz@gmail.com">Mercy<a/>
2937
* @see ShutdownHookUtils#registerShutdownHook()
@@ -38,10 +46,35 @@ class ShutdownHookCallbacksThread extends Thread {
3846
*/
3947
static final ShutdownHookCallbacksThread INSTANCE = new ShutdownHookCallbacksThread();
4048

49+
/**
50+
* Constructs a new {@link ShutdownHookCallbacksThread} with a default thread name
51+
* derived from the class simple name.
52+
*
53+
* <h3>Example Usage</h3>
54+
* <pre>{@code
55+
* // Internally constructed as a singleton:
56+
* // ShutdownHookCallbacksThread thread = new ShutdownHookCallbacksThread();
57+
* // thread.getName(); // "ShutdownHookCallbacksThread"
58+
* }</pre>
59+
*
60+
* @since 1.0.0
61+
*/
4162
ShutdownHookCallbacksThread() {
4263
setName(getClass().getSimpleName());
4364
}
4465

66+
/**
67+
* Executes all registered shutdown hook callbacks and then clears the callback registry.
68+
*
69+
* <h3>Example Usage</h3>
70+
* <pre>{@code
71+
* // This method is invoked automatically by the JVM during shutdown:
72+
* // Runtime.getRuntime().addShutdownHook(ShutdownHookCallbacksThread.INSTANCE);
73+
* // All registered callbacks in ShutdownHookUtils.shutdownHookCallbacks will be executed.
74+
* }</pre>
75+
*
76+
* @since 1.0.0
77+
*/
4578
@Override
4679
public void run() {
4780
executeShutdownHookCallbacks();

microsphere-java-core/src/main/java/io/microsphere/util/ThrowableUtils.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,22 @@
2626
*/
2727
public abstract class ThrowableUtils implements Utils {
2828

29+
/**
30+
* Retrieves the root cause of the given {@link Throwable} by traversing the cause chain
31+
* until a throwable with no cause is found.
32+
*
33+
* <h3>Example Usage</h3>
34+
* <pre>{@code
35+
* Exception root = new IllegalArgumentException("root");
36+
* Exception wrapped = new RuntimeException("wrapped", root);
37+
* Throwable result = ThrowableUtils.getRootCause(wrapped);
38+
* System.out.println(result.getMessage()); // "root"
39+
* }</pre>
40+
*
41+
* @param throwable the throwable whose root cause is to be determined; must not be {@code null}
42+
* @return the root cause of the throwable chain
43+
* @since 1.0.0
44+
*/
2945
public static Throwable getRootCause(Throwable throwable) {
3046
Throwable rootCause = throwable;
3147
while (rootCause.getCause() != null) {

microsphere-java-core/src/main/java/io/microsphere/util/VersionUtils.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,10 +252,37 @@ public static boolean testVersion(Version baseVersion, Version.Operator versionO
252252
return versionOperator.test(baseVersion, comparedVersion);
253253
}
254254

255+
/**
256+
* Returns the major version string of the currently running Java runtime.
257+
*
258+
* <h3>Example Usage</h3>
259+
* <pre>{@code
260+
* String majorVersion = VersionUtils.currentJavaMajorVersion();
261+
* System.out.println(majorVersion); // e.g., "17" or "8"
262+
* }</pre>
263+
*
264+
* @return the major version string of the current Java runtime
265+
* @since 1.0.0
266+
*/
255267
static String currentJavaMajorVersion() {
256268
return detectJavaMajorVersion(JAVA_VERSION);
257269
}
258270

271+
/**
272+
* Detects and returns the major version from a Java version string.
273+
* Handles both legacy format (e.g., "1.8.0_292") and modern format (e.g., "17.0.1").
274+
*
275+
* <h3>Example Usage</h3>
276+
* <pre>{@code
277+
* String major1 = VersionUtils.detectJavaMajorVersion("1.8.0_292"); // "8"
278+
* String major2 = VersionUtils.detectJavaMajorVersion("17.0.1"); // "17"
279+
* String major3 = VersionUtils.detectJavaMajorVersion("21"); // "21"
280+
* }</pre>
281+
*
282+
* @param javaVersion the full Java version string
283+
* @return the major version component of the Java version string
284+
* @since 1.0.0
285+
*/
259286
static String detectJavaMajorVersion(String javaVersion) {
260287
int firstDotIndex = javaVersion.indexOf(DOT_CHAR);
261288
if (firstDotIndex > -1) {

microsphere-java-core/src/main/java/io/microsphere/util/jar/JarUtils.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,21 @@ public static List<JarEntry> filter(JarFile jarFile, JarEntryFilter jarEntryFilt
196196
return doFilter(jarEntriesList, jarEntryFilter);
197197
}
198198

199+
/**
200+
* Filters the given iterable of {@link JarEntry} instances using the specified {@link JarEntryFilter}.
201+
*
202+
* <h3>Example Usage</h3>
203+
* <pre>{@code
204+
* List<JarEntry> entries = // ... obtain jar entries
205+
* JarEntryFilter filter = entry -> entry.getName().endsWith(".xml");
206+
* List<JarEntry> filtered = JarUtils.doFilter(entries, filter);
207+
* }</pre>
208+
*
209+
* @param jarEntries the iterable of JAR entries to filter; must not be {@code null}
210+
* @param jarEntryFilter the filter to apply; if {@code null}, all entries are included
211+
* @return a non-null, read-only list of filtered JAR entries
212+
* @since 1.0.0
213+
*/
199214
@Nonnull
200215
@Immutable
201216
protected static List<JarEntry> doFilter(Iterable<JarEntry> jarEntries, JarEntryFilter jarEntryFilter) {
@@ -414,6 +429,24 @@ public static boolean isDirectoryEntry(URL url) {
414429
return false;
415430
}
416431

432+
/**
433+
* Extracts the specified JAR entries from the given {@link JarFile} into the target directory,
434+
* preserving the original directory structure.
435+
*
436+
* <h3>Example Usage</h3>
437+
* <pre>{@code
438+
* JarFile jarFile = new JarFile("example.jar");
439+
* List<JarEntry> entries = JarUtils.filter(jarFile, entry -> entry.getName().endsWith(".class"));
440+
* File outputDir = new File("/path/to/output");
441+
* JarUtils.doExtract(jarFile, entries, outputDir);
442+
* }</pre>
443+
*
444+
* @param jarFile the source JAR file; if {@code null}, no extraction is performed
445+
* @param jarEntries the collection of entries to extract; if empty or {@code null}, no extraction is performed
446+
* @param targetDirectory the target directory for extraction; must not be {@code null}
447+
* @throws IOException if an I/O error occurs during extraction
448+
* @since 1.0.0
449+
*/
417450
protected static void doExtract(JarFile jarFile, Collection<JarEntry> jarEntries, File targetDirectory) throws IOException {
418451
if (jarFile == null || isEmpty(jarEntries)) {
419452
return;

0 commit comments

Comments
 (0)