001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.commons.discovery.log;
018:
019: import java.lang.reflect.Method;
020: import java.util.Enumeration;
021: import java.util.Hashtable;
022:
023: import org.apache.commons.discovery.DiscoveryException;
024: import org.apache.commons.discovery.tools.ClassUtils;
025: import org.apache.commons.logging.Log;
026: import org.apache.commons.logging.LogFactory;
027:
028: /**
029: * <p>Simple implementation of Log that sends all enabled log messages,
030: * for all defined loggers, to System.err.
031: * </p>
032: *
033: * <p>Hacked from commons-logging SimpleLog for use in discovery.
034: * This is intended to be enough of a Log implementation to bootstrap
035: * Discovery.
036: * </p>
037: *
038: * <p>One property: <code>org.apache.commons.discovery.log.level</code>.
039: * valid values: all, trace, debug, info, warn, error, fatal, off.
040: * </p>
041: *
042: * @author Richard A. Sitze
043: * @author <a href="mailto:sanders@apache.org">Scott Sanders</a>
044: * @author Rod Waldhoff
045: * @author Robert Burrell Donkin
046: *
047: * @version $Id: DiscoveryLogFactory.java 480374 2006-11-29 03:33:25Z niallp $
048: */
049: public class DiscoveryLogFactory {
050: private static LogFactory logFactory = null;
051: private static final Hashtable classRegistry = new Hashtable();
052: private static final Class[] setLogParamClasses = new Class[] { Log.class };
053:
054: /**
055: * Above fields must be initialied before this one..
056: */
057: private static Log log = DiscoveryLogFactory
058: ._newLog(DiscoveryLogFactory.class);
059:
060: /**
061: */
062: public static Log newLog(Class clazz) {
063: /**
064: * Required to implement 'public static void setLog(Log)'
065: */
066: try {
067: Method setLog = ClassUtils.findPublicStaticMethod(clazz,
068: void.class, "setLog", setLogParamClasses);
069:
070: if (setLog == null) {
071: String msg = "Internal Error: "
072: + clazz.getName()
073: + " required to implement 'public static void setLog(Log)'";
074: log.fatal(msg);
075: throw new DiscoveryException(msg);
076: }
077: } catch (SecurityException se) {
078: String msg = "Required Security Permissions not present";
079: log.fatal(msg, se);
080: throw new DiscoveryException(msg, se);
081: }
082:
083: if (log.isDebugEnabled())
084: log.debug("Class meets requirements: " + clazz.getName());
085:
086: return _newLog(clazz);
087: }
088:
089: /**
090: * This method MUST not invoke any logging..
091: */
092: public static Log _newLog(Class clazz) {
093: classRegistry.put(clazz, clazz);
094:
095: return (logFactory == null) ? new SimpleLog(clazz.getName())
096: : logFactory.getInstance(clazz.getName());
097: }
098:
099: public static void setLog(Log _log) {
100: log = _log;
101: }
102:
103: /**
104: * Set logFactory, works ONLY on first call.
105: */
106: public static void setFactory(LogFactory factory) {
107: if (logFactory == null) {
108: // for future generations.. if any
109: logFactory = factory;
110:
111: // now, go back and reset loggers for all current classes..
112: Enumeration elements = classRegistry.elements();
113: while (elements.hasMoreElements()) {
114: Class clazz = (Class) elements.nextElement();
115:
116: if (log.isDebugEnabled())
117: log.debug("Reset Log for: " + clazz.getName());
118:
119: Method setLog = null;
120:
121: // invoke 'setLog(Log)'.. we already know it's 'public static',
122: // have verified parameters, and return type..
123: try {
124: setLog = clazz.getMethod("setLog",
125: setLogParamClasses);
126: } catch (Exception e) {
127: String msg = "Internal Error: pre-check for "
128: + clazz.getName() + " failed?!";
129: log.fatal(msg, e);
130: throw new DiscoveryException(msg, e);
131: }
132:
133: Object[] setLogParam = new Object[] { factory
134: .getInstance(clazz.getName()) };
135:
136: try {
137: setLog.invoke(null, setLogParam);
138: } catch (Exception e) {
139: String msg = "Internal Error: setLog failed for "
140: + clazz.getName();
141: log.fatal(msg, e);
142: throw new DiscoveryException(msg, e);
143: }
144: }
145: }
146: }
147: }
|