1. /*
  2. * @(#)Handler.java 1.13 03/01/23
  3. *
  4. * Copyright 2003 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.13, 01/23/03
  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
  55. */
  56. public abstract void publish(LogRecord record);
  57. /**
  58. * Flush any buffered output.
  59. */
  60. public abstract void flush();
  61. /**
  62. * Close the <tt>Handler</tt> and free all associated resources.
  63. * <p>
  64. * The close method will perform a <tt>flush</tt> and then close the
  65. * <tt>Handler</tt>. After close has been called this <tt>Handler</tt>
  66. * should no longer be used. Method calls may either be silently
  67. * ignored or may throw runtime exceptions.
  68. *
  69. * @exception SecurityException if a security manager exists and if
  70. * the caller does not have <tt>LoggingPermission("control")</tt>.
  71. */
  72. public abstract void close() throws SecurityException;
  73. /**
  74. * Set a <tt>Formatter</tt>. This <tt>Formatter</tt> will be used
  75. * to format <tt>LogRecords</tt> for this <tt>Handler</tt>.
  76. * <p>
  77. * Some <tt>Handlers</tt> may not use <tt>Formatters</tt>, in
  78. * which case the <tt>Formatter</tt> will be remembered, but not used.
  79. * <p>
  80. * @param newFormatter the <tt>Formatter</tt> to use (may not be null)
  81. * @exception SecurityException if a security manager exists and if
  82. * the caller does not have <tt>LoggingPermission("control")</tt>.
  83. */
  84. public void setFormatter(Formatter newFormatter) throws SecurityException {
  85. checkAccess();
  86. // Check for a null pointer:
  87. newFormatter.getClass();
  88. formatter = newFormatter;
  89. }
  90. /**
  91. * Return the <tt>Formatter</tt> for this <tt>Handler</tt>.
  92. * @return the <tt>Formatter</tt> (may be null).
  93. */
  94. public Formatter getFormatter() {
  95. return formatter;
  96. }
  97. /**
  98. * Set the character encoding used by this <tt>Handler</tt>.
  99. * <p>
  100. * The encoding should be set before any <tt>LogRecords</tt> are written
  101. * to the <tt>Handler</tt>.
  102. *
  103. * @param encoding The name of a supported character encoding.
  104. * May be null, to indicate the default platform encoding.
  105. * @exception SecurityException if a security manager exists and if
  106. * the caller does not have <tt>LoggingPermission("control")</tt>.
  107. * @exception UnsupportedEncodingException if the named encoding is
  108. * not supported.
  109. */
  110. public void setEncoding(String encoding)
  111. throws SecurityException, java.io.UnsupportedEncodingException {
  112. checkAccess();
  113. if (encoding != null) {
  114. // Check the encoding exists.
  115. sun.io.CharToByteConverter.getConverter(encoding);
  116. }
  117. this.encoding = encoding;
  118. }
  119. /**
  120. * Return the character encoding for this <tt>Handler</tt>.
  121. *
  122. * @return The encoding name. May be null, which indicates the
  123. * default encoding should be used.
  124. */
  125. public String getEncoding() {
  126. return encoding;
  127. }
  128. /**
  129. * Set a <tt>Filter</tt> to control output on this <tt>Handler</tt>.
  130. * <P>
  131. * For each call of <tt>publish</tt> the <tt>Handler</tt> will call
  132. * this <tt>Filter</tt> (if it is non-null) to check if the
  133. * <tt>LogRecord</tt> should be published or discarded.
  134. *
  135. * @param newFilter a <tt>Filter</tt> object (may be null)
  136. * @exception SecurityException if a security manager exists and if
  137. * the caller does not have <tt>LoggingPermission("control")</tt>.
  138. */
  139. public void setFilter(Filter newFilter) throws SecurityException {
  140. checkAccess();
  141. filter = newFilter;
  142. }
  143. /**
  144. * Get the current <tt>Filter</tt> for this <tt>Handler</tt>.
  145. *
  146. * @return a </tt>Filter</tt> object (may be null)
  147. */
  148. public Filter getFilter() {
  149. return filter;
  150. }
  151. /**
  152. * Define an ErrorManager for this Handler.
  153. * <p>
  154. * The ErrorManager's "error" method will be invoked if any
  155. * errors occur while using this Handler.
  156. *
  157. * @param em the new ErrorManager
  158. * @exception SecurityException if a security manager exists and if
  159. * the caller does not have <tt>LoggingPermission("control")</tt>.
  160. */
  161. public void setErrorManager(ErrorManager em) {
  162. checkAccess();
  163. if (em == null) {
  164. throw new NullPointerException();
  165. }
  166. errorManager = em;
  167. }
  168. /**
  169. * Retrieves the ErrorManager for this Handler.
  170. *
  171. * @exception SecurityException if a security manager exists and if
  172. * the caller does not have <tt>LoggingPermission("control")</tt>.
  173. */
  174. public ErrorManager getErrorManager() {
  175. checkAccess();
  176. return errorManager;
  177. }
  178. /**
  179. * Protected convenience method to report an error to this Handler's
  180. * ErrorManager. Note that this method retrieves and uses the ErrorManager
  181. * without doing a security check. It can therefore be used in
  182. * environments where the caller may be non-privileged.
  183. *
  184. * @param msg a descriptive string (may be null)
  185. * @param ex an exception (may be null)
  186. * @param code an error code defined in ErrorManager
  187. */
  188. protected void reportError(String msg, Exception ex, int code) {
  189. try {
  190. errorManager.error(msg, ex, code);
  191. } catch (Exception ex2) {
  192. System.err.println("Handler.reportError caught:");
  193. ex2.printStackTrace();
  194. }
  195. }
  196. /**
  197. * Set the log level specifying which message levels will be
  198. * logged by this <tt>Handler</tt>. Message levels lower than this
  199. * value will be discarded.
  200. * <p>
  201. * The intention is to allow developers to turn on voluminous
  202. * logging, but to limit the messages that are sent to certain
  203. * <tt>Handlers</tt>.
  204. *
  205. * @param newLevel the new value for the log level
  206. * @exception SecurityException if a security manager exists and if
  207. * the caller does not have <tt>LoggingPermission("control")</tt>.
  208. */
  209. public synchronized void setLevel(Level newLevel) throws SecurityException {
  210. if (newLevel == null) {
  211. throw new NullPointerException();
  212. }
  213. checkAccess();
  214. logLevel = newLevel;
  215. }
  216. /**
  217. * Get the log level specifying which messages will be
  218. * logged by this <tt>Handler</tt>. Message levels lower
  219. * than this level will be discarded.
  220. * @return the level of messages being logged.
  221. */
  222. public synchronized Level getLevel() {
  223. return logLevel;
  224. }
  225. /**
  226. * Check if this <tt>Handler</tt> would actually log a given <tt>LogRecord</tt>.
  227. * <p>
  228. * This method checks if the <tt>LogRecord</tt> has an appropriate
  229. * <tt>Level</tt> and whether it satisfies any <tt>Filter</tt>. It also
  230. * may make other <tt>Handler</tt> specific checks that might prevent a
  231. * handler from logging the <tt>LogRecord</tt>.
  232. * <p>
  233. * @param record a <tt>LogRecord</tt>
  234. * @return true if the <tt>LogRecord</tt> would be logged.
  235. *
  236. */
  237. public boolean isLoggable(LogRecord record) {
  238. int levelValue = getLevel().intValue();
  239. if (record.getLevel().intValue() < levelValue || levelValue == offValue) {
  240. return false;
  241. }
  242. Filter filter = getFilter();
  243. if (filter == null) {
  244. return true;
  245. }
  246. return filter.isLoggable(record);
  247. }
  248. // Package-private support method for security checks.
  249. // If "sealed" is true, we check that the caller has
  250. // appropriate security privileges to update Handler
  251. // state and if not throw a SeucirtyException.
  252. void checkAccess() throws SecurityException {
  253. if (sealed) {
  254. manager.checkAccess();
  255. }
  256. }
  257. }