blob: 2643c73471489332498d7f15a0b3aeaf5719071d [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2000-2006 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26
27package java.util.logging;
28
29import 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
48public 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 */
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 */
82 public abstract void publish(LogRecord record);
83
84 /**
85 * Flush any buffered output.
86 */
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 */
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 */
113 public void setFormatter(Formatter newFormatter) throws SecurityException {
114 checkAccess();
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 */
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 */
141 public void setEncoding(String encoding)
142 throws SecurityException, java.io.UnsupportedEncodingException {
143 checkAccess();
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 */
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 */
177 public void setFilter(Filter newFilter) throws SecurityException {
178 checkAccess();
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 */
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 */
201 public void setErrorManager(ErrorManager em) {
202 checkAccess();
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 */
215 public ErrorManager getErrorManager() {
216 checkAccess();
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 */
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 */
252 public synchronized void setLevel(Level newLevel) throws SecurityException {
253 if (newLevel == null) {
254 throw new NullPointerException();
255 }
256 checkAccess();
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 */
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 */
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.
299 void checkAccess() throws SecurityException {
300 if (sealed) {
301 manager.checkAccess();
302 }
303 }
304}