View Javadoc
1   package org.eclipse.aether.util.listener;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   * 
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   * 
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.util.Arrays;
23  import java.util.Collection;
24  import java.util.List;
25  import java.util.concurrent.CopyOnWriteArrayList;
26  
27  import org.eclipse.aether.transfer.AbstractTransferListener;
28  import org.eclipse.aether.transfer.TransferCancelledException;
29  import org.eclipse.aether.transfer.TransferEvent;
30  import org.eclipse.aether.transfer.TransferListener;
31  
32  import static java.util.Objects.requireNonNull;
33  
34  /**
35   * A transfer listener that delegates to zero or more other listeners (multicast). The list of target listeners is
36   * thread-safe, i.e. target listeners can be added or removed by any thread at any time.
37   */
38  public final class ChainedTransferListener
39      extends AbstractTransferListener
40  {
41  
42      private final List<TransferListener> listeners = new CopyOnWriteArrayList<>();
43  
44      /**
45       * Creates a new multicast listener that delegates to the specified listeners. In contrast to the constructor, this
46       * factory method will avoid creating an actual chained listener if one of the specified readers is actually
47       * {@code null}.
48       * 
49       * @param listener1 The first listener, may be {@code null}.
50       * @param listener2 The second listener, may be {@code null}.
51       * @return The chained listener or {@code null} if no listener was supplied.
52       */
53      public static TransferListener newInstance( TransferListener listener1, TransferListener listener2 )
54      {
55          if ( listener1 == null )
56          {
57              return listener2;
58          }
59          else if ( listener2 == null )
60          {
61              return listener1;
62          }
63          return new ChainedTransferListener( listener1, listener2 );
64      }
65  
66      /**
67       * Creates a new multicast listener that delegates to the specified listeners.
68       * 
69       * @param listeners The listeners to delegate to, may be {@code null} or empty.
70       */
71      public ChainedTransferListener( TransferListener... listeners )
72      {
73          if ( listeners != null )
74          {
75              add( Arrays.asList( listeners ) );
76          }
77      }
78  
79      /**
80       * Creates a new multicast listener that delegates to the specified listeners.
81       * 
82       * @param listeners The listeners to delegate to, may be {@code null} or empty.
83       */
84      public ChainedTransferListener( Collection<? extends TransferListener> listeners )
85      {
86          add( listeners );
87      }
88  
89      /**
90       * Adds the specified listeners to the end of the multicast chain.
91       * 
92       * @param listeners The listeners to add, may be {@code null} or empty.
93       */
94      public void add( Collection<? extends TransferListener> listeners )
95      {
96          if ( listeners != null )
97          {
98              for ( TransferListener listener : listeners )
99              {
100                 add( listener );
101             }
102         }
103     }
104 
105     /**
106      * Adds the specified listener to the end of the multicast chain.
107      * 
108      * @param listener The listener to add, may be {@code null}.
109      */
110     public void add( TransferListener listener )
111     {
112         if ( listener != null )
113         {
114             listeners.add( listener );
115         }
116     }
117 
118     /**
119      * Removes the specified listener from the multicast chain. Trying to remove a non-existing listener has no effect.
120      * 
121      * @param listener The listener to remove, may be {@code null}.
122      */
123     public void remove( TransferListener listener )
124     {
125         if ( listener != null )
126         {
127             listeners.remove( listener );
128         }
129     }
130 
131     @SuppressWarnings( "EmptyMethod" )
132     protected void handleError( TransferEvent event, TransferListener listener, RuntimeException error )
133     {
134         // default just swallows errors
135     }
136 
137     @Override
138     public void transferInitiated( TransferEvent event )
139         throws TransferCancelledException
140     {
141         requireNonNull( event, "event cannot be null" );
142         for ( TransferListener listener : listeners )
143         {
144             try
145             {
146                 listener.transferInitiated( event );
147             }
148             catch ( RuntimeException e )
149             {
150                 handleError( event, listener, e );
151             }
152         }
153     }
154 
155     @Override
156     public void transferStarted( TransferEvent event )
157         throws TransferCancelledException
158     {
159         requireNonNull( event, "event cannot be null" );
160         for ( TransferListener listener : listeners )
161         {
162             try
163             {
164                 listener.transferStarted( event );
165             }
166             catch ( RuntimeException e )
167             {
168                 handleError( event, listener, e );
169             }
170         }
171     }
172 
173     @Override
174     public void transferProgressed( TransferEvent event )
175         throws TransferCancelledException
176     {
177         requireNonNull( event, "event cannot be null" );
178         for ( TransferListener listener : listeners )
179         {
180             try
181             {
182                 listener.transferProgressed( event );
183             }
184             catch ( RuntimeException e )
185             {
186                 handleError( event, listener, e );
187             }
188         }
189     }
190 
191     @Override
192     public void transferCorrupted( TransferEvent event )
193         throws TransferCancelledException
194     {
195         requireNonNull( event, "event cannot be null" );
196         for ( TransferListener listener : listeners )
197         {
198             try
199             {
200                 listener.transferCorrupted( event );
201             }
202             catch ( RuntimeException e )
203             {
204                 handleError( event, listener, e );
205             }
206         }
207     }
208 
209     @Override
210     public void transferSucceeded( TransferEvent event )
211     {
212         requireNonNull( event, "event cannot be null" );
213         for ( TransferListener listener : listeners )
214         {
215             try
216             {
217                 listener.transferSucceeded( event );
218             }
219             catch ( RuntimeException e )
220             {
221                 handleError( event, listener, e );
222             }
223         }
224     }
225 
226     @Override
227     public void transferFailed( TransferEvent event )
228     {
229         requireNonNull( event, "event cannot be null" );
230         for ( TransferListener listener : listeners )
231         {
232             try
233             {
234                 listener.transferFailed( event );
235             }
236             catch ( RuntimeException e )
237             {
238                 handleError( event, listener, e );
239             }
240         }
241     }
242 
243 }