View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.eclipse.aether.util.listener;
20  
21  import java.util.Arrays;
22  import java.util.Collection;
23  import java.util.List;
24  import java.util.concurrent.CopyOnWriteArrayList;
25  
26  import org.eclipse.aether.AbstractRepositoryListener;
27  import org.eclipse.aether.RepositoryEvent;
28  import org.eclipse.aether.RepositoryListener;
29  
30  import static java.util.Objects.requireNonNull;
31  
32  /**
33   * A repository listener that delegates to zero or more other listeners (multicast). The list of target listeners is
34   * thread-safe, i.e. target listeners can be added or removed by any thread at any time.
35   */
36  public final class ChainedRepositoryListener extends AbstractRepositoryListener {
37  
38      private final List<RepositoryListener> listeners = new CopyOnWriteArrayList<>();
39  
40      /**
41       * Creates a new multicast listener that delegates to the specified listeners. In contrast to the constructor, this
42       * factory method will avoid creating an actual chained listener if one of the specified readers is actually
43       * {@code null}.
44       *
45       * @param listener1 The first listener, may be {@code null}.
46       * @param listener2 The second listener, may be {@code null}.
47       * @return The chained listener or {@code null} if no listener was supplied.
48       */
49      public static RepositoryListener newInstance(RepositoryListener listener1, RepositoryListener listener2) {
50          if (listener1 == null) {
51              return listener2;
52          } else if (listener2 == null) {
53              return listener1;
54          }
55          return new ChainedRepositoryListener(listener1, listener2);
56      }
57  
58      /**
59       * Creates a new multicast listener that delegates to the specified listeners.
60       *
61       * @param listeners The listeners to delegate to, may be {@code null} or empty.
62       */
63      public ChainedRepositoryListener(RepositoryListener... listeners) {
64          if (listeners != null) {
65              add(Arrays.asList(listeners));
66          }
67      }
68  
69      /**
70       * Creates a new multicast listener that delegates to the specified listeners.
71       *
72       * @param listeners The listeners to delegate to, may be {@code null} or empty.
73       */
74      public ChainedRepositoryListener(Collection<? extends RepositoryListener> listeners) {
75          add(listeners);
76      }
77  
78      /**
79       * Adds the specified listeners to the end of the multicast chain.
80       *
81       * @param listeners The listeners to add, may be {@code null} or empty.
82       */
83      public void add(Collection<? extends RepositoryListener> listeners) {
84          if (listeners != null) {
85              for (RepositoryListener listener : listeners) {
86                  add(listener);
87              }
88          }
89      }
90  
91      /**
92       * Adds the specified listener to the end of the multicast chain.
93       *
94       * @param listener The listener to add, may be {@code null}.
95       */
96      public void add(RepositoryListener listener) {
97          if (listener != null) {
98              listeners.add(listener);
99          }
100     }
101 
102     /**
103      * Removes the specified listener from the multicast chain. Trying to remove a non-existing listener has no effect.
104      *
105      * @param listener The listener to remove, may be {@code null}.
106      */
107     public void remove(RepositoryListener listener) {
108         if (listener != null) {
109             listeners.remove(listener);
110         }
111     }
112 
113     @SuppressWarnings("EmptyMethod")
114     protected void handleError(RepositoryEvent event, RepositoryListener listener, RuntimeException error) {
115         // default just swallows errors
116     }
117 
118     @Override
119     public void artifactDeployed(RepositoryEvent event) {
120         requireNonNull(event, "event cannot be null");
121         for (RepositoryListener listener : listeners) {
122             try {
123                 listener.artifactDeployed(event);
124             } catch (RuntimeException e) {
125                 handleError(event, listener, e);
126             }
127         }
128     }
129 
130     @Override
131     public void artifactDeploying(RepositoryEvent event) {
132         requireNonNull(event, "event cannot be null");
133         for (RepositoryListener listener : listeners) {
134             try {
135                 listener.artifactDeploying(event);
136             } catch (RuntimeException e) {
137                 handleError(event, listener, e);
138             }
139         }
140     }
141 
142     @Override
143     public void artifactDescriptorInvalid(RepositoryEvent event) {
144         requireNonNull(event, "event cannot be null");
145         for (RepositoryListener listener : listeners) {
146             try {
147                 listener.artifactDescriptorInvalid(event);
148             } catch (RuntimeException e) {
149                 handleError(event, listener, e);
150             }
151         }
152     }
153 
154     @Override
155     public void artifactDescriptorMissing(RepositoryEvent event) {
156         requireNonNull(event, "event cannot be null");
157         for (RepositoryListener listener : listeners) {
158             try {
159                 listener.artifactDescriptorMissing(event);
160             } catch (RuntimeException e) {
161                 handleError(event, listener, e);
162             }
163         }
164     }
165 
166     @Override
167     public void artifactDownloaded(RepositoryEvent event) {
168         requireNonNull(event, "event cannot be null");
169         for (RepositoryListener listener : listeners) {
170             try {
171                 listener.artifactDownloaded(event);
172             } catch (RuntimeException e) {
173                 handleError(event, listener, e);
174             }
175         }
176     }
177 
178     @Override
179     public void artifactDownloading(RepositoryEvent event) {
180         requireNonNull(event, "event cannot be null");
181         for (RepositoryListener listener : listeners) {
182             try {
183                 listener.artifactDownloading(event);
184             } catch (RuntimeException e) {
185                 handleError(event, listener, e);
186             }
187         }
188     }
189 
190     @Override
191     public void artifactInstalled(RepositoryEvent event) {
192         requireNonNull(event, "event cannot be null");
193         for (RepositoryListener listener : listeners) {
194             try {
195                 listener.artifactInstalled(event);
196             } catch (RuntimeException e) {
197                 handleError(event, listener, e);
198             }
199         }
200     }
201 
202     @Override
203     public void artifactInstalling(RepositoryEvent event) {
204         requireNonNull(event, "event cannot be null");
205         for (RepositoryListener listener : listeners) {
206             try {
207                 listener.artifactInstalling(event);
208             } catch (RuntimeException e) {
209                 handleError(event, listener, e);
210             }
211         }
212     }
213 
214     @Override
215     public void artifactResolved(RepositoryEvent event) {
216         requireNonNull(event, "event cannot be null");
217         for (RepositoryListener listener : listeners) {
218             try {
219                 listener.artifactResolved(event);
220             } catch (RuntimeException e) {
221                 handleError(event, listener, e);
222             }
223         }
224     }
225 
226     @Override
227     public void artifactResolving(RepositoryEvent event) {
228         requireNonNull(event, "event cannot be null");
229         for (RepositoryListener listener : listeners) {
230             try {
231                 listener.artifactResolving(event);
232             } catch (RuntimeException e) {
233                 handleError(event, listener, e);
234             }
235         }
236     }
237 
238     @Override
239     public void metadataDeployed(RepositoryEvent event) {
240         requireNonNull(event, "event cannot be null");
241         for (RepositoryListener listener : listeners) {
242             try {
243                 listener.metadataDeployed(event);
244             } catch (RuntimeException e) {
245                 handleError(event, listener, e);
246             }
247         }
248     }
249 
250     @Override
251     public void metadataDeploying(RepositoryEvent event) {
252         requireNonNull(event, "event cannot be null");
253         for (RepositoryListener listener : listeners) {
254             try {
255                 listener.metadataDeploying(event);
256             } catch (RuntimeException e) {
257                 handleError(event, listener, e);
258             }
259         }
260     }
261 
262     @Override
263     public void metadataDownloaded(RepositoryEvent event) {
264         requireNonNull(event, "event cannot be null");
265         for (RepositoryListener listener : listeners) {
266             try {
267                 listener.metadataDownloaded(event);
268             } catch (RuntimeException e) {
269                 handleError(event, listener, e);
270             }
271         }
272     }
273 
274     @Override
275     public void metadataDownloading(RepositoryEvent event) {
276         requireNonNull(event, "event cannot be null");
277         for (RepositoryListener listener : listeners) {
278             try {
279                 listener.metadataDownloading(event);
280             } catch (RuntimeException e) {
281                 handleError(event, listener, e);
282             }
283         }
284     }
285 
286     @Override
287     public void metadataInstalled(RepositoryEvent event) {
288         requireNonNull(event, "event cannot be null");
289         for (RepositoryListener listener : listeners) {
290             try {
291                 listener.metadataInstalled(event);
292             } catch (RuntimeException e) {
293                 handleError(event, listener, e);
294             }
295         }
296     }
297 
298     @Override
299     public void metadataInstalling(RepositoryEvent event) {
300         requireNonNull(event, "event cannot be null");
301         for (RepositoryListener listener : listeners) {
302             try {
303                 listener.metadataInstalling(event);
304             } catch (RuntimeException e) {
305                 handleError(event, listener, e);
306             }
307         }
308     }
309 
310     @Override
311     public void metadataInvalid(RepositoryEvent event) {
312         requireNonNull(event, "event cannot be null");
313         for (RepositoryListener listener : listeners) {
314             try {
315                 listener.metadataInvalid(event);
316             } catch (RuntimeException e) {
317                 handleError(event, listener, e);
318             }
319         }
320     }
321 
322     @Override
323     public void metadataResolved(RepositoryEvent event) {
324         requireNonNull(event, "event cannot be null");
325         for (RepositoryListener listener : listeners) {
326             try {
327                 listener.metadataResolved(event);
328             } catch (RuntimeException e) {
329                 handleError(event, listener, e);
330             }
331         }
332     }
333 
334     @Override
335     public void metadataResolving(RepositoryEvent event) {
336         requireNonNull(event, "event cannot be null");
337         for (RepositoryListener listener : listeners) {
338             try {
339                 listener.metadataResolving(event);
340             } catch (RuntimeException e) {
341                 handleError(event, listener, e);
342             }
343         }
344     }
345 }