001// Generated by delombok at Sat Feb 25 17:58:34 UTC 2023 002package io.cui.tools.logging; 003 004import static io.cui.tools.logging.CuiLoggerFactory.MARKER_CLASS_NAMES; 005import static io.cui.tools.string.MoreStrings.lenientFormat; 006import static io.cui.tools.string.MoreStrings.nullToEmpty; 007import java.util.Comparator; 008import java.util.List; 009import java.util.function.Supplier; 010import java.util.logging.Level; 011import java.util.logging.Logger; 012import io.cui.tools.collect.CollectionLiterals; 013import io.cui.tools.reflect.MoreReflection; 014import lombok.NonNull; 015 016/** 017 * Defines the log-levels with implicit mapping 018 * 019 * @author Oliver Wolff 020 */ 021public enum LogLevel { 022 /** 023 * Trace Level, maps to {@link Level#FINER}. 024 * <p> 025 * Attention: This is a derivation to 026 * http://www.slf4j.org/apidocs/org/slf4j/bridge/SLF4JBridgeHandler.html. 027 * But in fact this works... 028 */ 029 TRACE(Level.FINER), /** 030 * Debug Level, maps to {@link Level#FINE}. 031 */ 032 DEBUG(Level.FINE), /** 033 * Info Level, maps to {@link Level#INFO}. 034 */ 035 INFO(Level.INFO), /** 036 * Warn Level, maps to {@link Level#WARNING}. 037 */ 038 WARN(Level.WARNING), /** 039 * Error Level, maps to {@link Level#SEVERE}. 040 */ 041 ERROR(Level.SEVERE), /** 042 * Off Level, maps to {@link Level#OFF} 043 */ 044 OFF(Level.OFF); 045 private final Level juliLevel; 046 047 /** 048 * @param logger to be checked, must not be null 049 * @return {@code true} if the log-level is enabled on the logger, false otherwise 050 */ 051 boolean isEnabled(final Logger logger) { 052 return logger.isLoggable(getJuliLevel()); 053 } 054 055 /** 056 * Logs the message 057 * 058 * @param logger to be used, must not be null 059 * @param message must not be null 060 * @param throwable to be logged, may be null 061 */ 062 void handleActualLog(final Logger logger, final String message, final Throwable throwable) { 063 if (!isEnabled(logger)) { 064 return; 065 } 066 doLog(logger, message, throwable); 067 } 068 069 /** 070 * @param juliLevel 071 * @return CUI log level 072 */ 073 public static LogLevel from(@NonNull final Level juliLevel) { 074 if (juliLevel == null) { 075 throw new java.lang.NullPointerException("juliLevel is marked non-null but is null"); 076 } 077 // highest value first, i.e. OFF, ERROR, WARN, INFO, DEBUG, TRACE 078 List<LogLevel> sortedCuiLevels = CollectionLiterals.mutableList(values()); 079 sortedCuiLevels.sort(Comparator.comparing(logLevel -> logLevel.getJuliLevel().intValue())); 080 sortedCuiLevels.sort(Comparator.reverseOrder()); 081 final var juliIntLevel = juliLevel.intValue(); 082 for (LogLevel cuiLevel : sortedCuiLevels) { 083 final var cuiIntLevel = cuiLevel.getJuliLevel().intValue(); 084 if (cuiIntLevel <= juliIntLevel) { 085 return cuiLevel; 086 } 087 } 088 return TRACE; 089 } 090 091 private void doLog(final Logger logger, final String message, final Throwable throwable) { 092 // We go up the stack-trace until we found the call from CuiLogger. 093 final var caller = MoreReflection.findCallerElement(throwable, MARKER_CLASS_NAMES); 094 if (caller.isPresent()) { 095 // This is needed because otherwise LogRecord will assume this class and this method as 096 // the source of the log-statement 097 logger.logp(getJuliLevel(), caller.get().getClassName(), caller.get().getMethodName(), message, throwable); 098 } else { 099 logger.log(getJuliLevel(), message, throwable); 100 } 101 } 102 103 // False positive, logger state explicitly checked 104 @SuppressWarnings("squid:S2629") 105 void log(final Logger logger, final String template, final Object... parameter) { 106 if (isEnabled(logger)) { 107 final var replacedTemplate = io.cui.tools.logging.CuiLogger.SLF4J_PATTERN.matcher(nullToEmpty(template)).replaceAll("%s"); 108 doLog(logger, lenientFormat(replacedTemplate, parameter), null); 109 } 110 } 111 112 // False positive, logger state explicitly checked 113 @SuppressWarnings("squid:S2629") 114 void log(final Logger logger, Supplier<String> message, final Throwable throwable) { 115 if (isEnabled(logger)) { 116 doLog(logger, message.get(), throwable); 117 } 118 } 119 120 // False positive, logger state explicitly checked 121 @SuppressWarnings("squid:S2629") 122 void log(final Logger logger, final Throwable throwable, final String template, final Object... parameter) { 123 if (isEnabled(logger)) { 124 final var replacedTemplate = io.cui.tools.logging.CuiLogger.SLF4J_PATTERN.matcher(nullToEmpty(template)).replaceAll("%s"); 125 doLog(logger, lenientFormat(replacedTemplate, parameter), throwable); 126 } 127 } 128 129 @java.lang.SuppressWarnings("all") 130 @lombok.Generated 131 private LogLevel(final Level juliLevel) { 132 this.juliLevel = juliLevel; 133 } 134 135 @java.lang.SuppressWarnings("all") 136 @lombok.Generated 137 Level getJuliLevel() { 138 return this.juliLevel; 139 } 140}