1 /* 2 * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 27 package java.util.logging; 28 29 import java.io.UnsupportedEncodingException; 30 /** 31 * A <tt>Handler</tt> object takes log messages from a <tt>Logger</tt> and 32 * exports them. It might for example, write them to a console 33 * or write them to a file, or send them to a network logging service, 34 * or forward them to an OS log, or whatever. 35 * <p> 36 * A <tt>Handler</tt> can be disabled by doing a <tt>setLevel(Level.OFF)</tt> 37 * and can be re-enabled by doing a <tt>setLevel</tt> with an appropriate level. 38 * <p> 39 * <tt>Handler</tt> classes typically use <tt>LogManager</tt> properties to set 40 * default values for the <tt>Handler</tt>'s <tt>Filter</tt>, <tt>Formatter</tt>, 41 * and <tt>Level</tt>. See the specific documentation for each concrete 42 * <tt>Handler</tt> class. 43 * 44 * 45 * @since 1.4 46 */ 47 48 public abstract class Handler { 49 private static final int offValue = Level.OFF.intValue(); 50 private LogManager manager = LogManager.getLogManager(); 51 private Filter filter; 52 private Formatter formatter; 53 private Level logLevel = Level.ALL; 54 private ErrorManager errorManager = new ErrorManager(); 55 private String encoding; 56 57 // Package private support for security checking. When sealed 58 // is true, we access check updates to the class. 59 boolean sealed = true; 60 61 /** 62 * Default constructor. The resulting <tt>Handler</tt> has a log 63 * level of <tt>Level.ALL</tt>, no <tt>Formatter</tt>, and no 64 * <tt>Filter</tt>. A default <tt>ErrorManager</tt> instance is installed 65 * as the <tt>ErrorManager</tt>. 66 */ Handler()67 protected Handler() { 68 } 69 70 /** 71 * Publish a <tt>LogRecord</tt>. 72 * <p> 73 * The logging request was made initially to a <tt>Logger</tt> object, 74 * which initialized the <tt>LogRecord</tt> and forwarded it here. 75 * <p> 76 * The <tt>Handler</tt> is responsible for formatting the message, when and 77 * if necessary. The formatting should include localization. 78 * 79 * @param record description of the log event. A null record is 80 * silently ignored and is not published 81 */ publish(LogRecord record)82 public abstract void publish(LogRecord record); 83 84 /** 85 * Flush any buffered output. 86 */ flush()87 public abstract void flush(); 88 89 /** 90 * Close the <tt>Handler</tt> and free all associated resources. 91 * <p> 92 * The close method will perform a <tt>flush</tt> and then close the 93 * <tt>Handler</tt>. After close has been called this <tt>Handler</tt> 94 * should no longer be used. Method calls may either be silently 95 * ignored or may throw runtime exceptions. 96 * 97 * @exception SecurityException if a security manager exists and if 98 * the caller does not have <tt>LoggingPermission("control")</tt>. 99 */ close()100 public abstract void close() throws SecurityException; 101 102 /** 103 * Set a <tt>Formatter</tt>. This <tt>Formatter</tt> will be used 104 * to format <tt>LogRecords</tt> for this <tt>Handler</tt>. 105 * <p> 106 * Some <tt>Handlers</tt> may not use <tt>Formatters</tt>, in 107 * which case the <tt>Formatter</tt> will be remembered, but not used. 108 * <p> 109 * @param newFormatter the <tt>Formatter</tt> to use (may not be null) 110 * @exception SecurityException if a security manager exists and if 111 * the caller does not have <tt>LoggingPermission("control")</tt>. 112 */ setFormatter(Formatter newFormatter)113 public void setFormatter(Formatter newFormatter) throws SecurityException { 114 checkPermission(); 115 // Check for a null pointer: 116 newFormatter.getClass(); 117 formatter = newFormatter; 118 } 119 120 /** 121 * Return the <tt>Formatter</tt> for this <tt>Handler</tt>. 122 * @return the <tt>Formatter</tt> (may be null). 123 */ getFormatter()124 public Formatter getFormatter() { 125 return formatter; 126 } 127 128 /** 129 * Set the character encoding used by this <tt>Handler</tt>. 130 * <p> 131 * The encoding should be set before any <tt>LogRecords</tt> are written 132 * to the <tt>Handler</tt>. 133 * 134 * @param encoding The name of a supported character encoding. 135 * May be null, to indicate the default platform encoding. 136 * @exception SecurityException if a security manager exists and if 137 * the caller does not have <tt>LoggingPermission("control")</tt>. 138 * @exception UnsupportedEncodingException if the named encoding is 139 * not supported. 140 */ setEncoding(String encoding)141 public void setEncoding(String encoding) 142 throws SecurityException, java.io.UnsupportedEncodingException { 143 checkPermission(); 144 if (encoding != null) { 145 try { 146 if(!java.nio.charset.Charset.isSupported(encoding)) { 147 throw new UnsupportedEncodingException(encoding); 148 } 149 } catch (java.nio.charset.IllegalCharsetNameException e) { 150 throw new UnsupportedEncodingException(encoding); 151 } 152 } 153 this.encoding = encoding; 154 } 155 156 /** 157 * Return the character encoding for this <tt>Handler</tt>. 158 * 159 * @return The encoding name. May be null, which indicates the 160 * default encoding should be used. 161 */ getEncoding()162 public String getEncoding() { 163 return encoding; 164 } 165 166 /** 167 * Set a <tt>Filter</tt> to control output on this <tt>Handler</tt>. 168 * <P> 169 * For each call of <tt>publish</tt> the <tt>Handler</tt> will call 170 * this <tt>Filter</tt> (if it is non-null) to check if the 171 * <tt>LogRecord</tt> should be published or discarded. 172 * 173 * @param newFilter a <tt>Filter</tt> object (may be null) 174 * @exception SecurityException if a security manager exists and if 175 * the caller does not have <tt>LoggingPermission("control")</tt>. 176 */ setFilter(Filter newFilter)177 public void setFilter(Filter newFilter) throws SecurityException { 178 checkPermission(); 179 filter = newFilter; 180 } 181 182 /** 183 * Get the current <tt>Filter</tt> for this <tt>Handler</tt>. 184 * 185 * @return a <tt>Filter</tt> object (may be null) 186 */ getFilter()187 public Filter getFilter() { 188 return filter; 189 } 190 191 /** 192 * Define an ErrorManager for this Handler. 193 * <p> 194 * The ErrorManager's "error" method will be invoked if any 195 * errors occur while using this Handler. 196 * 197 * @param em the new ErrorManager 198 * @exception SecurityException if a security manager exists and if 199 * the caller does not have <tt>LoggingPermission("control")</tt>. 200 */ setErrorManager(ErrorManager em)201 public void setErrorManager(ErrorManager em) { 202 checkPermission(); 203 if (em == null) { 204 throw new NullPointerException(); 205 } 206 errorManager = em; 207 } 208 209 /** 210 * Retrieves the ErrorManager for this Handler. 211 * 212 * @exception SecurityException if a security manager exists and if 213 * the caller does not have <tt>LoggingPermission("control")</tt>. 214 */ getErrorManager()215 public ErrorManager getErrorManager() { 216 checkPermission(); 217 return errorManager; 218 } 219 220 /** 221 * Protected convenience method to report an error to this Handler's 222 * ErrorManager. Note that this method retrieves and uses the ErrorManager 223 * without doing a security check. It can therefore be used in 224 * environments where the caller may be non-privileged. 225 * 226 * @param msg a descriptive string (may be null) 227 * @param ex an exception (may be null) 228 * @param code an error code defined in ErrorManager 229 */ reportError(String msg, Exception ex, int code)230 protected void reportError(String msg, Exception ex, int code) { 231 try { 232 errorManager.error(msg, ex, code); 233 } catch (Exception ex2) { 234 System.err.println("Handler.reportError caught:"); 235 ex2.printStackTrace(); 236 } 237 } 238 239 /** 240 * Set the log level specifying which message levels will be 241 * logged by this <tt>Handler</tt>. Message levels lower than this 242 * value will be discarded. 243 * <p> 244 * The intention is to allow developers to turn on voluminous 245 * logging, but to limit the messages that are sent to certain 246 * <tt>Handlers</tt>. 247 * 248 * @param newLevel the new value for the log level 249 * @exception SecurityException if a security manager exists and if 250 * the caller does not have <tt>LoggingPermission("control")</tt>. 251 */ setLevel(Level newLevel)252 public synchronized void setLevel(Level newLevel) throws SecurityException { 253 if (newLevel == null) { 254 throw new NullPointerException(); 255 } 256 checkPermission(); 257 logLevel = newLevel; 258 } 259 260 /** 261 * Get the log level specifying which messages will be 262 * logged by this <tt>Handler</tt>. Message levels lower 263 * than this level will be discarded. 264 * @return the level of messages being logged. 265 */ getLevel()266 public synchronized Level getLevel() { 267 return logLevel; 268 } 269 270 /** 271 * Check if this <tt>Handler</tt> would actually log a given <tt>LogRecord</tt>. 272 * <p> 273 * This method checks if the <tt>LogRecord</tt> has an appropriate 274 * <tt>Level</tt> and whether it satisfies any <tt>Filter</tt>. It also 275 * may make other <tt>Handler</tt> specific checks that might prevent a 276 * handler from logging the <tt>LogRecord</tt>. It will return false if 277 * the <tt>LogRecord</tt> is null. 278 * <p> 279 * @param record a <tt>LogRecord</tt> 280 * @return true if the <tt>LogRecord</tt> would be logged. 281 * 282 */ isLoggable(LogRecord record)283 public boolean isLoggable(LogRecord record) { 284 int levelValue = getLevel().intValue(); 285 if (record.getLevel().intValue() < levelValue || levelValue == offValue) { 286 return false; 287 } 288 Filter filter = getFilter(); 289 if (filter == null) { 290 return true; 291 } 292 return filter.isLoggable(record); 293 } 294 295 // Package-private support method for security checks. 296 // If "sealed" is true, we check that the caller has 297 // appropriate security privileges to update Handler 298 // state and if not throw a SecurityException. checkPermission()299 void checkPermission() throws SecurityException { 300 if (sealed) { 301 manager.checkPermission(); 302 } 303 } 304 } 305