1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one * 3 * or more contributor license agreements. See the NOTICE file * 4 * distributed with this work for additional information * 5 * regarding copyright ownership. The ASF licenses this file * 6 * to you under the Apache License, Version 2.0 (the * 7 * "License"); you may not use this file except in compliance * 8 * with the License. You may obtain a copy of the License at * 9 * * 10 * http://www.apache.org/licenses/LICENSE-2.0 * 11 * * 12 * Unless required by applicable law or agreed to in writing, * 13 * software distributed under the License is distributed on an * 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * 15 * KIND, either express or implied. See the License for the * 16 * specific language governing permissions and limitations * 17 * under the License. * 18 */ 19 package org.apache.rat.utils; 20 21 import java.io.PrintWriter; 22 import java.io.StringWriter; 23 import java.io.Writer; 24 25 /** 26 * The definition of logging for the core. UIs are expected to provide an implementation of 27 * Log to log data to the appropriate system within the UI. 28 */ 29 public interface Log { 30 /** 31 * The log levels supported by logging. 32 */ 33 enum Level { 34 // these must be listed in order of decreasing noisiness. 35 /** Log debug only. */ 36 DEBUG, 37 /** Log info only. */ 38 INFO, 39 /** Log warn only. */ 40 WARN, 41 /** Log error only. */ 42 ERROR, 43 /** Log nothing. */ 44 OFF } 45 46 /** 47 * Gets the log level that is enabled. If encapsulated logger does not report level 48 * implementations should return DEBUG. 49 * @return the level that is enabled. 50 */ 51 Level getLevel(); 52 53 /** 54 * Sets the log level. 55 * Implementations may elect not to set the level dynamically. However, if the option is supported 56 * this method should be overridden. 57 * @param level the level to set. 58 */ 59 default void setLevel(Level level) { 60 warn(String.format("This logger does not support dynamically setting the log level. Setting to %s ignored.", level)); 61 } 62 63 /** 64 * Determines if the log level is enabled. 65 * @param level The level to check. 66 * @return true if the level will produce output in the log. 67 */ 68 default boolean isEnabled(Level level) { 69 return getLevel().ordinal() <= level.ordinal(); 70 } 71 72 /** 73 * Writes a message at a specific log level. 74 * @param level The log level to write at. 75 * @param message the message to write. 76 */ 77 void log(Level level, String message); 78 79 /** 80 * Writes a log message at the specified level. 81 * @param level the level to write the message at. 82 * @param message the message to write. 83 */ 84 default void log(Level level, Object message) { 85 log(level, message == null ? "NULL" : message.toString()); 86 } 87 88 /** 89 * Write a message at DEBUG level. 90 * @param message the message to write. 91 */ 92 default void debug(Object message) { 93 log(Level.DEBUG, message); 94 } 95 96 /** 97 * Write a message at INFO level. 98 * @param message the message to write. 99 */ 100 default void info(Object message) { 101 log(Level.INFO, message); 102 } 103 104 /** 105 * Write a message at WARN level. 106 * @param message the message to write. 107 */ 108 default void warn(Object message) { 109 log(Level.WARN, message); 110 } 111 112 /** 113 * Write a message at ERROR level. 114 * @param message the message to write. 115 */ 116 default void error(Object message) { 117 log(Level.ERROR, message); 118 } 119 120 /** 121 * Write a log message and report throwable stack trace at the specified log level. 122 * @param level the level to report at 123 * @param message the message for the log 124 * @param throwable the throwable 125 */ 126 default void log(Level level, String message, Throwable throwable) { 127 StringWriter writer = new StringWriter(500); 128 PrintWriter pWriter = new PrintWriter(writer); 129 pWriter.print(message); 130 pWriter.print(System.lineSeparator()); 131 throwable.printStackTrace(pWriter); 132 log(level, writer.toString()); 133 } 134 135 /** 136 * Write a log message and report throwable stack trace at the specified log level. 137 * @param level the level to report at 138 * @param message the message for the log 139 * @param throwable the throwable 140 */ 141 default void log(Level level, Object message, Throwable throwable) { 142 log(level, message == null ? "NULL" : message.toString(), throwable); 143 } 144 145 /** 146 * Write a debug message and report throwable stack trace. 147 * @param message the message for the log 148 * @param throwable the throwable 149 */ 150 default void debug(Object message, Throwable throwable) { 151 log(Level.DEBUG, message, throwable); 152 } 153 154 /** 155 * Write an info message and report throwable stack trace. 156 * @param message the message for the log 157 * @param throwable the throwable 158 */ 159 default void info(Object message, Throwable throwable) { 160 log(Level.INFO, message, throwable); 161 } 162 163 /** 164 * Write a warn message and report throwable stack trace. 165 * @param message the message for the log 166 * @param throwable the throwable 167 */ 168 default void warn(Object message, Throwable throwable) { 169 log(Level.WARN, message, throwable); 170 } 171 172 /** 173 * Write an error message and report throwable stack trace. 174 * @param message the message for the log 175 * @param throwable the throwable 176 */ 177 default void error(Object message, Throwable throwable) { 178 log(Level.ERROR, message, throwable); 179 } 180 181 /** 182 * Returns a Writer backed by this log. All messages are logged at "INFO" level. 183 * @return the Writer backed by this log. 184 */ 185 default Writer asWriter() { 186 return asWriter(Level.INFO); 187 } 188 189 /** 190 * Returns a Writer backed by this log. All messages are logged at "INFO" level. 191 * @return the Writer backed by this log. 192 * @param level the Log level to write at. 193 */ 194 default Writer asWriter(Level level) { 195 return new Writer() { 196 private StringBuilder sb = new StringBuilder(); 197 198 @Override 199 public void write(final char[] cbuf, final int off, final int len) { 200 String txt = String.copyValueOf(cbuf, off, len); 201 int pos = txt.indexOf(System.lineSeparator()); 202 if (pos == -1) { 203 sb.append(txt); 204 } else { 205 while (pos > -1) { 206 Log.this.log(level, sb.append(txt, 0, pos).toString()); 207 sb.delete(0, sb.length()); 208 txt = txt.substring(pos + 1); 209 pos = txt.indexOf(System.lineSeparator()); 210 } 211 sb.append(txt); 212 } 213 } 214 215 @Override 216 public void flush() { 217 if (sb.length() > 0) { 218 Log.this.log(level, sb.toString()); 219 } 220 sb = new StringBuilder(); 221 } 222 223 @Override 224 public void close() { 225 flush(); 226 } 227 }; 228 } 229 230 }