KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > oddjob > logging > AbstractPollingArchiver


1 /*
2  * (c) Rob Gordon 2005
3  */

4 package org.oddjob.logging;
5
6 import java.util.HashMap JavaDoc;
7 import java.util.HashSet JavaDoc;
8 import java.util.Iterator JavaDoc;
9 import java.util.Map JavaDoc;
10 import java.util.Set JavaDoc;
11
12 import org.apache.log4j.Logger;
13
14 /**
15  * A LogArchiver which maintains it's log archives by polling.
16  * <p>
17  * This archiver will remove a component from it's list of components to poll
18  * when no more listeners are listening to it.
19  * <p>
20  * This archiver will only poll the first component where many components share
21  * the same archive.
22  *
23  * @author Rob Gordon
24  */

25 abstract public class AbstractPollingArchiver {
26     private static final Logger logger = Logger.getLogger(AbstractPollingArchiver.class);
27     
28     /** A local LogArchiver we delegate to. */
29     private final AbstractArchiverCache cache;
30     
31     /** Componts we want events for and there id */
32     private final Map JavaDoc /*<Object, String>*/ components = new HashMap JavaDoc();
33     
34     /** How many listeners are listening to a component. */
35     private SimpleCounter listenerCounter = new SimpleCounter();
36     
37     /**
38      * Constructor.
39      *
40      */

41     public AbstractPollingArchiver(AbstractArchiverCache cache) {
42         this.cache = cache;
43     }
44
45     /**
46      * Add a LogListener for the given component.
47      *
48      * @param l The LogListener.
49      * @param component The component.
50      * @param level The level.
51      * @param last The last message number required.
52      * @param max The maximum history.
53      */

54     public void addArchiveListener(LogListener l, Object JavaDoc component,
55             LogLevel level, long last, int max) {
56         String JavaDoc archive = archiveFor(component);
57         logger.debug("Adding LogListener for [" + archive + "]");
58         if (archive == null) {
59             l.logEvent(AbstractArchiverCache.NO_LOG_AVAILABLE);
60             return;
61         }
62         synchronized (components) {
63             components.put(component, archive);
64             listenerCounter.add(component);
65             cache.addLogListener(l, archive,
66                     level, last, max);
67         }
68     }
69     
70     /**
71      * Remove the LogListener for the given component.
72      *
73      * @param l The LogListener.
74      * @param component The component.
75      */

76     public void removeArchiveListener(LogListener l, final Object JavaDoc component) {
77         synchronized (components) {
78             String JavaDoc archive = (String JavaDoc) components.get(component);
79             if (archive == null) {
80                 return;
81             }
82             if (cache.removeLogListener(l, archive)) {
83                 // if the cache had the listener then decrease the count of
84
// things for that component. The runnable runs within
85
// the synchronized method call ensuring serialized removal
86
// from the components.
87
listenerCounter.remove(component, new Runnable JavaDoc() {
88                     public void run() {
89                         components.remove(component);
90                     }
91                 });
92             }
93         }
94     }
95     
96     abstract public String JavaDoc archiveFor(Object JavaDoc component);
97     
98     /**
99      * Poll for Log Messages.
100      *
101      */

102     public void poll() {
103         synchronized (components) {
104             Set JavaDoc polled = new HashSet JavaDoc();
105             for (Iterator JavaDoc it = components.entrySet().iterator(); it.hasNext(); ) {
106                 Map.Entry JavaDoc entry = (Map.Entry JavaDoc) it.next();
107                 Object JavaDoc component = entry.getKey();
108                 String JavaDoc archive = (String JavaDoc) entry.getValue();
109                 // stops polling the same archive when components share the same
110
// logger/console
111
if (polled.contains(archive)) {
112                     continue;
113                 }
114                 LogEvent[] events = null;
115                 try {
116                     // this could fail if the remote node has gone or the connection
117
// has dropped.
118
events = retrieveEvents(component,
119                             cache.getLastMessageNumber(archive),
120                             cache.getMaxHistory());
121                 } catch (Exception JavaDoc e) {
122                     logger.debug("Failed to retrieve events for [" + component + "]", e);
123                     continue;
124                 }
125                 for (int i = 0; i < events.length; ++i) {
126                     cache.addEvent(archive, events[i].getLevel(), events[i].getMessage());
127                 }
128                 polled.add(archive);
129             }
130         }
131     }
132
133     public abstract LogEvent[] retrieveEvents(Object JavaDoc component, long last, int max);
134     
135     public void destroy() {
136         cache.destroy();
137     }
138 }
139
Popular Tags