1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.discovery.log;
18
19 import java.lang.reflect.Method;
20 import java.util.Hashtable;
21 import java.util.Map;
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 * <p>Simple implementation of Log that sends all enabled log messages,
30 * for all defined loggers, to System.err.
31 * </p>
32 *
33 * <p>Hacked from commons-logging SimpleLog for use in discovery.
34 * This is intended to be enough of a Log implementation to bootstrap
35 * Discovery.
36 * </p>
37 *
38 * <p>One property: <code>org.apache.commons.discovery.log.level</code>.
39 * valid values: all, trace, debug, info, warn, error, fatal, off.
40 * </p>
41 *
42 * @deprecated Starting from commons-discovery-05, Log is totally delegated to commons-logging
43 * @version $Id: DiscoveryLogFactory.java 1089255 2011-04-05 21:51:05Z simonetripodi $
44 */
45 @Deprecated
46 public class DiscoveryLogFactory {
47
48 private static LogFactory logFactory = null;
49
50 private static final Map<Class<?>, Class<?>> classRegistry = new Hashtable<Class<?>, Class<?>>();
51
52 private static final Class<?>[] setLogParamClasses = new Class<?>[] { Log.class };
53
54 /**
55 * Above fields must be initialied before this one..
56 */
57 private static Log log = DiscoveryLogFactory._newLog(DiscoveryLogFactory.class);
58
59 /**
60 * Creates a new {@code Log} instance for the input class.
61 *
62 * @param clazz The class the log has to be created for
63 * @return The input class logger
64 */
65 public static Log newLog(Class<?> clazz) {
66 /**
67 * Required to implement 'public static void setLog(Log)'
68 */
69 try {
70 Method setLog = ClassUtils.findPublicStaticMethod(clazz,
71 void.class,
72 "setLog",
73 setLogParamClasses);
74
75 if (setLog == null) {
76 String msg = "Internal Error: "
77 + clazz.getName()
78 + " required to implement 'public static void setLog(Log)'";
79 log.fatal(msg);
80 throw new DiscoveryException(msg);
81 }
82 } catch (SecurityException se) {
83 String msg = "Required Security Permissions not present";
84 log.fatal(msg, se);
85 throw new DiscoveryException(msg, se);
86 }
87
88 if (log.isDebugEnabled()) {
89 log.debug("Class meets requirements: " + clazz.getName());
90 }
91
92 return _newLog(clazz);
93 }
94
95 /**
96 * This method MUST not invoke any logging..
97 *
98 * @param clazz The class the log has to be created for
99 * @return The input class logger
100 */
101 public static Log _newLog(Class<?> clazz) {
102 classRegistry.put(clazz, clazz);
103
104 return (logFactory == null)
105 ? new SimpleLog(clazz.getName())
106 : logFactory.getInstance(clazz.getName());
107 }
108
109 /**
110 * Sets the {@code Log} for this class.
111 *
112 * @param _log This class {@code Log}
113 */
114 public static void setLog(Log _log) {
115 log = _log;
116 }
117
118 /**
119 * Set logFactory, works ONLY on first call.
120 *
121 * @param factory The log factory
122 */
123 public static void setFactory(LogFactory factory) {
124 if (logFactory == null) {
125 // for future generations.. if any
126 logFactory = factory;
127
128 // now, go back and reset loggers for all current classes..
129 for (Class<?> clazz : classRegistry.values()) {
130
131 if (log.isDebugEnabled()) {
132 log.debug("Reset Log for: " + clazz.getName());
133 }
134
135 Method setLog = null;
136
137 // invoke 'setLog(Log)'.. we already know it's 'public static',
138 // have verified parameters, and return type..
139 try {
140 setLog = clazz.getMethod("setLog", setLogParamClasses);
141 } catch(Exception e) {
142 String msg = "Internal Error: pre-check for " + clazz.getName() + " failed?!";
143 log.fatal(msg, e);
144 throw new DiscoveryException(msg, e);
145 }
146
147 Object[] setLogParam = new Object[] { factory.getInstance(clazz.getName()) };
148
149 try {
150 setLog.invoke(null, setLogParam);
151 } catch(Exception e) {
152 String msg = "Internal Error: setLog failed for " + clazz.getName();
153 log.fatal(msg, e);
154 throw new DiscoveryException(msg, e);
155 }
156 }
157 }
158 }
159
160 }