• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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