diff --git a/src/main/java/org/jboss/logmanager/configuration/ContextConfiguration.java b/src/main/java/org/jboss/logmanager/configuration/ContextConfiguration.java index 3fd831cc..6e9153f7 100644 --- a/src/main/java/org/jboss/logmanager/configuration/ContextConfiguration.java +++ b/src/main/java/org/jboss/logmanager/configuration/ContextConfiguration.java @@ -29,6 +29,7 @@ import java.util.logging.Formatter; import java.util.logging.Handler; +import org.jboss.logmanager.LogContext; import org.jboss.logmanager.Logger; /** @@ -47,8 +48,10 @@ * @author James R. Perkins */ @SuppressWarnings({ "UnusedReturnValue", "unused" }) -public class ContextConfiguration { +public class ContextConfiguration implements AutoCloseable { public static final Logger.AttachmentKey CONTEXT_CONFIGURATION_KEY = new Logger.AttachmentKey<>(); + private final LogContext context; + private final Map loggers; private final Map> errorManagers; private final Map> filters; private final Map> formatters; @@ -58,7 +61,9 @@ public class ContextConfiguration { /** * Creates a new context configuration. */ - public ContextConfiguration() { + public ContextConfiguration(final LogContext context) { + this.context = context; + loggers = new ConcurrentHashMap<>(); errorManagers = new ConcurrentHashMap<>(); handlers = new ConcurrentHashMap<>(); formatters = new ConcurrentHashMap<>(); @@ -66,6 +71,72 @@ public ContextConfiguration() { objects = new ConcurrentHashMap<>(); } + /** + * Returns the {@linkplain LogContext context} for this configuration. + * + * @return the context for this configuration + */ + public LogContext getContext() { + return context; + } + + /** + * Adds a logger to the context configuration. + * + * @param name the name of the logger + * @param logger the logger + * + * @return the previous logger or {@code null} if one did not exist + */ + public Logger addLogger(final String name, final Logger logger) { + if (logger == null) { + return loggers.remove(Objects.requireNonNull(name, "The name cannot be null")); + } + return loggers.put(Objects.requireNonNull(name, "The name cannot be null"), logger); + } + + /** + * Checks if the logger exists in this context. + * + * @param name the logger name + * + * @return {@code true} if the logger exists in this context, otherwise {@code false} + */ + public boolean hasLogger(final String name) { + return loggers.containsKey(Objects.requireNonNull(name, "The name cannot be null")); + } + + /** + * Gets the logger if it exists. + * + * @param name the name of the logger + * + * @return the logger or {@code null} if the logger does not exist + */ + public Logger getLogger(final String name) { + return loggers.get(Objects.requireNonNull(name, "The name cannot be null")); + } + + /** + * Returns an unmodifiable map of the loggers. + * + * @return an unmodified map of the loggers + */ + public Map getLoggers() { + return Collections.unmodifiableMap(loggers); + } + + /** + * Removes the logger from the context configuration. + * + * @param name the name of the logger + * + * @return the logger removed or {@code null} if the logger did not exist + */ + public Logger removeLogger(final String name) { + return loggers.remove(Objects.requireNonNull(name, "The name cannot be null")); + } + /** * Adds an error manager to the context configuration. * @@ -372,28 +443,15 @@ public Map> getObjects() { return Collections.unmodifiableMap(objects); } - private static class SingletonSupplier implements Supplier { - private final Supplier supplier; - private volatile T instance; - - private SingletonSupplier(final Supplier supplier) { - this.supplier = supplier; - } - - static Supplier of(final Supplier supplier) { - return new SingletonSupplier<>(supplier); - } - - @Override - public T get() { - if (instance == null) { - synchronized (this) { - if (instance == null) { - instance = supplier.get(); - } - } - } - return instance; - } + @Override + public void close() throws Exception { + context.close(); + loggers.clear(); + handlers.clear(); + filters.clear(); + formatters.clear(); + errorManagers.clear(); + objects.clear(); } + } diff --git a/src/main/java/org/jboss/logmanager/configuration/DefaultConfiguratorFactory.java b/src/main/java/org/jboss/logmanager/configuration/DefaultConfiguratorFactory.java index 561b44c6..6451fee8 100644 --- a/src/main/java/org/jboss/logmanager/configuration/DefaultConfiguratorFactory.java +++ b/src/main/java/org/jboss/logmanager/configuration/DefaultConfiguratorFactory.java @@ -33,7 +33,7 @@ public class DefaultConfiguratorFactory implements ConfiguratorFactory { @Override public LogContextConfigurator create() { - return new DefaultLogContextConfigurator(); + return new PropertyLogContextConfigurator(); } @Override diff --git a/src/main/java/org/jboss/logmanager/configuration/ObjectBuilder.java b/src/main/java/org/jboss/logmanager/configuration/ObjectBuilder.java index 70b55d02..76e54905 100644 --- a/src/main/java/org/jboss/logmanager/configuration/ObjectBuilder.java +++ b/src/main/java/org/jboss/logmanager/configuration/ObjectBuilder.java @@ -33,7 +33,6 @@ import java.util.logging.Level; import java.util.regex.Pattern; -import org.jboss.logmanager.LogContext; import org.jboss.modules.Module; import org.jboss.modules.ModuleLoader; @@ -44,8 +43,6 @@ */ @SuppressWarnings({ "UnusedReturnValue" }) class ObjectBuilder { - - private final LogContext logContext; private final ContextConfiguration contextConfiguration; private final Class baseClass; private final String className; @@ -55,9 +52,8 @@ class ObjectBuilder { private final Set postConstructMethods; private String moduleName; - private ObjectBuilder(final LogContext logContext, final ContextConfiguration contextConfiguration, + private ObjectBuilder(final ContextConfiguration contextConfiguration, final Class baseClass, final String className) { - this.logContext = logContext; this.contextConfiguration = contextConfiguration; this.baseClass = baseClass; this.className = className; @@ -70,16 +66,15 @@ private ObjectBuilder(final LogContext logContext, final ContextConfiguration co /** * Create a new {@link ObjectBuilder}. * - * @param logContext the log context being configured - * @param baseClass the base type - * @param className the name of the class to create - * @param the type being created + * @param baseClass the base type + * @param className the name of the class to create + * @param the type being created * * @return a new {@link ObjectBuilder} */ - static ObjectBuilder of(final LogContext logContext, final ContextConfiguration contextConfiguration, + static ObjectBuilder of(final ContextConfiguration contextConfiguration, final Class baseClass, final String className) { - return new ObjectBuilder<>(logContext, contextConfiguration, baseClass, className); + return new ObjectBuilder<>(contextConfiguration, baseClass, className); } /** @@ -272,39 +267,40 @@ private Object getValue(final Class objClass, final String propertyName, fina } return null; } + final var trimmedValue = value.trim(); if (paramType == String.class) { // Don't use the trimmed value for strings return value; } else if (paramType == java.util.logging.Level.class) { - return logContext.getLevelForName(value); + return contextConfiguration.getContext().getLevelForName(trimmedValue); } else if (paramType == java.util.logging.Logger.class) { - return logContext.getLogger(value); + return contextConfiguration.getContext().getLogger(trimmedValue); } else if (paramType == boolean.class || paramType == Boolean.class) { - return Boolean.valueOf(value); + return Boolean.valueOf(trimmedValue); } else if (paramType == byte.class || paramType == Byte.class) { - return Byte.valueOf(value); + return Byte.valueOf(trimmedValue); } else if (paramType == short.class || paramType == Short.class) { - return Short.valueOf(value); + return Short.valueOf(trimmedValue); } else if (paramType == int.class || paramType == Integer.class) { - return Integer.valueOf(value); + return Integer.valueOf(trimmedValue); } else if (paramType == long.class || paramType == Long.class) { - return Long.valueOf(value); + return Long.valueOf(trimmedValue); } else if (paramType == float.class || paramType == Float.class) { - return Float.valueOf(value); + return Float.valueOf(trimmedValue); } else if (paramType == double.class || paramType == Double.class) { - return Double.valueOf(value); + return Double.valueOf(trimmedValue); } else if (paramType == char.class || paramType == Character.class) { - return value.length() > 0 ? value.charAt(0) : 0; + return trimmedValue.length() > 0 ? trimmedValue.charAt(0) : 0; } else if (paramType == TimeZone.class) { - return TimeZone.getTimeZone(value); + return TimeZone.getTimeZone(trimmedValue); } else if (paramType == Charset.class) { - return Charset.forName(value); + return Charset.forName(trimmedValue); } else if (paramType.isAssignableFrom(Level.class)) { - return Level.parse(value); + return Level.parse(trimmedValue); } else if (paramType.isEnum()) { - return Enum.valueOf(paramType.asSubclass(Enum.class), value); - } else if (contextConfiguration.hasObject(value)) { - return contextConfiguration.getObject(value); + return Enum.valueOf(paramType.asSubclass(Enum.class), trimmedValue); + } else if (contextConfiguration.hasObject(trimmedValue)) { + return contextConfiguration.getObject(trimmedValue); } else if (definedPropertiesContains(propertyName)) { final PropertyValue propertyValue = findDefinedProperty(propertyName); if (propertyValue == null) { diff --git a/src/main/java/org/jboss/logmanager/configuration/PropertyConfigurator.java b/src/main/java/org/jboss/logmanager/configuration/PropertyContextConfiguration.java similarity index 79% rename from src/main/java/org/jboss/logmanager/configuration/PropertyConfigurator.java rename to src/main/java/org/jboss/logmanager/configuration/PropertyContextConfiguration.java index f0483431..030157da 100644 --- a/src/main/java/org/jboss/logmanager/configuration/PropertyConfigurator.java +++ b/src/main/java/org/jboss/logmanager/configuration/PropertyContextConfiguration.java @@ -23,6 +23,7 @@ import java.util.EnumSet; import java.util.List; import java.util.Locale; +import java.util.Objects; import java.util.Properties; import java.util.function.Supplier; import java.util.logging.ErrorManager; @@ -30,15 +31,14 @@ import java.util.logging.Formatter; import java.util.logging.Handler; import java.util.logging.Level; -import java.util.logging.Logger; import org.jboss.logmanager.LogContext; +import org.jboss.logmanager.Logger; import org.jboss.logmanager.StandardOutputStreams; import org.jboss.logmanager.configuration.filters.FilterExpressions; import org.jboss.logmanager.filters.AcceptAllFilter; import org.jboss.logmanager.filters.DenyAllFilter; -import io.smallrye.common.constraint.Assert; import io.smallrye.common.expression.Expression; /** @@ -47,20 +47,14 @@ * @author James R. Perkins */ @SuppressWarnings("WeakerAccess") -public class PropertyConfigurator { +public class PropertyContextConfiguration extends ContextConfiguration { private static final String[] EMPTY_STRINGS = new String[0]; - - private final LogContext logContext; private final Properties properties; - private final ContextConfiguration contextConfiguration; - private PropertyConfigurator(final LogContext logContext, final Properties properties) { - this.logContext = logContext; + private PropertyContextConfiguration(final LogContext logContext, final Properties properties) { + super(logContext); this.properties = properties; - ContextConfiguration config = new ContextConfiguration(); - final ContextConfiguration current = logContext.attachIfAbsent(ContextConfiguration.CONTEXT_CONFIGURATION_KEY, config); - contextConfiguration = (current == null ? config : current); } /** @@ -68,12 +62,15 @@ private PropertyConfigurator(final LogContext logContext, final Properties prope * * @param logContext the log context to configure * @param properties the properties used to configure the log context + * + * @return the context configuration for the properties */ - public static void configure(final LogContext logContext, final Properties properties) { - final PropertyConfigurator config = new PropertyConfigurator( - Assert.checkNotNullParam("logContext", logContext), - Assert.checkNotNullParam("properties", properties)); + public static PropertyContextConfiguration configure(final LogContext logContext, final Properties properties) { + final PropertyContextConfiguration config = new PropertyContextConfiguration( + Objects.requireNonNull(logContext), + Objects.requireNonNull(properties)); config.doConfigure(); + return config; } private void doConfigure() { @@ -105,7 +102,7 @@ private void doConfigure() { } } - @SuppressWarnings({ "ConstantConditions", "CastCanBeRemovedNarrowingVariableType" }) + @SuppressWarnings({ "ConstantConditions" }) private void configureLogger(final String loggerName) { /* * if (logContext.getLoggerIfExists(loggerName) != null) { @@ -113,7 +110,7 @@ private void configureLogger(final String loggerName) { * return; * } */ - final Logger logger = logContext.getLogger(loggerName); + final Logger logger = getContext().getLogger(loggerName); // Get logger level final String levelName = getStringProperty(getKey("logger", loggerName, "level")); @@ -125,7 +122,7 @@ private void configureLogger(final String loggerName) { final String filterName = getStringProperty(getKey("logger", loggerName, "filter")); if (filterName != null) { if (configureFilter(filterName)) { - logger.setFilter(contextConfiguration.getFilter(filterName)); + logger.setFilter(getFilter(filterName)); } } @@ -133,7 +130,7 @@ private void configureLogger(final String loggerName) { final String[] handlerNames = getStringCsvArray(getKey("logger", loggerName, "handlers")); for (String name : handlerNames) { if (configureHandler(name)) { - logger.addHandler(contextConfiguration.getHandler(name)); + logger.addHandler(getHandler(name)); } } @@ -148,10 +145,11 @@ private void configureLogger(final String loggerName) { ((org.jboss.logmanager.Logger) logger).setUseParentFilters(resolveBooleanExpression(useParentHandlersString)); } } + addLogger(loggerName, logger); } private boolean configureHandler(final String handlerName) { - if (contextConfiguration.hasHandler(handlerName)) { + if (hasHandler(handlerName)) { // already configured! return true; } @@ -161,8 +159,7 @@ private boolean configureHandler(final String handlerName) { return false; } - final ObjectBuilder handlerBuilder = ObjectBuilder - .of(logContext, contextConfiguration, Handler.class, className) + final ObjectBuilder handlerBuilder = ObjectBuilder.of(this, Handler.class, className) .setModuleName(getStringProperty(getKey("handler", handlerName, "module"))) .addPostConstructMethods(getStringCsvArray(getKey("handler", handlerName, "postConfiguration"))); @@ -176,7 +173,7 @@ private boolean configureHandler(final String handlerName) { final String filter = getStringProperty(getKey("handler", handlerName, "filter")); if (filter != null) { if (configureFilter(filter)) { - handlerBuilder.addDefinedProperty("filter", Filter.class, contextConfiguration.getFilters().get(filter)); + handlerBuilder.addDefinedProperty("filter", Filter.class, getFilters().get(filter)); } } final String levelName = getStringProperty(getKey("handler", handlerName, "level")); @@ -186,14 +183,14 @@ private boolean configureHandler(final String handlerName) { final String formatterName = getStringProperty(getKey("handler", handlerName, "formatter")); if (formatterName != null) { if (configureFormatter(formatterName)) { - handlerBuilder.addDefinedProperty("formatter", Formatter.class, contextConfiguration.getFormatters() + handlerBuilder.addDefinedProperty("formatter", Formatter.class, getFormatters() .get(formatterName)); } } final String errorManagerName = getStringProperty(getKey("handler", handlerName, "errorManager")); if (errorManagerName != null) { if (configureErrorManager(errorManagerName)) { - handlerBuilder.addDefinedProperty("errorManager", ErrorManager.class, contextConfiguration.getErrorManagers() + handlerBuilder.addDefinedProperty("errorManager", ErrorManager.class, getErrorManagers() .get(errorManagerName)); } } @@ -203,31 +200,27 @@ private boolean configureHandler(final String handlerName) { final List> subhandlers = new ArrayList<>(); for (String name : handlerNames) { if (configureHandler(name)) { - subhandlers.add(contextConfiguration.getHandlers().get(name)); + subhandlers.add(getHandlers().get(name)); } } - handlerBuilder.addDefinedProperty("handlers", Handler[].class, new Supplier() { - - @Override - public Handler[] get() { - if (subhandlers.isEmpty()) { - return new Handler[0]; - } - final Handler[] result = new Handler[subhandlers.size()]; - int i = 0; - for (Supplier supplier : subhandlers) { - result[i++] = supplier.get(); - } - return result; + handlerBuilder.addDefinedProperty("handlers", Handler[].class, (Supplier) () -> { + if (subhandlers.isEmpty()) { + return new Handler[0]; + } + final Handler[] result = new Handler[subhandlers.size()]; + int i = 0; + for (Supplier supplier : subhandlers) { + result[i++] = supplier.get(); } + return result; }); } - contextConfiguration.addHandler(handlerName, handlerBuilder.build()); + addHandler(handlerName, handlerBuilder.build()); return true; } private boolean configureFormatter(final String formatterName) { - if (contextConfiguration.hasFilter(formatterName)) { + if (hasFilter(formatterName)) { // already configured! return true; } @@ -236,17 +229,16 @@ private boolean configureFormatter(final String formatterName) { StandardOutputStreams.printError("Formatter %s is not defined%n", formatterName); return false; } - final ObjectBuilder formatterBuilder = ObjectBuilder - .of(logContext, contextConfiguration, Formatter.class, className) + final ObjectBuilder formatterBuilder = ObjectBuilder.of(this, Formatter.class, className) .setModuleName(getStringProperty(getKey("formatter", formatterName, "module"))) .addPostConstructMethods(getStringCsvArray(getKey("formatter", formatterName, "postConfiguration"))); configureProperties(formatterBuilder, "formatter", formatterName); - contextConfiguration.addFormatter(formatterName, formatterBuilder.build()); + addFormatter(formatterName, formatterBuilder.build()); return true; } private boolean configureErrorManager(final String errorManagerName) { - if (contextConfiguration.hasErrorManager(errorManagerName)) { + if (hasErrorManager(errorManagerName)) { // already configured! return true; } @@ -255,17 +247,16 @@ private boolean configureErrorManager(final String errorManagerName) { StandardOutputStreams.printError("Error manager %s is not defined%n", errorManagerName); return false; } - final ObjectBuilder errorManagerBuilder = ObjectBuilder - .of(logContext, contextConfiguration, ErrorManager.class, className) + final ObjectBuilder errorManagerBuilder = ObjectBuilder.of(this, ErrorManager.class, className) .setModuleName(getStringProperty(getKey("errorManager", errorManagerName, "module"))) .addPostConstructMethods(getStringCsvArray(getKey("errorManager", errorManagerName, "postConfiguration"))); configureProperties(errorManagerBuilder, "errorManager", errorManagerName); - contextConfiguration.addErrorManager(errorManagerName, errorManagerBuilder.build()); + addErrorManager(errorManagerName, errorManagerBuilder.build()); return true; } private boolean configureFilter(final String filterName) { - if (contextConfiguration.hasFilter(filterName)) { + if (hasFilter(filterName)) { return true; } // First determine if we're using a defined filters or filters expression. We assume a defined filters if there is @@ -273,28 +264,27 @@ private boolean configureFilter(final String filterName) { String filterValue = getStringProperty(getKey("filter", filterName), true, false); if (filterValue == null) { // We are a filters expression, parse the expression and create a filters - contextConfiguration.addFilter(filterName, () -> FilterExpressions.parse(logContext, filterName)); + addFilter(filterName, () -> FilterExpressions.parse(getContext(), filterName)); } else { // The AcceptAllFilter and DenyAllFilter are singletons. if (AcceptAllFilter.class.getName().equals(filterValue)) { - contextConfiguration.addFilter(filterName, AcceptAllFilter::getInstance); + addFilter(filterName, AcceptAllFilter::getInstance); } else if (DenyAllFilter.class.getName().equals(filterValue)) { - contextConfiguration.addFilter(filterName, DenyAllFilter::getInstance); + addFilter(filterName, DenyAllFilter::getInstance); } else { // We assume we're a defined filter - final ObjectBuilder filterBuilder = ObjectBuilder - .of(logContext, contextConfiguration, Filter.class, filterValue) + final ObjectBuilder filterBuilder = ObjectBuilder.of(this, Filter.class, filterValue) .setModuleName(getStringProperty(getKey("filter", filterName, "module"))) .addPostConstructMethods(getStringCsvArray(getKey("filter", filterName, "postConfiguration"))); configureProperties(filterBuilder, "errorManager", filterName); - contextConfiguration.addFilter(filterName, filterBuilder.build()); + addFilter(filterName, filterBuilder.build()); } } return true; } private void configurePojos(final String pojoName) { - if (contextConfiguration.hasObject(pojoName)) { + if (hasObject(pojoName)) { // already configured! return; } @@ -303,11 +293,11 @@ private void configurePojos(final String pojoName) { StandardOutputStreams.printError("POJO %s is not defined%n", pojoName); return; } - final ObjectBuilder pojoBuilder = ObjectBuilder.of(logContext, contextConfiguration, Object.class, className) + final ObjectBuilder pojoBuilder = ObjectBuilder.of(this, Object.class, className) .setModuleName(getStringProperty(getKey("pojo", pojoName, "module"))) .addPostConstructMethods(getStringCsvArray(getKey("pojo", pojoName, "postConfiguration"))); configureProperties(pojoBuilder, "pojo", pojoName); - contextConfiguration.addObject(pojoName, pojoBuilder.build()); + addObject(pojoName, pojoBuilder.build()); } private String getStringProperty(final String key) { diff --git a/src/main/java/org/jboss/logmanager/configuration/DefaultLogContextConfigurator.java b/src/main/java/org/jboss/logmanager/configuration/PropertyLogContextConfigurator.java similarity index 87% rename from src/main/java/org/jboss/logmanager/configuration/DefaultLogContextConfigurator.java rename to src/main/java/org/jboss/logmanager/configuration/PropertyLogContextConfigurator.java index de004fdc..3622ab84 100644 --- a/src/main/java/org/jboss/logmanager/configuration/DefaultLogContextConfigurator.java +++ b/src/main/java/org/jboss/logmanager/configuration/PropertyLogContextConfigurator.java @@ -58,11 +58,12 @@ * * @author James R. Perkins */ -public class DefaultLogContextConfigurator implements LogContextConfigurator { +public class PropertyLogContextConfigurator implements LogContextConfigurator { @Override public void configure(final LogContext logContext, final InputStream inputStream) { final InputStream configIn = inputStream != null ? inputStream : findConfiguration(); + final LogContext context = logContext == null ? LogContext.getLogContext() : logContext; // Configure the log context based on a property file if (configIn != null) { @@ -72,19 +73,20 @@ public void configure(final LogContext logContext, final InputStream inputStream } catch (IOException e) { throw new RuntimeException("Failed to configure log manager with configuration file.", e); } - PropertyConfigurator.configure(logContext, properties); + final PropertyContextConfiguration configurator = PropertyContextConfiguration.configure(context, properties); + context.attachIfAbsent(ContextConfiguration.CONTEXT_CONFIGURATION_KEY, configurator); } else { // Next check the service loader final Iterator serviceLoader = ServiceLoader.load(LogContextConfigurator.class).iterator(); if (serviceLoader.hasNext()) { - serviceLoader.next().configure(logContext, inputStream); + serviceLoader.next().configure(context, null); } else { // Configure a default console handler, pattern formatter and associated with the root logger final ConsoleHandler handler = new ConsoleHandler( new PatternFormatter("%d{yyyy-MM-dd'T'HH:mm:ssXXX} %-5p [%c] (%t) %s%e%n")); handler.setLevel(Level.INFO); handler.setAutoFlush(true); - final Logger rootLogger = logContext.getLogger(""); + final Logger rootLogger = context.getLogger(""); rootLogger.setLevel(Level.INFO); rootLogger.addHandler(handler); } @@ -107,6 +109,6 @@ private static InputStream findConfiguration() { return stream; } catch (Exception ignore) { } - return DefaultLogContextConfigurator.class.getResourceAsStream("logging.properties"); + return PropertyLogContextConfigurator.class.getResourceAsStream("logging.properties"); } } diff --git a/src/main/java/org/jboss/logmanager/configuration/SingletonSupplier.java b/src/main/java/org/jboss/logmanager/configuration/SingletonSupplier.java new file mode 100644 index 00000000..cd61476c --- /dev/null +++ b/src/main/java/org/jboss/logmanager/configuration/SingletonSupplier.java @@ -0,0 +1,53 @@ +/* + * JBoss, Home of Professional Open Source. + * + * Copyright 2022 Red Hat, Inc., and individual contributors + * as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jboss.logmanager.configuration; + +import java.util.function.Supplier; + +/** + * @author James R. Perkins + */ +class SingletonSupplier implements Supplier { + private final Supplier supplier; + private volatile T instance; + + private SingletonSupplier(final Supplier supplier) { + this.supplier = supplier; + } + + static Supplier of(final Supplier supplier) { + if (supplier instanceof SingletonSupplier) { + return supplier; + } + return new SingletonSupplier<>(supplier); + } + + @Override + public T get() { + if (instance == null) { + synchronized (this) { + if (instance == null) { + instance = supplier.get(); + } + } + } + return instance; + } +} diff --git a/src/test/java/org/jboss/logmanager/configuration/PropertyConfigurationTests.java b/src/test/java/org/jboss/logmanager/configuration/PropertyConfigurationTests.java index f65fbd9a..febb25f9 100644 --- a/src/test/java/org/jboss/logmanager/configuration/PropertyConfigurationTests.java +++ b/src/test/java/org/jboss/logmanager/configuration/PropertyConfigurationTests.java @@ -82,7 +82,7 @@ public void readConfigs() throws Exception { Reader reader = Files.newBufferedReader(configFile, StandardCharsets.UTF_8)) { final Properties properties = new Properties(); properties.load(reader); - PropertyConfigurator.configure(logContext, properties); + PropertyContextConfiguration.configure(logContext, properties); } catch (Exception e) { final StringWriter writer = new StringWriter(); writer.append("Failed to configure ") @@ -97,7 +97,7 @@ public void readConfigs() throws Exception { @Test public void testSimple() { final Properties config = defaultProperties(); - PropertyConfigurator.configure(logContext, config); + PropertyContextConfiguration.configure(logContext, config); testDefault(2, 1); } @@ -111,7 +111,7 @@ public void testLogger() { config.setProperty("handler.TEST", TestHandler.class.getName()); - PropertyConfigurator.configure(logContext, config); + PropertyContextConfiguration.configure(logContext, config); testDefault(3, 1); final Logger logger = logContext.getLoggerIfExists(loggerName); @@ -137,7 +137,7 @@ public void testErrorManager() { config.setProperty("errorManager.TEST", TestErrorManager.class.getName()); - PropertyConfigurator.configure(logContext, config); + PropertyContextConfiguration.configure(logContext, config); testDefault(2, 2); final Logger rootLogger = logContext.getLogger(""); @@ -154,7 +154,7 @@ public void testErrorManager() { public void testPojo() { final Properties config = defaultProperties(); addPojoConfiguration(config); - PropertyConfigurator.configure(logContext, config); + PropertyContextConfiguration.configure(logContext, config); testDefault(2, 2); final Logger rootLogger = logContext.getLogger(""); @@ -174,7 +174,7 @@ public void testUnusedHandler() { final Properties config = defaultProperties(); config.setProperty("handler.TEST", TestHandler.class.getName()); - PropertyConfigurator.configure(logContext, config); + PropertyContextConfiguration.configure(logContext, config); testDefault(2, 1); // The test handler should not have been activated @@ -186,7 +186,7 @@ public void testUnusedFormatter() { final Properties config = defaultProperties(); config.setProperty("formatter.TEST", TestFormatter.class.getName()); - PropertyConfigurator.configure(logContext, config); + PropertyContextConfiguration.configure(logContext, config); testDefault(2, 1); // The test handler should not have been activated @@ -198,7 +198,7 @@ public void testUnusedErrorManager() { final Properties config = defaultProperties(); config.setProperty("errorManager.TEST", TestErrorManager.class.getName()); - PropertyConfigurator.configure(logContext, config); + PropertyContextConfiguration.configure(logContext, config); testDefault(2, 1); // The test handler should not have been activated @@ -210,7 +210,7 @@ public void testUnusedFilter() { final Properties config = defaultProperties(); config.setProperty("filter.TEST", TestFilter.class.getName()); - PropertyConfigurator.configure(logContext, config); + PropertyContextConfiguration.configure(logContext, config); testDefault(2, 1); // The test handler should not have been activated