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.Hashtable;
021 import java.util.Map;
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 * @deprecated Starting from commons-discovery-05, Log is totally delegated to commons-logging
043 * @version $Id: DiscoveryLogFactory.java 1089255 2011-04-05 21:51:05Z simonetripodi $
044 */
045 @Deprecated
046 public class DiscoveryLogFactory {
047
048 private static LogFactory logFactory = null;
049
050 private static final Map<Class<?>, Class<?>> classRegistry = new Hashtable<Class<?>, Class<?>>();
051
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._newLog(DiscoveryLogFactory.class);
058
059 /**
060 * Creates a new {@code Log} instance for the input class.
061 *
062 * @param clazz The class the log has to be created for
063 * @return The input class logger
064 */
065 public static Log newLog(Class<?> clazz) {
066 /**
067 * Required to implement 'public static void setLog(Log)'
068 */
069 try {
070 Method setLog = ClassUtils.findPublicStaticMethod(clazz,
071 void.class,
072 "setLog",
073 setLogParamClasses);
074
075 if (setLog == null) {
076 String msg = "Internal Error: "
077 + clazz.getName()
078 + " required to implement 'public static void setLog(Log)'";
079 log.fatal(msg);
080 throw new DiscoveryException(msg);
081 }
082 } catch (SecurityException se) {
083 String msg = "Required Security Permissions not present";
084 log.fatal(msg, se);
085 throw new DiscoveryException(msg, se);
086 }
087
088 if (log.isDebugEnabled()) {
089 log.debug("Class meets requirements: " + clazz.getName());
090 }
091
092 return _newLog(clazz);
093 }
094
095 /**
096 * This method MUST not invoke any logging..
097 *
098 * @param clazz The class the log has to be created for
099 * @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 }