1 /**
2  * Logback: the reliable, generic, fast and flexible logging framework.
3  * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
4  *
5  * This program and the accompanying materials are dual-licensed under
6  * either the terms of the Eclipse Public License v1.0 as published by
7  * the Eclipse Foundation
8  *
9  *   or (per the licensee's choosing)
10  *
11  * under the terms of the GNU Lesser General Public License version 2.1
12  * as published by the Free Software Foundation.
13  */

14 package ch.qos.logback.core.spi;
15
16 import java.util.Iterator;
17
18 import ch.qos.logback.core.Appender;
19 import ch.qos.logback.core.util.COWArrayList;
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     @SuppressWarnings("unchecked")
30     final private COWArrayList<Appender<E>> appenderList = new COWArrayList<Appender<E>>(new Appender[0]);
31
32     /**
33      * Attach an appender. If the appender is already in the list in won't be
34      * added again.
35      */

36     public void addAppender(Appender<E> newAppender) {
37         if (newAppender == null) {
38             throw new IllegalArgumentException("Null argument disallowed");
39         }
40         appenderList.addIfAbsent(newAppender);
41     }
42
43     /**
44      * Call the <code>doAppend</code> method on all attached appenders.
45      */

46     public int appendLoopOnAppenders(E e) {
47         int size = 0;
48         final Appender<E>[] appenderArray = appenderList.asTypedArray();
49         final int len = appenderArray.length;
50         for (int i = 0; i < len; i++) {
51             appenderArray[i].doAppend(e);
52             size++;
53         }
54         return size;
55     }
56
57     /**
58      * Get all attached appenders as an Enumeration. If there are no attached
59      * appenders <code>null</code> is returned.
60      *
61      * @return Iterator An iterator of attached appenders.
62      */

63     public Iterator<Appender<E>> iteratorForAppenders() {
64         return appenderList.iterator();
65     }
66
67     /**
68      * Look for an attached appender named as <code>name</code>.
69      * <p/>
70      * <p> Return the appender with that name if in the list. Return null
71      * otherwise.
72      */

73     public Appender<E> getAppender(String name) {
74         if (name == null) {
75             return null;
76         }
77         for (Appender<E> appender : appenderList) {
78             if (name.equals(appender.getName())) {
79                 return appender;
80             }
81         }
82         return null;
83     }
84
85     /**
86      * Returns <code>true</code> if the specified appender is in the list of
87      * attached appenders, <code>false</code> otherwise.
88      *
89      * @since 1.2
90      */

91     public boolean isAttached(Appender<E> appender) {
92         if (appender == null) {
93             return false;
94         }
95         for (Appender<E> a : appenderList) {
96             if (a == appender)
97                 return true;
98         }
99         return false;
100     }
101
102     /**
103      * Remove and processPriorToRemoval all previously attached appenders.
104      */

105     public void detachAndStopAllAppenders() {
106         for (Appender<E> a : appenderList) {
107             a.stop();
108         }
109         appenderList.clear();
110     }
111
112     static final long START = System.currentTimeMillis();
113
114     /**
115      * Remove the appender passed as parameter form the list of attached
116      * appenders.
117      */

118     public boolean detachAppender(Appender<E> appender) {
119         if (appender == null) {
120             return false;
121         }
122         boolean result;
123         result = appenderList.remove(appender);
124         return result;
125     }
126
127     /**
128      * Remove the appender with the name passed as parameter form the list of
129      * appenders.
130      */

131     public boolean detachAppender(String name) {
132         if (name == null) {
133             return false;
134         }
135         boolean removed = false;
136         for (Appender<E> a : appenderList) {
137             if (name.equals((a).getName())) {
138                 removed = appenderList.remove(a);
139                 break;
140             }
141         }
142         return removed;
143     }
144 }
145