001: /**
002: *
003: */package logging;
004:
005: import java.util.Enumeration;
006: import org.apache.log4j.Appender;
007: import org.apache.log4j.Category;
008: import org.apache.log4j.Level;
009: import org.apache.log4j.Logger;
010: import org.apache.log4j.Hierarchy;
011: import org.apache.log4j.spi.HierarchyEventListener;
012: import org.apache.log4j.spi.LoggerFactory;
013: import org.apache.log4j.spi.RootCategory;
014: import java.util.Properties;
015: import org.apache.log4j.PropertyConfigurator;
016: import org.eclipse.core.runtime.ILog;
017: import org.eclipse.core.runtime.IPath;
018: import org.eclipse.core.runtime.Plugin;
019: import java.util.HashMap;
020: import java.util.Iterator;
021:
022: /**
023: * PluginLogManager
024: * This class encapsulates a Log4J Hierarchy and centralizes all Logger access.
025: * @author Manoel Marques
026: */
027: public class PluginLogManager {
028:
029: private ILog log;
030: private IPath stateLocation;
031: private Hierarchy hierarchy;
032: private HashMap hookedPlugins = new HashMap();
033:
034: private class PluginEventListener implements HierarchyEventListener {
035:
036: /**
037: * Called when a new appender is added for a particular level.
038: * Internally it checks if the appender is one of our custom ones
039: * and sets its custom properties.
040: * @param category level
041: * @param appender appender added for this level
042: */
043: public void addAppenderEvent(Category cat, Appender appender) {
044: if (appender instanceof PluginLogAppender) {
045: ((PluginLogAppender) appender).setLog(log);
046: }
047: if (appender instanceof PluginFileAppender) {
048: ((PluginFileAppender) appender)
049: .setStateLocation(stateLocation);
050: }
051: }
052:
053: /**
054: * Called when a appender is removed from for a particular level.
055: * Does nothing.
056: * @param category level
057: * @param appender appender added for this level
058: */
059: public void removeAppenderEvent(Category cat, Appender appender) {
060: }
061: }
062:
063: /**
064: * Creates a new PluginLogManager. Saves the plug-in log and state location.
065: * Creates a new Hierarchy and add a new PluginEventListener to it.
066: * Configure the hierarchy with the properties passed.
067: * Add this object to the lits of acctive plug-in log managers.
068: * @param plugin the plug-in object
069: * @param properties log configuration properties
070: */
071: public PluginLogManager(Plugin plugin, Properties properties) {
072: this .log = plugin.getLog();
073: this .stateLocation = plugin.getStateLocation();
074: this .hierarchy = new Hierarchy(new RootCategory(Level.DEBUG));
075: this .hierarchy
076: .addHierarchyEventListener(new PluginEventListener());
077: new PropertyConfigurator().doConfigure(properties,
078: this .hierarchy);
079: LoggingPlugin.getDefault().addLogManager(this );
080: }
081:
082: /**
083: * Hooks a plug-in into this PluginLogManager. When the hooked plug-in uses the
084: * Eclipse log API, it will be channeled to this logging framework.
085: * @param id logger name (usually the the plug-in id)
086: * @param log plug-in log
087: */
088: public boolean hookPlugin(String id, ILog log) {
089: synchronized (this .hookedPlugins) {
090: if (log == null || id == null
091: || this .hookedPlugins.containsKey(id))
092: return false;
093:
094: PluginLogListener listener = new PluginLogListener(log,
095: getLogger(id));
096: this .hookedPlugins.put(id, listener);
097: }
098: return true;
099: }
100:
101: /**
102: * Unhooks a plug-in from this PluginLogManager. The Eclipse log API
103: * won't be channeled to this logging framework anymore.
104: * @param id logger name (usually the the plug-in id)
105: */
106: public boolean unHookPlugin(String id) {
107: synchronized (this .hookedPlugins) {
108: if (id == null || !this .hookedPlugins.containsKey(id))
109: return false;
110:
111: PluginLogListener listener = (PluginLogListener) this .hookedPlugins
112: .get(id);
113: listener.dispose();
114: this .hookedPlugins.remove(id);
115: }
116: return true;
117: }
118:
119: /**
120: * Checks if this PluginLogManager is disabled for this level.
121: * @param level level value
122: * @return boolean true if it is disabled
123: */
124: public boolean isDisabled(int level) {
125: return this .hierarchy.isDisabled(level);
126: }
127:
128: /**
129: * Enable logging for logging requests with level l or higher.
130: * By default all levels are enabled.
131: * @param level level object
132: */
133: public void setThreshold(Level level) {
134: this .hierarchy.setThreshold(level);
135: }
136:
137: /**
138: * The string version of setThreshold(Level level)
139: * @param level level string
140: */
141: public void setThreshold(String level) {
142: this .hierarchy.setThreshold(level);
143: }
144:
145: /**
146: * Get the repository-wide threshold.
147: * @return Level
148: */
149: public Level getThreshold() {
150: return this .hierarchy.getThreshold();
151: }
152:
153: /**
154: * Returns a new logger instance named as the first parameter
155: * using the default factory. If a logger of that name already exists,
156: * then it will be returned. Otherwise, a new logger will be instantiated
157: * and then linked with its existing ancestors as well as children.
158: * @param name logger name
159: * @return Logger
160: */
161: public Logger getLogger(String name) {
162: return this .hierarchy.getLogger(name);
163: }
164:
165: /**
166: * The same as getLogger(String name) but using a factory instance instead of
167: * a default factory.
168: * @param name logger name
169: * @param factory factory instance
170: * @return Logger
171: */
172: public Logger getLogger(String name, LoggerFactory factory) {
173: return this .hierarchy.getLogger(name, factory);
174: }
175:
176: /**
177: * Returns the root of this hierarchy.
178: * @return Logger
179: */
180: public Logger getRootLogger() {
181: return this .hierarchy.getRootLogger();
182: }
183:
184: /**
185: * Checks if this logger exists.
186: * @return Logger
187: */
188: public Logger exists(String name) {
189: return this .hierarchy.exists(name);
190: }
191:
192: /**
193: * Removes appenders and disposes the logger hierarchy
194: *
195: */
196: public void shutdown() {
197: internalShutdown();
198: LoggingPlugin.getDefault().removeLogManager(this );
199: }
200:
201: /**
202: * Used by LoggingPlugin to shutdown without removing it from the LoggingPlugin list
203: *
204: */
205: void internalShutdown() {
206: synchronized (this .hookedPlugins) {
207: Iterator it = this .hookedPlugins.keySet().iterator();
208: while (it.hasNext()) {
209: String id = (String) it.next();
210: PluginLogListener listener = (PluginLogListener) this .hookedPlugins
211: .get(id);
212: listener.dispose();
213: }
214: this .hookedPlugins.clear();
215: }
216: this .hierarchy.shutdown();
217: }
218:
219: /**
220: * Returns all the loggers in this manager.
221: * @return Enumeration logger enumeration
222: */
223: public Enumeration getCurrentLoggers() {
224: return this .hierarchy.getCurrentLoggers();
225: }
226:
227: /**
228: * Resets configuration values to its defaults.
229: *
230: */
231: public void resetConfiguration() {
232: this.hierarchy.resetConfiguration();
233: }
234: }
|