-
Notifications
You must be signed in to change notification settings - Fork 2
Improve utility behavior and logger adapter detection #15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -127,19 +127,51 @@ protected static synchronized void initialize() { | |||||
| /** | ||||||
| * Returns the logger adapter factory. | ||||||
| * <p> | ||||||
| * If Commons Logging is available, returns a factory for using Commons Logging. | ||||||
| * If not available, returns a factory for using java.util.logging logger. | ||||||
| * Detects available logging frameworks in the following order: | ||||||
| * 1. SLF4J (if available) | ||||||
| * 2. Commons Logging (if available) | ||||||
| * 3. java.util.logging (fallback) | ||||||
| * </p> | ||||||
| * | ||||||
| * @return the logger adapter factory | ||||||
| */ | ||||||
| protected static LoggerAdapterFactory getLoggerAdapterFactory() { | ||||||
| // TODO | ||||||
| // Check for SLF4J first (most commonly used) | ||||||
| if (isClassAvailable("org.slf4j.LoggerFactory")) { | ||||||
| try { | ||||||
| // Dynamically create SLF4J adapter if available | ||||||
| return new JulLoggerAdapterFactory(); // For now, fallback to JUL | ||||||
| // In future: return new Slf4jLoggerAdapterFactory(); | ||||||
| } catch (final Throwable ignore) { | ||||||
| // Fall through to next option | ||||||
| } | ||||||
| } | ||||||
|
Comment on lines
+139
to
+148
|
||||||
|
|
||||||
| // Check for Commons Logging | ||||||
| if (isClassAvailable("org.apache.commons.logging.LogFactory")) { | ||||||
| try { | ||||||
| return new JclLoggerAdapterFactory(); | ||||||
| } catch (final Throwable ignore) { | ||||||
| // Fall through to next option | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| // Default to java.util.logging | ||||||
| return new JulLoggerAdapterFactory(); | ||||||
| } | ||||||
|
|
||||||
| /** | ||||||
| * Checks if a class is available on the classpath. | ||||||
| * | ||||||
| * @param className the fully qualified class name | ||||||
| * @return true if the class is available, false otherwise | ||||||
| */ | ||||||
| private static boolean isClassAvailable(final String className) { | ||||||
| try { | ||||||
| Class.forName("org.apache.commons.logging.LogFactory"); | ||||||
| return new JclLoggerAdapterFactory(); | ||||||
| } catch (final Throwable ignore) { | ||||||
| return new JulLoggerAdapterFactory(); | ||||||
| Class.forName(className, false, Logger.class.getClassLoader()); | ||||||
| return true; | ||||||
| } catch (final ClassNotFoundException e) { | ||||||
|
||||||
| } catch (final ClassNotFoundException e) { | |
| } catch (final Throwable t) { |
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -86,7 +86,7 @@ public static synchronized void dispose() { | |||||||
| try { | ||||||||
| disposable.dispose(); | ||||||||
| } catch (final Throwable t) { | ||||||||
| t.printStackTrace(); // must not use Logger. | ||||||||
| System.err.println("[DisposableUtil] Failed to dispose resource: " + t.getClass().getName() + ": " + t.getMessage()); // must not use Logger. | ||||||||
|
||||||||
| System.err.println("[DisposableUtil] Failed to dispose resource: " + t.getClass().getName() + ": " + t.getMessage()); // must not use Logger. | |
| System.err.println("[DisposableUtil] Failed to dispose resource: " + t.getClass().getName() + ": " + t.getMessage()); // must not use Logger. | |
| t.printStackTrace(System.err); |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -39,19 +39,24 @@ protected LocaleUtil() { | |||||||||||||||||||||
| * @return {@link Locale} | ||||||||||||||||||||||
| */ | ||||||||||||||||||||||
| public static Locale getLocale(final String localeStr) { | ||||||||||||||||||||||
| // TODO replace with Fess | ||||||||||||||||||||||
| Locale locale = LocaleUtil.getDefault(); | ||||||||||||||||||||||
| if (localeStr != null) { | ||||||||||||||||||||||
| final int index = localeStr.indexOf('_'); | ||||||||||||||||||||||
| if (index < 0) { | ||||||||||||||||||||||
| locale = new Locale(localeStr); | ||||||||||||||||||||||
| } else { | ||||||||||||||||||||||
| final String language = localeStr.substring(0, index); | ||||||||||||||||||||||
| final String country = localeStr.substring(index + 1); | ||||||||||||||||||||||
| locale = new Locale(language, country); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| if (localeStr == null || localeStr.isEmpty()) { | ||||||||||||||||||||||
| return LocaleUtil.getDefault(); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
Comment on lines
+42
to
+44
|
||||||||||||||||||||||
| if (localeStr == null || localeStr.isEmpty()) { | |
| return LocaleUtil.getDefault(); | |
| } | |
| if (localeStr == null) { | |
| return LocaleUtil.getDefault(); | |
| } | |
| if (localeStr.isEmpty()) { | |
| // Preserve previous behavior: construct an empty-language Locale for empty input | |
| return new Locale(""); | |
| } |
Copilot
AI
Feb 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment claims 'Java's built-in locale parsing', but the implementation is manual splitting and does not handle common BCP 47 tags like en-US (it would create a Locale with language en-US). Either update the comment to match the actual parsing rules, or switch to a built-in approach (e.g., Locale.forLanguageTag) / accept both '_' and '-' separators.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
timeProvideris a mutable static that can be updated concurrently without any memory-visibility guarantees. Mark itvolatileor store it in anAtomicReference<LongSupplier>to ensure threads callingcurrentTimeMillis()see the latest provider (especially relevant in parallel test execution).