1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.discovery.log;
18
19 import java.lang.reflect.Method;
20 import java.util.Enumeration;
21 import java.util.Hashtable;
22
23 import org.apache.commons.discovery.DiscoveryException;
24 import org.apache.commons.discovery.tools.ClassUtils;
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27
28
29 /***
30 * <p>Simple implementation of Log that sends all enabled log messages,
31 * for all defined loggers, to System.err.
32 * </p>
33 *
34 * <p>Hacked from commons-logging SimpleLog for use in discovery.
35 * This is intended to be enough of a Log implementation to bootstrap
36 * Discovery.
37 * </p>
38 *
39 * <p>One property: <code>org.apache.commons.discovery.log.level</code>.
40 * valid values: all, trace, debug, info, warn, error, fatal, off.
41 * </p>
42 *
43 * @author Richard A. Sitze
44 * @author <a href="mailto:sanders@apache.org">Scott Sanders</a>
45 * @author Rod Waldhoff
46 * @author Robert Burrell Donkin
47 *
48 * @version $Id: DiscoveryLogFactory.java 480374 2006-11-29 03:33:25Z niallp $
49 */
50 public class DiscoveryLogFactory {
51 private static LogFactory logFactory = null;
52 private static final Hashtable classRegistry = new Hashtable();
53 private static final Class[] setLogParamClasses = new Class[] { Log.class };
54
55 /***
56 * Above fields must be initialied before this one..
57 */
58 private static Log log = DiscoveryLogFactory._newLog(DiscoveryLogFactory.class);
59
60 /***
61 */
62 public static Log newLog(Class clazz) {
63 /***
64 * Required to implement 'public static void setLog(Log)'
65 */
66 try {
67 Method setLog = ClassUtils.findPublicStaticMethod(clazz,
68 void.class,
69 "setLog",
70 setLogParamClasses);
71
72 if (setLog == null) {
73 String msg = "Internal Error: " + clazz.getName() + " required to implement 'public static void setLog(Log)'";
74 log.fatal(msg);
75 throw new DiscoveryException(msg);
76 }
77 } catch (SecurityException se) {
78 String msg = "Required Security Permissions not present";
79 log.fatal(msg, se);
80 throw new DiscoveryException(msg, se);
81 }
82
83 if (log.isDebugEnabled())
84 log.debug("Class meets requirements: " + clazz.getName());
85
86 return _newLog(clazz);
87 }
88
89 /***
90 * This method MUST not invoke any logging..
91 */
92 public static Log _newLog(Class clazz) {
93 classRegistry.put(clazz, clazz);
94
95 return (logFactory == null)
96 ? new SimpleLog(clazz.getName())
97 : logFactory.getInstance(clazz.getName());
98 }
99
100 public static void setLog(Log _log) {
101 log = _log;
102 }
103
104 /***
105 * Set logFactory, works ONLY on first call.
106 */
107 public static void setFactory(LogFactory factory) {
108 if (logFactory == null) {
109
110 logFactory = factory;
111
112
113 Enumeration elements = classRegistry.elements();
114 while (elements.hasMoreElements()) {
115 Class clazz = (Class)elements.nextElement();
116
117 if (log.isDebugEnabled())
118 log.debug("Reset Log for: " + clazz.getName());
119
120 Method setLog = null;
121
122
123
124 try {
125 setLog = clazz.getMethod("setLog", setLogParamClasses);
126 } catch(Exception e) {
127 String msg = "Internal Error: pre-check for " + clazz.getName() + " failed?!";
128 log.fatal(msg, e);
129 throw new DiscoveryException(msg, e);
130 }
131
132 Object[] setLogParam = new Object[] { factory.getInstance(clazz.getName()) };
133
134 try {
135 setLog.invoke(null, setLogParam);
136 } catch(Exception e) {
137 String msg = "Internal Error: setLog failed for " + clazz.getName();
138 log.fatal(msg, e);
139 throw new DiscoveryException(msg, e);
140 }
141 }
142 }
143 }
144 }