View Javadoc

1   /**
2    * Logback: the generic, reliable, fast and flexible logging framework.
3    * 
4    * Copyright (C) 2000-2008, QOS.ch
5    * 
6    * This library is free software, you can redistribute it and/or modify it under
7    * the terms of the GNU Lesser General Public License as published by the Free
8    * Software Foundation.
9    */
10  package ch.qos.logback.core.spi;
11  
12  import java.util.ArrayList;
13  import java.util.Iterator;
14  import java.util.List;
15  import java.util.concurrent.locks.Lock;
16  import java.util.concurrent.locks.ReadWriteLock;
17  import java.util.concurrent.locks.ReentrantReadWriteLock;
18  
19  import ch.qos.logback.core.Appender;
20  
21  /**
22   * A ReentrantReadWriteLock based implementation of the
23   * {@link AppenderAttachable} interface.
24   * 
25   * @author Ceki Gülcü
26   */
27  public class AppenderAttachableImpl<E> implements AppenderAttachable<E> {
28  
29    final private List<Appender<E>> appenderList = new ArrayList<Appender<E>>();
30    final private ReadWriteLock rwLock = new ReentrantReadWriteLock();
31    private final Lock r = rwLock.readLock();
32    private final Lock w = rwLock.writeLock();
33  
34    /**
35     * Attach an appender. If the appender is already in the list in won't be
36     * added again.
37     */
38    public void addAppender(Appender<E> newAppender) {
39      if (newAppender == null) {
40        throw new IllegalArgumentException("Null argument disallowed");
41      }
42      w.lock();
43      try {
44        if (!appenderList.contains(newAppender)) {
45          appenderList.add(newAppender);
46        }
47      } finally {
48        w.unlock();
49      }
50    }
51  
52    /**
53     * Call the <code>doAppend</code> method on all attached appenders.
54     */
55    public int appendLoopOnAppenders(E e) {
56      int size = 0;
57      r.lock();
58      try {
59        for (Appender<E> appender : appenderList) {
60          appender.doAppend(e);
61          size++;
62        }
63      } finally {
64        r.unlock();
65      }
66      return size;
67    }
68  
69    /**
70     * Get all attached appenders as an Enumeration. If there are no attached
71     * appenders <code>null</code> is returned.
72     * 
73     * @return Iterator An iterator of attached appenders.
74     */
75    public Iterator<Appender<E>> iteratorForAppenders() {
76      List<Appender<E>> copy;
77      r.lock();
78      try {
79        copy = new ArrayList<Appender<E>>(appenderList);
80      } finally {
81        r.unlock();
82      }
83      return copy.iterator();
84    }
85  
86    /**
87     * Look for an attached appender named as <code>name</code>.
88     * 
89     * <p> Return the appender with that name if in the list. Return null
90     * otherwise.
91     * 
92     */
93    public Appender<E> getAppender(String name) {
94      if (name == null) {
95        return null;
96      }
97      Appender<E> found = null;
98  
99      r.lock();
100     try {
101       for (Appender<E> appender : appenderList) {
102         if (name.equals(appender.getName())) {
103           found = appender;
104           break;
105         }
106       }
107     } finally {
108       r.unlock();
109     }
110     return found;
111   }
112 
113   /**
114    * Returns <code>true</code> if the specified appender is in the list of
115    * attached appenders, <code>false</code> otherwise.
116    * 
117    * @since 1.2
118    */
119   public boolean isAttached(Appender appender) {
120     if (appender == null) {
121       return false;
122     }
123     boolean attached = false;
124     r.lock();
125     try {
126       for (Appender<E> a : appenderList) {
127         if (a == appender) {
128           attached = true;
129           break;
130         }
131       }
132     } finally {
133       r.unlock();
134     }
135     return attached;
136   }
137 
138   /**
139    * Remove and stop all previously attached appenders.
140    */
141   public void detachAndStopAllAppenders() {
142     w.lock();
143     try {
144       for (Appender<E> a : appenderList) {
145         a.stop();
146       }
147       appenderList.clear();
148     } finally {
149       w.unlock();
150     }
151   }
152 
153   /**
154    * Remove the appender passed as parameter form the list of attached
155    * appenders.
156    */
157   public boolean detachAppender(Appender appender) {
158     if (appender == null) {
159       return false;
160     }
161     boolean result;
162     w.lock();
163     try {
164       result = appenderList.remove(appender);
165     } finally {
166       w.unlock();
167     }
168     return result;
169   }
170 
171   /**
172    * Remove the appender with the name passed as parameter form the list of
173    * appenders.
174    */
175   public boolean detachAppender(String name) {
176     if (name == null) {
177       return false;
178     }
179     boolean removed = false;
180     w.lock();
181     try {
182       for (Appender<E> a : appenderList) {
183         if (name.equals((a).getName())) {
184           removed = appenderList.remove(a);
185           break;
186         }
187       }
188     } finally {
189       w.unlock();
190     }
191     return removed;
192   }
193 }