Path: blob/master/src/java.base/share/classes/sun/net/ProgressMonitor.java
41152 views
/*1* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.net;2627import java.util.ArrayList;28import java.util.Iterator;29import java.net.URL;3031/**32* ProgressMonitor is a class for monitoring progress in network input stream.33*34* @author Stanley Man-Kit Ho35*/36public class ProgressMonitor37{38/**39* Return default ProgressMonitor.40*/41public static synchronized ProgressMonitor getDefault() {42return pm;43}4445/**46* Change default ProgressMonitor implementation.47*/48public static synchronized void setDefault(ProgressMonitor m) {49if (m != null)50pm = m;51}5253/**54* Change progress metering policy.55*/56public static synchronized void setMeteringPolicy(ProgressMeteringPolicy policy) {57if (policy != null)58meteringPolicy = policy;59}606162/**63* Return a snapshot of the ProgressSource list64*/65public ArrayList<ProgressSource> getProgressSources() {66ArrayList<ProgressSource> snapshot = new ArrayList<>();6768try {69synchronized(progressSourceList) {70for (Iterator<ProgressSource> iter = progressSourceList.iterator(); iter.hasNext();) {71ProgressSource pi = iter.next();7273// Clone ProgressSource and add to snapshot74snapshot.add((ProgressSource)pi.clone());75}76}77}78catch(CloneNotSupportedException e) {79e.printStackTrace();80}8182return snapshot;83}8485/**86* Return update notification threshold87*/88public synchronized int getProgressUpdateThreshold() {89return meteringPolicy.getProgressUpdateThreshold();90}9192/**93* Return true if metering should be turned on94* for a particular URL input stream.95*/96public boolean shouldMeterInput(URL url, String method) {97return meteringPolicy.shouldMeterInput(url, method);98}99100/**101* Register progress source when progress is began.102*/103public void registerSource(ProgressSource pi) {104105synchronized(progressSourceList) {106if (progressSourceList.contains(pi))107return;108109progressSourceList.add(pi);110}111112// Notify only if there is at least one listener113if (progressListenerList.size() > 0)114{115// Notify progress listener if there is progress change116ArrayList<ProgressListener> listeners = new ArrayList<>();117118// Copy progress listeners to another list to avoid holding locks119synchronized(progressListenerList) {120for (Iterator<ProgressListener> iter = progressListenerList.iterator(); iter.hasNext();) {121listeners.add(iter.next());122}123}124125// Fire event on each progress listener126for (Iterator<ProgressListener> iter = listeners.iterator(); iter.hasNext();) {127ProgressListener pl = iter.next();128ProgressEvent pe = new ProgressEvent(pi, pi.getURL(), pi.getMethod(), pi.getContentType(), pi.getState(), pi.getProgress(), pi.getExpected());129pl.progressStart(pe);130}131}132}133134/**135* Unregister progress source when progress is finished.136*/137public void unregisterSource(ProgressSource pi) {138139synchronized(progressSourceList) {140// Return if ProgressEvent does not exist141if (progressSourceList.contains(pi) == false)142return;143144// Close entry and remove from map145pi.close();146progressSourceList.remove(pi);147}148149// Notify only if there is at least one listener150if (progressListenerList.size() > 0)151{152// Notify progress listener if there is progress change153ArrayList<ProgressListener> listeners = new ArrayList<>();154155// Copy progress listeners to another list to avoid holding locks156synchronized(progressListenerList) {157for (Iterator<ProgressListener> iter = progressListenerList.iterator(); iter.hasNext();) {158listeners.add(iter.next());159}160}161162// Fire event on each progress listener163for (Iterator<ProgressListener> iter = listeners.iterator(); iter.hasNext();) {164ProgressListener pl = iter.next();165ProgressEvent pe = new ProgressEvent(pi, pi.getURL(), pi.getMethod(), pi.getContentType(), pi.getState(), pi.getProgress(), pi.getExpected());166pl.progressFinish(pe);167}168}169}170171/**172* Progress source is updated.173*/174public void updateProgress(ProgressSource pi) {175176synchronized (progressSourceList) {177if (progressSourceList.contains(pi) == false)178return;179}180181// Notify only if there is at least one listener182if (progressListenerList.size() > 0)183{184// Notify progress listener if there is progress change185ArrayList<ProgressListener> listeners = new ArrayList<>();186187// Copy progress listeners to another list to avoid holding locks188synchronized(progressListenerList) {189for (Iterator<ProgressListener> iter = progressListenerList.iterator(); iter.hasNext();) {190listeners.add(iter.next());191}192}193194// Fire event on each progress listener195for (Iterator<ProgressListener> iter = listeners.iterator(); iter.hasNext();) {196ProgressListener pl = iter.next();197ProgressEvent pe = new ProgressEvent(pi, pi.getURL(), pi.getMethod(), pi.getContentType(), pi.getState(), pi.getProgress(), pi.getExpected());198pl.progressUpdate(pe);199}200}201}202203/**204* Add progress listener in progress monitor.205*/206public void addProgressListener(ProgressListener l) {207synchronized(progressListenerList) {208progressListenerList.add(l);209}210}211212/**213* Remove progress listener from progress monitor.214*/215public void removeProgressListener(ProgressListener l) {216synchronized(progressListenerList) {217progressListenerList.remove(l);218}219}220221// Metering policy222private static ProgressMeteringPolicy meteringPolicy = new DefaultProgressMeteringPolicy();223224// Default implementation225private static ProgressMonitor pm = new ProgressMonitor();226227// ArrayList for outstanding progress sources228private ArrayList<ProgressSource> progressSourceList = new ArrayList<ProgressSource>();229230// ArrayList for progress listeners231private ArrayList<ProgressListener> progressListenerList = new ArrayList<ProgressListener>();232}233234235/**236* Default progress metering policy.237*/238class DefaultProgressMeteringPolicy implements ProgressMeteringPolicy {239/**240* Return true if metering should be turned on for a particular network input stream.241*/242public boolean shouldMeterInput(URL url, String method)243{244// By default, no URL input stream is metered for245// performance reason.246return false;247}248249/**250* Return update notification threshold.251*/252public int getProgressUpdateThreshold() {253// 8K - same as default I/O buffer size254return 8192;255}256}257258259