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.AbstractRepositoryListener;
28  import org.eclipse.aether.RepositoryEvent;
29  import org.eclipse.aether.RepositoryListener;
30  
31  import static java.util.Objects.requireNonNull;
32  
33  /**
34   * A repository listener that delegates to zero or more other listeners (multicast). The list of target listeners is
35   * thread-safe, i.e. target listeners can be added or removed by any thread at any time.
36   */
37  public final class ChainedRepositoryListener
38      extends AbstractRepositoryListener
39  {
40  
41      private final List<RepositoryListener> listeners = new CopyOnWriteArrayList<>();
42  
43      /**
44       * Creates a new multicast listener that delegates to the specified listeners. In contrast to the constructor, this
45       * factory method will avoid creating an actual chained listener if one of the specified readers is actually
46       * {@code null}.
47       * 
48       * @param listener1 The first listener, may be {@code null}.
49       * @param listener2 The second listener, may be {@code null}.
50       * @return The chained listener or {@code null} if no listener was supplied.
51       */
52      public static RepositoryListener newInstance( RepositoryListener listener1, RepositoryListener listener2 )
53      {
54          if ( listener1 == null )
55          {
56              return listener2;
57          }
58          else if ( listener2 == null )
59          {
60              return listener1;
61          }
62          return new ChainedRepositoryListener( listener1, listener2 );
63      }
64  
65      /**
66       * Creates a new multicast listener that delegates to the specified listeners.
67       * 
68       * @param listeners The listeners to delegate to, may be {@code null} or empty.
69       */
70      public ChainedRepositoryListener( RepositoryListener... listeners )
71      {
72          if ( listeners != null )
73          {
74              add( Arrays.asList( listeners ) );
75          }
76      }
77  
78      /**
79       * Creates a new multicast listener that delegates to the specified listeners.
80       * 
81       * @param listeners The listeners to delegate to, may be {@code null} or empty.
82       */
83      public ChainedRepositoryListener( Collection<? extends RepositoryListener> listeners )
84      {
85          add( listeners );
86      }
87  
88      /**
89       * Adds the specified listeners to the end of the multicast chain.
90       * 
91       * @param listeners The listeners to add, may be {@code null} or empty.
92       */
93      public void add( Collection<? extends RepositoryListener> listeners )
94      {
95          if ( listeners != null )
96          {
97              for ( RepositoryListener listener : listeners )
98              {
99                  add( listener );
100             }
101         }
102     }
103 
104     /**
105      * Adds the specified listener to the end of the multicast chain.
106      * 
107      * @param listener The listener to add, may be {@code null}.
108      */
109     public void add( RepositoryListener listener )
110     {
111         if ( listener != null )
112         {
113             listeners.add( listener );
114         }
115     }
116 
117     /**
118      * Removes the specified listener from the multicast chain. Trying to remove a non-existing listener has no effect.
119      * 
120      * @param listener The listener to remove, may be {@code null}.
121      */
122     public void remove( RepositoryListener listener )
123     {
124         if ( listener != null )
125         {
126             listeners.remove( listener );
127         }
128     }
129 
130     @SuppressWarnings( "EmptyMethod" )
131     protected void handleError( RepositoryEvent event, RepositoryListener listener, RuntimeException error )
132     {
133         // default just swallows errors
134     }
135 
136     @Override
137     public void artifactDeployed( RepositoryEvent event )
138     {
139         requireNonNull( event, "event cannot be null" );
140         for ( RepositoryListener listener : listeners )
141         {
142             try
143             {
144                 listener.artifactDeployed( event );
145             }
146             catch ( RuntimeException e )
147             {
148                 handleError( event, listener, e );
149             }
150         }
151     }
152 
153     @Override
154     public void artifactDeploying( RepositoryEvent event )
155     {
156         requireNonNull( event, "event cannot be null" );
157         for ( RepositoryListener listener : listeners )
158         {
159             try
160             {
161                 listener.artifactDeploying( event );
162             }
163             catch ( RuntimeException e )
164             {
165                 handleError( event, listener, e );
166             }
167         }
168     }
169 
170     @Override
171     public void artifactDescriptorInvalid( RepositoryEvent event )
172     {
173         requireNonNull( event, "event cannot be null" );
174         for ( RepositoryListener listener : listeners )
175         {
176             try
177             {
178                 listener.artifactDescriptorInvalid( event );
179             }
180             catch ( RuntimeException e )
181             {
182                 handleError( event, listener, e );
183             }
184         }
185     }
186 
187     @Override
188     public void artifactDescriptorMissing( RepositoryEvent event )
189     {
190         requireNonNull( event, "event cannot be null" );
191         for ( RepositoryListener listener : listeners )
192         {
193             try
194             {
195                 listener.artifactDescriptorMissing( event );
196             }
197             catch ( RuntimeException e )
198             {
199                 handleError( event, listener, e );
200             }
201         }
202     }
203 
204     @Override
205     public void artifactDownloaded( RepositoryEvent event )
206     {
207         requireNonNull( event, "event cannot be null" );
208         for ( RepositoryListener listener : listeners )
209         {
210             try
211             {
212                 listener.artifactDownloaded( event );
213             }
214             catch ( RuntimeException e )
215             {
216                 handleError( event, listener, e );
217             }
218         }
219     }
220 
221     @Override
222     public void artifactDownloading( RepositoryEvent event )
223     {
224         requireNonNull( event, "event cannot be null" );
225         for ( RepositoryListener listener : listeners )
226         {
227             try
228             {
229                 listener.artifactDownloading( event );
230             }
231             catch ( RuntimeException e )
232             {
233                 handleError( event, listener, e );
234             }
235         }
236     }
237 
238     @Override
239     public void artifactInstalled( RepositoryEvent event )
240     {
241         requireNonNull( event, "event cannot be null" );
242         for ( RepositoryListener listener : listeners )
243         {
244             try
245             {
246                 listener.artifactInstalled( event );
247             }
248             catch ( RuntimeException e )
249             {
250                 handleError( event, listener, e );
251             }
252         }
253     }
254 
255     @Override
256     public void artifactInstalling( RepositoryEvent event )
257     {
258         requireNonNull( event, "event cannot be null" );
259         for ( RepositoryListener listener : listeners )
260         {
261             try
262             {
263                 listener.artifactInstalling( event );
264             }
265             catch ( RuntimeException e )
266             {
267                 handleError( event, listener, e );
268             }
269         }
270     }
271 
272     @Override
273     public void artifactResolved( RepositoryEvent event )
274     {
275         requireNonNull( event, "event cannot be null" );
276         for ( RepositoryListener listener : listeners )
277         {
278             try
279             {
280                 listener.artifactResolved( event );
281             }
282             catch ( RuntimeException e )
283             {
284                 handleError( event, listener, e );
285             }
286         }
287     }
288 
289     @Override
290     public void artifactResolving( RepositoryEvent event )
291     {
292         requireNonNull( event, "event cannot be null" );
293         for ( RepositoryListener listener : listeners )
294         {
295             try
296             {
297                 listener.artifactResolving( event );
298             }
299             catch ( RuntimeException e )
300             {
301                 handleError( event, listener, e );
302             }
303         }
304     }
305 
306     @Override
307     public void metadataDeployed( RepositoryEvent event )
308     {
309         requireNonNull( event, "event cannot be null" );
310         for ( RepositoryListener listener : listeners )
311         {
312             try
313             {
314                 listener.metadataDeployed( event );
315             }
316             catch ( RuntimeException e )
317             {
318                 handleError( event, listener, e );
319             }
320         }
321     }
322 
323     @Override
324     public void metadataDeploying( RepositoryEvent event )
325     {
326         requireNonNull( event, "event cannot be null" );
327         for ( RepositoryListener listener : listeners )
328         {
329             try
330             {
331                 listener.metadataDeploying( event );
332             }
333             catch ( RuntimeException e )
334             {
335                 handleError( event, listener, e );
336             }
337         }
338     }
339 
340     @Override
341     public void metadataDownloaded( RepositoryEvent event )
342     {
343         requireNonNull( event, "event cannot be null" );
344         for ( RepositoryListener listener : listeners )
345         {
346             try
347             {
348                 listener.metadataDownloaded( event );
349             }
350             catch ( RuntimeException e )
351             {
352                 handleError( event, listener, e );
353             }
354         }
355     }
356 
357     @Override
358     public void metadataDownloading( RepositoryEvent event )
359     {
360         requireNonNull( event, "event cannot be null" );
361         for ( RepositoryListener listener : listeners )
362         {
363             try
364             {
365                 listener.metadataDownloading( event );
366             }
367             catch ( RuntimeException e )
368             {
369                 handleError( event, listener, e );
370             }
371         }
372     }
373 
374     @Override
375     public void metadataInstalled( RepositoryEvent event )
376     {
377         requireNonNull( event, "event cannot be null" );
378         for ( RepositoryListener listener : listeners )
379         {
380             try
381             {
382                 listener.metadataInstalled( event );
383             }
384             catch ( RuntimeException e )
385             {
386                 handleError( event, listener, e );
387             }
388         }
389     }
390 
391     @Override
392     public void metadataInstalling( RepositoryEvent event )
393     {
394         requireNonNull( event, "event cannot be null" );
395         for ( RepositoryListener listener : listeners )
396         {
397             try
398             {
399                 listener.metadataInstalling( event );
400             }
401             catch ( RuntimeException e )
402             {
403                 handleError( event, listener, e );
404             }
405         }
406     }
407 
408     @Override
409     public void metadataInvalid( RepositoryEvent event )
410     {
411         requireNonNull( event, "event cannot be null" );
412         for ( RepositoryListener listener : listeners )
413         {
414             try
415             {
416                 listener.metadataInvalid( event );
417             }
418             catch ( RuntimeException e )
419             {
420                 handleError( event, listener, e );
421             }
422         }
423     }
424 
425     @Override
426     public void metadataResolved( RepositoryEvent event )
427     {
428         requireNonNull( event, "event cannot be null" );
429         for ( RepositoryListener listener : listeners )
430         {
431             try
432             {
433                 listener.metadataResolved( event );
434             }
435             catch ( RuntimeException e )
436             {
437                 handleError( event, listener, e );
438             }
439         }
440     }
441 
442     @Override
443     public void metadataResolving( RepositoryEvent event )
444     {
445         requireNonNull( event, "event cannot be null" );
446         for ( RepositoryListener listener : listeners )
447         {
448             try
449             {
450                 listener.metadataResolving( event );
451             }
452             catch ( RuntimeException e )
453             {
454                 handleError( event, listener, e );
455             }
456         }
457     }
458 
459 }