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