You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

MessageHandler.java 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. /*
  2. * $Id$
  3. * ============================================================================
  4. * The Apache Software License, Version 1.1
  5. * ============================================================================
  6. *
  7. * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
  8. *
  9. * Redistribution and use in source and binary forms, with or without modifica-
  10. * tion, are permitted provided that the following conditions are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright notice,
  13. * this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright notice,
  16. * this list of conditions and the following disclaimer in the documentation
  17. * and/or other materials provided with the distribution.
  18. *
  19. * 3. The end-user documentation included with the redistribution, if any, must
  20. * include the following acknowledgment: "This product includes software
  21. * developed by the Apache Software Foundation (http://www.apache.org/)."
  22. * Alternately, this acknowledgment may appear in the software itself, if
  23. * and wherever such third-party acknowledgments normally appear.
  24. *
  25. * 4. The names "FOP" and "Apache Software Foundation" must not be used to
  26. * endorse or promote products derived from this software without prior
  27. * written permission. For written permission, please contact
  28. * apache@apache.org.
  29. *
  30. * 5. Products derived from this software may not be called "Apache", nor may
  31. * "Apache" appear in their name, without prior written permission of the
  32. * Apache Software Foundation.
  33. *
  34. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  35. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  36. * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  37. * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  38. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
  39. * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  40. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  41. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  42. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  43. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  44. * ============================================================================
  45. *
  46. * This software consists of voluntary contributions made by many individuals
  47. * on behalf of the Apache Software Foundation and was originally created by
  48. * James Tauber <jtauber@jtauber.com>. For more information on the Apache
  49. * Software Foundation, please see <http://www.apache.org/>.
  50. */
  51. package org.apache.fop.messaging;
  52. import org.apache.avalon.framework.logger.ConsoleLogger;
  53. import org.apache.avalon.framework.logger.Logger;
  54. import java.io.PrintWriter;
  55. import java.io.IOException;
  56. import java.io.FileWriter;
  57. import java.util.Vector;
  58. import java.util.Enumeration;
  59. /**
  60. * The class MessageHandler contains the static methods log and error which
  61. * should be used for any end user information instead of System.out.print() or
  62. * System.err.print(). The class defines several output methods:
  63. * writing to the screen (default), logging to a file, creating message events and repressing all
  64. * output. If you don't want to change the default behaviour, you should be
  65. * happy with MessageHandler.log(message) and MessageHandler.error(message)<br>
  66. * The class MessageHandler also supports the setting of an id. If set every message
  67. * has as a prefix an identifying string. That way Fop probably can also be used in
  68. * environments, where more than one Fop instance are running in same JVM.<br>
  69. * If Fop is embedded in a gui application or for any reasons the existing
  70. * messaging system doesn't meet the programmer's requirements, one can add
  71. * a MessageEvent listener to MessageHandler and handle the incoming messages
  72. * in an appropriate way. See the class DefaultMessageListener, which is a trivial
  73. * implementation of the MessageListener.
  74. * Here is an example how to configure MessageHandler for the DefaultMessageListener (anybody
  75. * can provide his own listener by extending MessageListener<br>
  76. * <code>
  77. * MessageHandler.setOutputMethod(MessageHandler.EVENT);
  78. * MessageHandler.addListener(new DefaultMessageListener());
  79. * </code><br>
  80. * This examples shows, how to redirect the messages to a log file called fop.log.
  81. * All messages are appended to this file.
  82. * <code>
  83. * MessageHandler.setOutputMethod(MessageHandler.FILE);
  84. * MessageHandler.setLogfileName("\\fop.log",true);
  85. * </code>
  86. */
  87. public class MessageHandler {
  88. public static final int SCREEN = 0;
  89. public static final int FILE = 1;
  90. public static final int EVENT = 2;
  91. public static final int NONE = 3; // this should always be the last method
  92. private static Logger logger = null;
  93. private static String logfileName = "fop.log";
  94. private static PrintWriter writer;
  95. private static int outputMethod = SCREEN;
  96. private static boolean fileOpened = false;
  97. private static boolean appendToFile = true;
  98. private static String message = "";
  99. private static String prefix = "";
  100. private static Vector listeners = new Vector();
  101. private static boolean IDisSet = false;
  102. private static boolean quiet = false;
  103. /**
  104. * helper class to access the message
  105. * @return a string containing the message
  106. */
  107. private static String getMessage() {
  108. return message;
  109. }
  110. /**
  111. * helper class which sets the message
  112. * and adds a prefix which can contain
  113. * the id of the thread which uses this messagehandler
  114. */
  115. private static void setMessage(String m) {
  116. if (IDisSet) {
  117. message = getID() + ":" + m;
  118. } else {
  119. message = m;
  120. }
  121. }
  122. /**
  123. * informs the user of the message
  124. * @param message the message for the user
  125. */
  126. public static void log(String message) {
  127. if (quiet) {
  128. return;
  129. }
  130. if (logger == null) {
  131. logger = new ConsoleLogger(ConsoleLogger.LEVEL_INFO);
  132. logger.warn("Screen logger not set - Using ConsoleLogger.");
  133. }
  134. setMessage(message);
  135. switch (outputMethod) {
  136. case SCREEN:
  137. logger.info(getMessage());
  138. break;
  139. case FILE:
  140. if (fileOpened) {
  141. writer.print(getMessage());
  142. writer.flush();
  143. } else {
  144. openFile();
  145. writer.print(getMessage());
  146. writer.flush();
  147. }
  148. break;
  149. case EVENT:
  150. setMessage(message);
  151. Enumeration en = listeners.elements();
  152. while (en.hasMoreElements()) {
  153. ((MessageListener)en.nextElement()).processMessage(new MessageEvent(getMessage()));
  154. }
  155. break;
  156. case NONE:
  157. // do nothing
  158. break;
  159. default:
  160. logger.info(message);
  161. }
  162. }
  163. /**
  164. * convenience method which adds a return to the message
  165. * @param message the message for the user
  166. */
  167. public static void logln(String message) {
  168. log(message);
  169. }
  170. /**
  171. * error warning for the user
  172. * @param errorMessage contains the warning string
  173. */
  174. public static void error(String errorMessage) {
  175. if (logger == null) {
  176. logger = new ConsoleLogger(ConsoleLogger.LEVEL_INFO);
  177. logger.warn("Screen logger not set - Using ConsoleLogger.");
  178. }
  179. setMessage(errorMessage);
  180. switch (outputMethod) {
  181. case SCREEN:
  182. logger.error(getMessage());
  183. break;
  184. case FILE:
  185. if (fileOpened) {
  186. writer.print(getMessage());
  187. writer.flush();
  188. } else {
  189. openFile();
  190. writer.print(getMessage());
  191. writer.flush();
  192. }
  193. break;
  194. case EVENT:
  195. setMessage(message);
  196. Enumeration en = listeners.elements();
  197. while (en.hasMoreElements()) {
  198. MessageEvent messEv = new MessageEvent(getMessage());
  199. messEv.setMessageType(MessageEvent.ERROR);
  200. ((MessageListener)en.nextElement()).processMessage(messEv);
  201. }
  202. break;
  203. case NONE:
  204. // do nothing
  205. break;
  206. default:
  207. logger.error(errorMessage);
  208. }
  209. }
  210. /**
  211. * convenience method which adds a return to the error message
  212. * @param errorMessage the message for the user
  213. */
  214. public static void errorln(String errorMessage) {
  215. error(errorMessage);
  216. }
  217. /**
  218. * adds a MessageListener which listens for MessageEvents
  219. * @param MessageListener the listener to add
  220. */
  221. public static void addListener(MessageListener listener) {
  222. listeners.add(listener);
  223. }
  224. /**
  225. * removes a MessageListener
  226. * @param MessageListener the listener to remove
  227. */
  228. public static void removeListener(MessageListener listener) {
  229. listeners.removeElement(listener);
  230. }
  231. /**
  232. * Sets the Logger used for the screen output method.
  233. * @param newLogger a logger for screen output. This may not be null.
  234. */
  235. public static void setScreenLogger(Logger newLogger) {
  236. if (newLogger == null)
  237. throw new NullPointerException();
  238. logger = newLogger;
  239. }
  240. /**
  241. * sets the output method
  242. * @param method the output method to use, allowed values are<br>
  243. * MessageHandler.SCREEN, MessageHandler.FILE, MessageHandler.EVENT
  244. * MessageHandler.NONE
  245. */
  246. public static void setOutputMethod(int method) {
  247. if (method > NONE) {
  248. MessageHandler.error("Error: Unknown output method");
  249. } else {
  250. outputMethod = method;
  251. }
  252. }
  253. /**
  254. * informs what output method is set
  255. * @return the output method
  256. */
  257. public static int getOutputMethod() {
  258. return outputMethod;
  259. }
  260. /**
  261. * sets the logfile name
  262. * @param filename name of the logfile
  263. * @param append if true, the logfile is appended
  264. */
  265. public static void setLogfileName(String filename, boolean append) {
  266. logfileName = filename;
  267. appendToFile = append;
  268. }
  269. /**
  270. * returns the logfile name
  271. * @return String containing the logfile name
  272. */
  273. public static String getLogfileName() {
  274. return logfileName;
  275. }
  276. /**
  277. * helper file which opens the file for output method FILE
  278. */
  279. private static void openFile() {
  280. try {
  281. writer =
  282. new PrintWriter(new FileWriter(logfileName, appendToFile),
  283. true);
  284. writer.println("\n==============================================");
  285. fileOpened = true;
  286. } catch (IOException ioe) {
  287. System.err.println("Error: " + ioe);
  288. }
  289. }
  290. /**
  291. * if set to true an id string is prefixed to every message
  292. * uses the thread info as an id for the message producer. Should be used if
  293. * more than one instance of Fop is running in the same JVM
  294. * this id becomes a prefix to every message
  295. */
  296. private static String getID() {
  297. return Thread.currentThread().toString();
  298. }
  299. /**
  300. * if set to true an id string is prefixed to every message
  301. * uses the thread info as an id for the message producer. Should be used if
  302. * more than one instance of Fop is running in the same JVM
  303. * this id becomes a prefix to every message
  304. *
  305. * @param id boolean (default is false)
  306. */
  307. public static void setID(boolean id) {
  308. IDisSet = id;
  309. }
  310. /**
  311. * if set to true all normal messages are suppressed.
  312. * error messages are displayed allthesame
  313. *
  314. * @param quietMode boolean (default is false)
  315. */
  316. public static void setQuiet(boolean quietMode) {
  317. quiet = quietMode;
  318. }
  319. }