0N/A/*
2362N/A * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.net;
0N/A
0N/Aimport java.util.ArrayList;
0N/Aimport java.util.Iterator;
0N/Aimport java.net.URL;
0N/A
0N/A/**
0N/A * ProgressMonitor is a class for monitoring progress in network input stream.
0N/A *
0N/A * @author Stanley Man-Kit Ho
0N/A */
0N/Apublic class ProgressMonitor
0N/A{
0N/A /**
0N/A * Return default ProgressMonitor.
0N/A */
0N/A public static synchronized ProgressMonitor getDefault() {
0N/A return pm;
0N/A }
0N/A
0N/A /**
0N/A * Change default ProgressMonitor implementation.
0N/A */
0N/A public static synchronized void setDefault(ProgressMonitor m) {
0N/A if (m != null)
0N/A pm = m;
0N/A }
0N/A
0N/A /**
0N/A * Change progress metering policy.
0N/A */
0N/A public static synchronized void setMeteringPolicy(ProgressMeteringPolicy policy) {
0N/A if (policy != null)
0N/A meteringPolicy = policy;
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Return a snapshot of the ProgressSource list
0N/A */
0N/A public ArrayList<ProgressSource> getProgressSources() {
0N/A ArrayList<ProgressSource> snapshot = new ArrayList<ProgressSource>();
0N/A
0N/A try {
0N/A synchronized(progressSourceList) {
0N/A for (Iterator<ProgressSource> iter = progressSourceList.iterator(); iter.hasNext();) {
0N/A ProgressSource pi = iter.next();
0N/A
0N/A // Clone ProgressSource and add to snapshot
0N/A snapshot.add((ProgressSource)pi.clone());
0N/A }
0N/A }
0N/A }
0N/A catch(CloneNotSupportedException e) {
0N/A e.printStackTrace();
0N/A }
0N/A
0N/A return snapshot;
0N/A }
0N/A
0N/A /**
0N/A * Return update notification threshold
0N/A */
0N/A public synchronized int getProgressUpdateThreshold() {
0N/A return meteringPolicy.getProgressUpdateThreshold();
0N/A }
0N/A
0N/A /**
0N/A * Return true if metering should be turned on
0N/A * for a particular URL input stream.
0N/A */
0N/A public boolean shouldMeterInput(URL url, String method) {
0N/A return meteringPolicy.shouldMeterInput(url, method);
0N/A }
0N/A
0N/A /**
0N/A * Register progress source when progress is began.
0N/A */
0N/A public void registerSource(ProgressSource pi) {
0N/A
0N/A synchronized(progressSourceList) {
0N/A if (progressSourceList.contains(pi))
0N/A return;
0N/A
0N/A progressSourceList.add(pi);
0N/A }
0N/A
0N/A // Notify only if there is at least one listener
0N/A if (progressListenerList.size() > 0)
0N/A {
0N/A // Notify progress listener if there is progress change
0N/A ArrayList<ProgressListener> listeners = new ArrayList<ProgressListener>();
0N/A
0N/A // Copy progress listeners to another list to avoid holding locks
0N/A synchronized(progressListenerList) {
0N/A for (Iterator<ProgressListener> iter = progressListenerList.iterator(); iter.hasNext();) {
0N/A listeners.add(iter.next());
0N/A }
0N/A }
0N/A
0N/A // Fire event on each progress listener
0N/A for (Iterator<ProgressListener> iter = listeners.iterator(); iter.hasNext();) {
0N/A ProgressListener pl = iter.next();
0N/A ProgressEvent pe = new ProgressEvent(pi, pi.getURL(), pi.getMethod(), pi.getContentType(), pi.getState(), pi.getProgress(), pi.getExpected());
0N/A pl.progressStart(pe);
0N/A }
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Unregister progress source when progress is finished.
0N/A */
0N/A public void unregisterSource(ProgressSource pi) {
0N/A
0N/A synchronized(progressSourceList) {
0N/A // Return if ProgressEvent does not exist
0N/A if (progressSourceList.contains(pi) == false)
0N/A return;
0N/A
0N/A // Close entry and remove from map
0N/A pi.close();
0N/A progressSourceList.remove(pi);
0N/A }
0N/A
0N/A // Notify only if there is at least one listener
0N/A if (progressListenerList.size() > 0)
0N/A {
0N/A // Notify progress listener if there is progress change
0N/A ArrayList<ProgressListener> listeners = new ArrayList<ProgressListener>();
0N/A
0N/A // Copy progress listeners to another list to avoid holding locks
0N/A synchronized(progressListenerList) {
0N/A for (Iterator<ProgressListener> iter = progressListenerList.iterator(); iter.hasNext();) {
0N/A listeners.add(iter.next());
0N/A }
0N/A }
0N/A
0N/A // Fire event on each progress listener
0N/A for (Iterator<ProgressListener> iter = listeners.iterator(); iter.hasNext();) {
0N/A ProgressListener pl = iter.next();
0N/A ProgressEvent pe = new ProgressEvent(pi, pi.getURL(), pi.getMethod(), pi.getContentType(), pi.getState(), pi.getProgress(), pi.getExpected());
0N/A pl.progressFinish(pe);
0N/A }
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Progress source is updated.
0N/A */
0N/A public void updateProgress(ProgressSource pi) {
0N/A
0N/A synchronized (progressSourceList) {
0N/A if (progressSourceList.contains(pi) == false)
0N/A return;
0N/A }
0N/A
0N/A // Notify only if there is at least one listener
0N/A if (progressListenerList.size() > 0)
0N/A {
0N/A // Notify progress listener if there is progress change
0N/A ArrayList<ProgressListener> listeners = new ArrayList<ProgressListener>();
0N/A
0N/A // Copy progress listeners to another list to avoid holding locks
0N/A synchronized(progressListenerList) {
0N/A for (Iterator<ProgressListener> iter = progressListenerList.iterator(); iter.hasNext();) {
0N/A listeners.add(iter.next());
0N/A }
0N/A }
0N/A
0N/A // Fire event on each progress listener
0N/A for (Iterator<ProgressListener> iter = listeners.iterator(); iter.hasNext();) {
0N/A ProgressListener pl = iter.next();
0N/A ProgressEvent pe = new ProgressEvent(pi, pi.getURL(), pi.getMethod(), pi.getContentType(), pi.getState(), pi.getProgress(), pi.getExpected());
0N/A pl.progressUpdate(pe);
0N/A }
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Add progress listener in progress monitor.
0N/A */
0N/A public void addProgressListener(ProgressListener l) {
0N/A synchronized(progressListenerList) {
0N/A progressListenerList.add(l);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Remove progress listener from progress monitor.
0N/A */
0N/A public void removeProgressListener(ProgressListener l) {
0N/A synchronized(progressListenerList) {
0N/A progressListenerList.remove(l);
0N/A }
0N/A }
0N/A
0N/A // Metering policy
0N/A private static ProgressMeteringPolicy meteringPolicy = new DefaultProgressMeteringPolicy();
0N/A
0N/A // Default implementation
0N/A private static ProgressMonitor pm = new ProgressMonitor();
0N/A
0N/A // ArrayList for outstanding progress sources
0N/A private ArrayList<ProgressSource> progressSourceList = new ArrayList<ProgressSource>();
0N/A
0N/A // ArrayList for progress listeners
0N/A private ArrayList<ProgressListener> progressListenerList = new ArrayList<ProgressListener>();
0N/A}
0N/A
0N/A
0N/A/**
0N/A * Default progress metering policy.
0N/A */
0N/Aclass DefaultProgressMeteringPolicy implements ProgressMeteringPolicy {
0N/A /**
0N/A * Return true if metering should be turned on for a particular network input stream.
0N/A */
0N/A public boolean shouldMeterInput(URL url, String method)
0N/A {
0N/A // By default, no URL input stream is metered for
0N/A // performance reason.
0N/A return false;
0N/A }
0N/A
0N/A /**
0N/A * Return update notification threshold.
0N/A */
0N/A public int getProgressUpdateThreshold() {
0N/A // 8K - same as default I/O buffer size
0N/A return 8192;
0N/A }
0N/A}