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<>(); 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 @SuppressWarnings( "EmptyMethod" ) 129 protected void handleError( RepositoryEvent event, RepositoryListener listener, RuntimeException error ) 130 { 131 // default just swallows errors 132 } 133 134 @Override 135 public void artifactDeployed( RepositoryEvent event ) 136 { 137 for ( RepositoryListener listener : listeners ) 138 { 139 try 140 { 141 listener.artifactDeployed( event ); 142 } 143 catch ( RuntimeException e ) 144 { 145 handleError( event, listener, e ); 146 } 147 } 148 } 149 150 @Override 151 public void artifactDeploying( RepositoryEvent event ) 152 { 153 for ( RepositoryListener listener : listeners ) 154 { 155 try 156 { 157 listener.artifactDeploying( event ); 158 } 159 catch ( RuntimeException e ) 160 { 161 handleError( event, listener, e ); 162 } 163 } 164 } 165 166 @Override 167 public void artifactDescriptorInvalid( RepositoryEvent event ) 168 { 169 for ( RepositoryListener listener : listeners ) 170 { 171 try 172 { 173 listener.artifactDescriptorInvalid( event ); 174 } 175 catch ( RuntimeException e ) 176 { 177 handleError( event, listener, e ); 178 } 179 } 180 } 181 182 @Override 183 public void artifactDescriptorMissing( RepositoryEvent event ) 184 { 185 for ( RepositoryListener listener : listeners ) 186 { 187 try 188 { 189 listener.artifactDescriptorMissing( event ); 190 } 191 catch ( RuntimeException e ) 192 { 193 handleError( event, listener, e ); 194 } 195 } 196 } 197 198 @Override 199 public void artifactDownloaded( RepositoryEvent event ) 200 { 201 for ( RepositoryListener listener : listeners ) 202 { 203 try 204 { 205 listener.artifactDownloaded( event ); 206 } 207 catch ( RuntimeException e ) 208 { 209 handleError( event, listener, e ); 210 } 211 } 212 } 213 214 @Override 215 public void artifactDownloading( RepositoryEvent event ) 216 { 217 for ( RepositoryListener listener : listeners ) 218 { 219 try 220 { 221 listener.artifactDownloading( event ); 222 } 223 catch ( RuntimeException e ) 224 { 225 handleError( event, listener, e ); 226 } 227 } 228 } 229 230 @Override 231 public void artifactInstalled( RepositoryEvent event ) 232 { 233 for ( RepositoryListener listener : listeners ) 234 { 235 try 236 { 237 listener.artifactInstalled( event ); 238 } 239 catch ( RuntimeException e ) 240 { 241 handleError( event, listener, e ); 242 } 243 } 244 } 245 246 @Override 247 public void artifactInstalling( RepositoryEvent event ) 248 { 249 for ( RepositoryListener listener : listeners ) 250 { 251 try 252 { 253 listener.artifactInstalling( event ); 254 } 255 catch ( RuntimeException e ) 256 { 257 handleError( event, listener, e ); 258 } 259 } 260 } 261 262 @Override 263 public void artifactResolved( RepositoryEvent event ) 264 { 265 for ( RepositoryListener listener : listeners ) 266 { 267 try 268 { 269 listener.artifactResolved( event ); 270 } 271 catch ( RuntimeException e ) 272 { 273 handleError( event, listener, e ); 274 } 275 } 276 } 277 278 @Override 279 public void artifactResolving( RepositoryEvent event ) 280 { 281 for ( RepositoryListener listener : listeners ) 282 { 283 try 284 { 285 listener.artifactResolving( event ); 286 } 287 catch ( RuntimeException e ) 288 { 289 handleError( event, listener, e ); 290 } 291 } 292 } 293 294 @Override 295 public void metadataDeployed( RepositoryEvent event ) 296 { 297 for ( RepositoryListener listener : listeners ) 298 { 299 try 300 { 301 listener.metadataDeployed( event ); 302 } 303 catch ( RuntimeException e ) 304 { 305 handleError( event, listener, e ); 306 } 307 } 308 } 309 310 @Override 311 public void metadataDeploying( RepositoryEvent event ) 312 { 313 for ( RepositoryListener listener : listeners ) 314 { 315 try 316 { 317 listener.metadataDeploying( event ); 318 } 319 catch ( RuntimeException e ) 320 { 321 handleError( event, listener, e ); 322 } 323 } 324 } 325 326 @Override 327 public void metadataDownloaded( RepositoryEvent event ) 328 { 329 for ( RepositoryListener listener : listeners ) 330 { 331 try 332 { 333 listener.metadataDownloaded( event ); 334 } 335 catch ( RuntimeException e ) 336 { 337 handleError( event, listener, e ); 338 } 339 } 340 } 341 342 @Override 343 public void metadataDownloading( RepositoryEvent event ) 344 { 345 for ( RepositoryListener listener : listeners ) 346 { 347 try 348 { 349 listener.metadataDownloading( event ); 350 } 351 catch ( RuntimeException e ) 352 { 353 handleError( event, listener, e ); 354 } 355 } 356 } 357 358 @Override 359 public void metadataInstalled( RepositoryEvent event ) 360 { 361 for ( RepositoryListener listener : listeners ) 362 { 363 try 364 { 365 listener.metadataInstalled( event ); 366 } 367 catch ( RuntimeException e ) 368 { 369 handleError( event, listener, e ); 370 } 371 } 372 } 373 374 @Override 375 public void metadataInstalling( RepositoryEvent event ) 376 { 377 for ( RepositoryListener listener : listeners ) 378 { 379 try 380 { 381 listener.metadataInstalling( event ); 382 } 383 catch ( RuntimeException e ) 384 { 385 handleError( event, listener, e ); 386 } 387 } 388 } 389 390 @Override 391 public void metadataInvalid( RepositoryEvent event ) 392 { 393 for ( RepositoryListener listener : listeners ) 394 { 395 try 396 { 397 listener.metadataInvalid( event ); 398 } 399 catch ( RuntimeException e ) 400 { 401 handleError( event, listener, e ); 402 } 403 } 404 } 405 406 @Override 407 public void metadataResolved( RepositoryEvent event ) 408 { 409 for ( RepositoryListener listener : listeners ) 410 { 411 try 412 { 413 listener.metadataResolved( event ); 414 } 415 catch ( RuntimeException e ) 416 { 417 handleError( event, listener, e ); 418 } 419 } 420 } 421 422 @Override 423 public void metadataResolving( RepositoryEvent event ) 424 { 425 for ( RepositoryListener listener : listeners ) 426 { 427 try 428 { 429 listener.metadataResolving( event ); 430 } 431 catch ( RuntimeException e ) 432 { 433 handleError( event, listener, e ); 434 } 435 } 436 } 437 438}