001package org.eclipse.aether.util.listener; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import java.util.Arrays; 023import java.util.Collection; 024import java.util.List; 025import java.util.concurrent.CopyOnWriteArrayList; 026 027import org.eclipse.aether.AbstractRepositoryListener; 028import org.eclipse.aether.RepositoryEvent; 029import org.eclipse.aether.RepositoryListener; 030 031/** 032 * A repository listener that delegates to zero or more other listeners (multicast). The list of target listeners is 033 * thread-safe, i.e. target listeners can be added or removed by any thread at any time. 034 */ 035public final class ChainedRepositoryListener 036 extends AbstractRepositoryListener 037{ 038 039 private final List<RepositoryListener> listeners = new CopyOnWriteArrayList<RepositoryListener>(); 040 041 /** 042 * Creates a new multicast listener that delegates to the specified listeners. In contrast to the constructor, this 043 * factory method will avoid creating an actual chained listener if one of the specified readers is actually 044 * {@code null}. 045 * 046 * @param listener1 The first listener, may be {@code null}. 047 * @param listener2 The second listener, may be {@code null}. 048 * @return The chained listener or {@code null} if no listener was supplied. 049 */ 050 public static RepositoryListener newInstance( RepositoryListener listener1, RepositoryListener listener2 ) 051 { 052 if ( listener1 == null ) 053 { 054 return listener2; 055 } 056 else if ( listener2 == null ) 057 { 058 return listener1; 059 } 060 return new ChainedRepositoryListener( listener1, listener2 ); 061 } 062 063 /** 064 * Creates a new multicast listener that delegates to the specified listeners. 065 * 066 * @param listeners The listeners to delegate to, may be {@code null} or empty. 067 */ 068 public ChainedRepositoryListener( RepositoryListener... listeners ) 069 { 070 if ( listeners != null ) 071 { 072 add( Arrays.asList( listeners ) ); 073 } 074 } 075 076 /** 077 * Creates a new multicast listener that delegates to the specified listeners. 078 * 079 * @param listeners The listeners to delegate to, may be {@code null} or empty. 080 */ 081 public ChainedRepositoryListener( Collection<? extends RepositoryListener> listeners ) 082 { 083 add( listeners ); 084 } 085 086 /** 087 * Adds the specified listeners to the end of the multicast chain. 088 * 089 * @param listeners The listeners to add, may be {@code null} or empty. 090 */ 091 public void add( Collection<? extends RepositoryListener> listeners ) 092 { 093 if ( listeners != null ) 094 { 095 for ( RepositoryListener listener : listeners ) 096 { 097 add( listener ); 098 } 099 } 100 } 101 102 /** 103 * Adds the specified listener to the end of the multicast chain. 104 * 105 * @param listener The listener to add, may be {@code null}. 106 */ 107 public void add( RepositoryListener listener ) 108 { 109 if ( listener != null ) 110 { 111 listeners.add( listener ); 112 } 113 } 114 115 /** 116 * Removes the specified listener from the multicast chain. Trying to remove a non-existing listener has no effect. 117 * 118 * @param listener The listener to remove, may be {@code null}. 119 */ 120 public void remove( RepositoryListener listener ) 121 { 122 if ( listener != null ) 123 { 124 listeners.remove( listener ); 125 } 126 } 127 128 protected void handleError( RepositoryEvent event, RepositoryListener listener, RuntimeException error ) 129 { 130 // default just swallows errors 131 } 132 133 @Override 134 public void artifactDeployed( RepositoryEvent event ) 135 { 136 for ( RepositoryListener listener : listeners ) 137 { 138 try 139 { 140 listener.artifactDeployed( event ); 141 } 142 catch ( RuntimeException e ) 143 { 144 handleError( event, listener, e ); 145 } 146 } 147 } 148 149 @Override 150 public void artifactDeploying( RepositoryEvent event ) 151 { 152 for ( RepositoryListener listener : listeners ) 153 { 154 try 155 { 156 listener.artifactDeploying( event ); 157 } 158 catch ( RuntimeException e ) 159 { 160 handleError( event, listener, e ); 161 } 162 } 163 } 164 165 @Override 166 public void artifactDescriptorInvalid( RepositoryEvent event ) 167 { 168 for ( RepositoryListener listener : listeners ) 169 { 170 try 171 { 172 listener.artifactDescriptorInvalid( event ); 173 } 174 catch ( RuntimeException e ) 175 { 176 handleError( event, listener, e ); 177 } 178 } 179 } 180 181 @Override 182 public void artifactDescriptorMissing( RepositoryEvent event ) 183 { 184 for ( RepositoryListener listener : listeners ) 185 { 186 try 187 { 188 listener.artifactDescriptorMissing( event ); 189 } 190 catch ( RuntimeException e ) 191 { 192 handleError( event, listener, e ); 193 } 194 } 195 } 196 197 @Override 198 public void artifactDownloaded( RepositoryEvent event ) 199 { 200 for ( RepositoryListener listener : listeners ) 201 { 202 try 203 { 204 listener.artifactDownloaded( event ); 205 } 206 catch ( RuntimeException e ) 207 { 208 handleError( event, listener, e ); 209 } 210 } 211 } 212 213 @Override 214 public void artifactDownloading( RepositoryEvent event ) 215 { 216 for ( RepositoryListener listener : listeners ) 217 { 218 try 219 { 220 listener.artifactDownloading( event ); 221 } 222 catch ( RuntimeException e ) 223 { 224 handleError( event, listener, e ); 225 } 226 } 227 } 228 229 @Override 230 public void artifactInstalled( RepositoryEvent event ) 231 { 232 for ( RepositoryListener listener : listeners ) 233 { 234 try 235 { 236 listener.artifactInstalled( event ); 237 } 238 catch ( RuntimeException e ) 239 { 240 handleError( event, listener, e ); 241 } 242 } 243 } 244 245 @Override 246 public void artifactInstalling( RepositoryEvent event ) 247 { 248 for ( RepositoryListener listener : listeners ) 249 { 250 try 251 { 252 listener.artifactInstalling( event ); 253 } 254 catch ( RuntimeException e ) 255 { 256 handleError( event, listener, e ); 257 } 258 } 259 } 260 261 @Override 262 public void artifactResolved( RepositoryEvent event ) 263 { 264 for ( RepositoryListener listener : listeners ) 265 { 266 try 267 { 268 listener.artifactResolved( event ); 269 } 270 catch ( RuntimeException e ) 271 { 272 handleError( event, listener, e ); 273 } 274 } 275 } 276 277 @Override 278 public void artifactResolving( RepositoryEvent event ) 279 { 280 for ( RepositoryListener listener : listeners ) 281 { 282 try 283 { 284 listener.artifactResolving( event ); 285 } 286 catch ( RuntimeException e ) 287 { 288 handleError( event, listener, e ); 289 } 290 } 291 } 292 293 @Override 294 public void metadataDeployed( RepositoryEvent event ) 295 { 296 for ( RepositoryListener listener : listeners ) 297 { 298 try 299 { 300 listener.metadataDeployed( event ); 301 } 302 catch ( RuntimeException e ) 303 { 304 handleError( event, listener, e ); 305 } 306 } 307 } 308 309 @Override 310 public void metadataDeploying( RepositoryEvent event ) 311 { 312 for ( RepositoryListener listener : listeners ) 313 { 314 try 315 { 316 listener.metadataDeploying( event ); 317 } 318 catch ( RuntimeException e ) 319 { 320 handleError( event, listener, e ); 321 } 322 } 323 } 324 325 @Override 326 public void metadataDownloaded( RepositoryEvent event ) 327 { 328 for ( RepositoryListener listener : listeners ) 329 { 330 try 331 { 332 listener.metadataDownloaded( event ); 333 } 334 catch ( RuntimeException e ) 335 { 336 handleError( event, listener, e ); 337 } 338 } 339 } 340 341 @Override 342 public void metadataDownloading( RepositoryEvent event ) 343 { 344 for ( RepositoryListener listener : listeners ) 345 { 346 try 347 { 348 listener.metadataDownloading( event ); 349 } 350 catch ( RuntimeException e ) 351 { 352 handleError( event, listener, e ); 353 } 354 } 355 } 356 357 @Override 358 public void metadataInstalled( RepositoryEvent event ) 359 { 360 for ( RepositoryListener listener : listeners ) 361 { 362 try 363 { 364 listener.metadataInstalled( event ); 365 } 366 catch ( RuntimeException e ) 367 { 368 handleError( event, listener, e ); 369 } 370 } 371 } 372 373 @Override 374 public void metadataInstalling( RepositoryEvent event ) 375 { 376 for ( RepositoryListener listener : listeners ) 377 { 378 try 379 { 380 listener.metadataInstalling( event ); 381 } 382 catch ( RuntimeException e ) 383 { 384 handleError( event, listener, e ); 385 } 386 } 387 } 388 389 @Override 390 public void metadataInvalid( RepositoryEvent event ) 391 { 392 for ( RepositoryListener listener : listeners ) 393 { 394 try 395 { 396 listener.metadataInvalid( event ); 397 } 398 catch ( RuntimeException e ) 399 { 400 handleError( event, listener, e ); 401 } 402 } 403 } 404 405 @Override 406 public void metadataResolved( RepositoryEvent event ) 407 { 408 for ( RepositoryListener listener : listeners ) 409 { 410 try 411 { 412 listener.metadataResolved( event ); 413 } 414 catch ( RuntimeException e ) 415 { 416 handleError( event, listener, e ); 417 } 418 } 419 } 420 421 @Override 422 public void metadataResolving( RepositoryEvent event ) 423 { 424 for ( RepositoryListener listener : listeners ) 425 { 426 try 427 { 428 listener.metadataResolving( event ); 429 } 430 catch ( RuntimeException e ) 431 { 432 handleError( event, listener, e ); 433 } 434 } 435 } 436 437}