/* * Copyright 2010-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ package com.amazonaws.event; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; /** * An implementation of ProgressListener interface that delegates * progressChanged callback to multiple listeners. It also takes an optional * ProgressEventFilter to filter incoming events before passing them to the * listeners. * <p> * This class could be used for both Amazon S3 and Amazon Glacier clients. The * legacy Amazon S3 progress listener chain * com.amazonaws.services.s3.transfer.internal.ProgressListenerChain has been * deprecated in favor of this new class. * </p> */ public class ProgressListenerChain implements ProgressListener { private final List<ProgressListener> listeners = new CopyOnWriteArrayList<ProgressListener>(); private final ProgressEventFilter progressEventFilter; private static final Log log = LogFactory.getLog(ProgressListenerChain.class); /** * Create a listener chain that directly passes all the progress events to * the specified listeners. */ public ProgressListenerChain(ProgressListener... listeners) { this(null, listeners); } /** * Create a listener chain with a ProgressEventFilter. */ public ProgressListenerChain(ProgressEventFilter progressEventFilter, ProgressListener... listeners) { if (listeners == null) { throw new IllegalArgumentException( "Progress Listeners cannot be null."); } for (ProgressListener listener : listeners) addProgressListener(listener); this.progressEventFilter = progressEventFilter; } public synchronized void addProgressListener(ProgressListener listener) { if (listener == null) return; this.listeners.add(listener); } public synchronized void removeProgressListener(ProgressListener listener) { if (listener == null) return; this.listeners.remove(listener); } /** * Returns the listeners associated with this listener chain. */ protected List<ProgressListener> getListeners() { return listeners; } @Override public void progressChanged(final ProgressEvent progressEvent) { ProgressEvent filteredEvent = progressEvent; if (progressEventFilter != null) { filteredEvent = progressEventFilter.filter(progressEvent); if (filteredEvent == null) return; } for (ProgressListener listener : listeners) { try { listener.progressChanged(filteredEvent); } catch (RuntimeException e) { log.warn("Couldn't update progress listener", e); } } } /** * An interface that filters the incoming events before passing them into * the registered listeners. */ public static interface ProgressEventFilter { /** * Returns the filtered event object that will be actually passed into * the listeners. Returns null if the event should be completely * blocked. */ public ProgressEvent filter(ProgressEvent progressEvent); } }