All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.jstach.rainbowgum.systemlogger.RainbowGumSystemLoggerFinder Maven / Gradle / Ivy

The newest version!
package io.jstach.rainbowgum.systemlogger;

import java.lang.System.Logger;
import java.util.Locale;
import java.util.function.Supplier;

import org.eclipse.jdt.annotation.Nullable;

import io.jstach.rainbowgum.LogProperties;
import io.jstach.rainbowgum.LogRouter;
import io.jstach.rainbowgum.RainbowGum;
import io.jstach.rainbowgum.LogProperty.Property;

/**
 * Abstract System Logger Finder to allow users to create their own custom
 * System.LoggerFinder. This implementation does not cache System Loggers
 * by name!
 *
 * @see #INTIALIZE_RAINBOW_GUM_PROPERTY
 */
public abstract class RainbowGumSystemLoggerFinder extends System.LoggerFinder {

	/**
	 * Initialization flag.
	 * @see InitOption
	 */
	public static final String INTIALIZE_RAINBOW_GUM_PROPERTY = LogProperties.ROOT_PREFIX + "systemlogger.intialize";

	private final RouterProvider routerProvider;

	/**
	 * Values (case is ignored) for {@value #INTIALIZE_RAINBOW_GUM_PROPERTY}.
	 */
	public enum InitOption {

		/**
		 * Will not initialize rainbow gum.
		 */
		FALSE,
		/**
		 * Will initialize rainbow gum.
		 */
		TRUE,
		/**
		 * Will reuse an existing rainbow gum or fail.
		 */
		REUSE;

		/**
		 * Parses an init option from a property value.
		 * @param input from properties.
		 * @return init option.
		 */
		public static InitOption parse(String input) {
			if (input.isBlank())
				return FALSE;
			return InitOption.valueOf(input.toUpperCase(Locale.ROOT));
		}

	}

	/**
	 * Creates the logger inder based on init option.
	 * @param opt can be resolved with {@link #initOption(LogProperties)}.
	 */
	protected RainbowGumSystemLoggerFinder(InitOption opt) {
		this.routerProvider = switch (opt) {
			case FALSE -> n -> LogRouter.global();
			case TRUE -> new InitRouterProvider(RainbowGum::of);
			case REUSE -> new InitRouterProvider(() -> {
				var gum = RainbowGum.getOrNull();
				if (gum == null) {
					throw new IllegalStateException(
							"SystemLogging was configured to reuse a loaded Rainbow Gum but none was found. "
									+ INTIALIZE_RAINBOW_GUM_PROPERTY + "=" + opt);
				}
				return gum;
			});
		};
	}

	@Override
	public Logger getLogger(String name, Module module) {
		var router = routerProvider.router(name);
		return RainbowGumSystemLogger.of(name, router);
	}

	/**
	 * Gets the init option from properties.
	 * @param properties usually system properties.
	 * @return intialization option.
	 */
	protected static InitOption initOption(LogProperties properties) {
		return Property.builder() //
			.map(InitOption::parse)
			.build(INTIALIZE_RAINBOW_GUM_PROPERTY) //
			.get(properties) //
			.value(InitOption.FALSE);
	}

	private interface RouterProvider {

		LogRouter router(String loggerName);

	}

	private class InitRouterProvider implements RouterProvider {

		private final Supplier supplier;

		private volatile @Nullable RainbowGum gum = null;

		public InitRouterProvider(Supplier supplier) {
			super();
			this.supplier = supplier;
		}

		@Override
		public LogRouter router(String loggerName) {
			LogRouter router;
			RainbowGum gum = this.gum;
			if (gum == null) {
				gum = this.gum = supplier.get();
			}
			if (gum.config().changePublisher().isEnabled(loggerName)) {
				router = LogRouter.global();
			}
			else {
				var rootRouter = gum.router();
				var levelResolver = rootRouter.levelResolver();
				var level = levelResolver.resolveLevel(loggerName);
				var logger = rootRouter.route(loggerName, level);
				router = LogRouter.ofLevel(logger, level);
			}
			return router;
		}

	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy