1. /*
  2. * @(#)Handler.java 1.17 04/01/12
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.util.logging;
  8. /**
  9. * A <tt>Handler</tt> object takes log messages from a <tt>Logger</tt> and
  10. * exports them. It might for example, write them to a console
  11. * or write them to a file, or send them to a network logging service,
  12. * or forward them to an OS log, or whatever.
  13. * <p>
  14. * A <tt>Handler</tt> can be disabled by doing a <tt>setLevel(Level.OFF)</tt>
  15. * and can be re-enabled by doing a <tt>setLevel</tt> with an appropriate level.
  16. * <p>
  17. * <tt>Handler</tt> classes typically use <tt>LogManager</tt> properties to set
  18. * default values for the <tt>Handler</tt>'s <tt>Filter</tt>, <tt>Formatter</tt>,
  19. * and <tt>Level</tt>. See the specific documentation for each concrete
  20. * <tt>Handler</tt> class.
  21. *
  22. *
  23. * @version 1.17, 01/12/04
  24. * @since 1.4
  25. */
  26. public abstract class Handler {
  27. private static final int offValue = Level.OFF.intValue();
  28. private LogManager manager = LogManager.getLogManager();
  29. private Filter filter;
  30. private Formatter formatter;
  31. private Level logLevel = Level.ALL;
  32. private ErrorManager errorManager = new ErrorManager();
  33. private String encoding;
  34. // Package private support for security checking. When sealed
  35. // is true, we access check updates to the class.
  36. boolean sealed = true;
  37. /**
  38. * Default constructor. The resulting <tt>Handler</tt> has a log
  39. * level of <tt>Level.ALL</tt>, no <tt>Formatter</tt>, and no
  40. * <tt>Filter</tt>. A default <tt>ErrorManager</tt> instance is installed
  41. * as the <tt>ErrorManager</tt>.
  42. */
  43. protected Handler() {
  44. }
  45. /**
  46. * Publish a <tt>LogRecord</tt>.
  47. * <p>
  48. * The logging request was made initially to a <tt>Logger</tt> object,
  49. * which initialized the <tt>LogRecord</tt> and forwarded it here.
  50. * <p>
  51. * The <tt>Handler</tt> is responsible for formatting the message, when and
  52. * if necessary. The formatting should include localization.
  53. *
  54. * @param record description of the log event. A null record is
  55. * silently ignored and is not published
  56. */
  57. public abstract void publish(LogRecord record);
  58. /**
  59. * Flush any buffered output.
  60. */
  61. public abstract void flush();
  62. /**
  63. * Close the <tt>Handler</tt> and free all associated resources.
  64. * <p>
  65. * The close method will perform a <tt>flush</tt> and then close the
  66. * <tt>Handler</tt>. After close has been called this <tt>Handler</tt>
  67. * should no longer be used. Method calls may either be silently
  68. * ignored or may throw runtime exceptions.
  69. *
  70. * @exception SecurityException if a security manager exists and if
  71. * the caller does not have <tt>LoggingPermission("control")</tt>.
  72. */
  73. public abstract void close() throws SecurityException;
  74. /**
  75. * Set a <tt>Formatter</tt>. This <tt>Formatter</tt> will be used
  76. * to format <tt>LogRecords</tt> for this <tt>Handler</tt>.
  77. * <p>
  78. * Some <tt>Handlers</tt> may not use <tt>Formatters</tt>, in
  79. * which case the <tt>Formatter</tt> will be remembered, but not used.
  80. * <p>
  81. * @param newFormatter the <tt>Formatter</tt> to use (may not be null)
  82. * @exception SecurityException if a security manager exists and if
  83. * the caller does not have <tt>LoggingPermission("control")</tt>.
  84. */
  85. public void setFormatter(Formatter newFormatter) throws SecurityException {
  86. checkAccess();
  87. // Check for a null pointer:
  88. newFormatter.getClass();
  89. formatter = newFormatter;
  90. }
  91. /**
  92. * Return the <tt>Formatter</tt> for this <tt>Handler</tt>.
  93. * @return the <tt>Formatter</tt> (may be null).
  94. */
  95. public Formatter getFormatter() {
  96. return formatter;
  97. }
  98. /**
  99. * Set the character encoding used by this <tt>Handler</tt>.
  100. * <p>
  101. * The encoding should be set before any <tt>LogRecords</tt> are written
  102. * to the <tt>Handler</tt>.
  103. *
  104. * @param encoding The name of a supported character encoding.
  105. * May be null, to indicate the default platform encoding.
  106. * @exception SecurityException if a security manager exists and if
  107. * the caller does not have <tt>LoggingPermission("control")</tt>.
  108. * @exception UnsupportedEncodingException if the named encoding is
  109. * not supported.
  110. */
  111. public void setEncoding(String encoding)
  112. throws SecurityException, java.io.UnsupportedEncodingException {
  113. checkAccess();
  114. if (encoding != null) {
  115. // Check the encoding exists.
  116. sun.io.CharToByteConverter.getConverter(encoding);
  117. }
  118. this.encoding = encoding;
  119. }
  120. /**
  121. * Return the character encoding for this <tt>Handler</tt>.
  122. *
  123. * @return The encoding name. May be null, which indicates the
  124. * default encoding should be used.
  125. */
  126. public String getEncoding() {
  127. return encoding;
  128. }
  129. /**
  130. * Set a <tt>Filter</tt> to control output on this <tt>Handler</tt>.
  131. * <P>
  132. * For each call of <tt>publish</tt> the <tt>Handler</tt> will call
  133. * this <tt>Filter</tt> (if it is non-null) to check if the
  134. * <tt>LogRecord</tt> should be published or discarded.
  135. *
  136. * @param newFilter a <tt>Filter</tt> object (may be null)
  137. * @exception SecurityException if a security manager exists and if
  138. * the caller does not have <tt>LoggingPermission("control")</tt>.
  139. */
  140. public void setFilter(Filter newFilter) throws SecurityException {
  141. checkAccess();
  142. filter = newFilter;
  143. }
  144. /**
  145. * Get the current <tt>Filter</tt> for this <tt>Handler</tt>.
  146. *
  147. * @return a </tt>Filter</tt> object (may be null)
  148. */
  149. public Filter getFilter() {
  150. return filter;
  151. }
  152. /**
  153. * Define an ErrorManager for this Handler.
  154. * <p>
  155. * The ErrorManager's "error" method will be invoked if any
  156. * errors occur while using this Handler.
  157. *
  158. * @param em the new ErrorManager
  159. * @exception SecurityException if a security manager exists and if
  160. * the caller does not have <tt>LoggingPermission("control")</tt>.
  161. */
  162. public void setErrorManager(ErrorManager em) {
  163. checkAccess();
  164. if (em == null) {
  165. throw new NullPointerException();
  166. }
  167. errorManager = em;
  168. }
  169. /**
  170. * Retrieves the ErrorManager for this Handler.
  171. *
  172. * @exception SecurityException if a security manager exists and if
  173. * the caller does not have <tt>LoggingPermission("control")</tt>.
  174. */
  175. public ErrorManager getErrorManager() {
  176. checkAccess();
  177. return errorManager;
  178. }
  179. /**
  180. * Protected convenience method to report an error to this Handler's
  181. * ErrorManager. Note that this method retrieves and uses the ErrorManager
  182. * without doing a security check. It can therefore be used in
  183. * environments where the caller may be non-privileged.
  184. *
  185. * @param msg a descriptive string (may be null)
  186. * @param ex an exception (may be null)
  187. * @param code an error code defined in ErrorManager
  188. */
  189. protected void reportError(String msg, Exception ex, int code) {
  190. try {
  191. errorManager.error(msg, ex, code);
  192. } catch (Exception ex2) {
  193. System.err.println("Handler.reportError caught:");
  194. ex2.printStackTrace();
  195. }
  196. }
  197. /**
  198. * Set the log level specifying which message levels will be
  199. * logged by this <tt>Handler</tt>. Message levels lower than this
  200. * value will be discarded.
  201. * <p>
  202. * The intention is to allow developers to turn on voluminous
  203. * logging, but to limit the messages that are sent to certain
  204. * <tt>Handlers</tt>.
  205. *
  206. * @param newLevel the new value for the log level
  207. * @exception SecurityException if a security manager exists and if
  208. * the caller does not have <tt>LoggingPermission("control")</tt>.
  209. */
  210. public synchronized void setLevel(Level newLevel) throws SecurityException {
  211. if (newLevel == null) {
  212. throw new NullPointerException();
  213. }
  214. checkAccess();
  215. logLevel = newLevel;
  216. }
  217. /**
  218. * Get the log level specifying which messages will be
  219. * logged by this <tt>Handler</tt>. Message levels lower
  220. * than this level will be discarded.
  221. * @return the level of messages being logged.
  222. */
  223. public synchronized Level getLevel() {
  224. return logLevel;
  225. }
  226. /**
  227. * Check if this <tt>Handler</tt> would actually log a given <tt>LogRecord</tt>.
  228. * <p>
  229. * This method checks if the <tt>LogRecord</tt> has an appropriate
  230. * <tt>Level</tt> and whether it satisfies any <tt>Filter</tt>. It also
  231. * may make other <tt>Handler</tt> specific checks that might prevent a
  232. * handler from logging the <tt>LogRecord</tt>. It will return false if
  233. * the <tt>LogRecord</tt> is Null.
  234. * <p>
  235. * @param record a <tt>LogRecord</tt>
  236. * @return true if the <tt>LogRecord</tt> would be logged.
  237. *
  238. */
  239. public boolean isLoggable(LogRecord record) {
  240. int levelValue = getLevel().intValue();
  241. if (record.getLevel().intValue() < levelValue || levelValue == offValue) {
  242. return false;
  243. }
  244. Filter filter = getFilter();
  245. if (filter == null) {
  246. return true;
  247. }
  248. return filter.isLoggable(record);
  249. }
  250. // Package-private support method for security checks.
  251. // If "sealed" is true, we check that the caller has
  252. // appropriate security privileges to update Handler
  253. // state and if not throw a SecurityException.
  254. void checkAccess() throws SecurityException {
  255. if (sealed) {
  256. manager.checkAccess();
  257. }
  258. }
  259. }