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/Apackage sun.net;
0N/A
0N/Aimport java.net.URL;
0N/A
0N/A/**
0N/A * ProgressSource represents the source of progress changes.
0N/A *
0N/A * @author Stanley Man-Kit Ho
0N/A */
0N/Apublic class ProgressSource
0N/A{
0N/A public enum State { NEW, CONNECTED, UPDATE, DELETE };
0N/A
0N/A // URL
0N/A private URL url;
0N/A // URL method
0N/A private String method;
0N/A // Content type
0N/A private String contentType;
0N/A // bytes read
0N/A private long progress = 0;
0N/A // last bytes read
0N/A private long lastProgress = 0;
0N/A //bytes expected
0N/A private long expected = -1;
0N/A // the last thing to happen with this source
0N/A private State state;
0N/A // connect flag
0N/A private boolean connected = false;
0N/A // threshold for notification
0N/A private int threshold = 8192;
0N/A // progress monitor
0N/A private ProgressMonitor progressMonitor;
0N/A
0N/A /**
0N/A * Construct progress source object.
0N/A */
0N/A public ProgressSource(URL url, String method) {
0N/A this(url, method, -1);
0N/A }
0N/A
0N/A /**
0N/A * Construct progress source object.
0N/A */
0N/A public ProgressSource(URL url, String method, long expected) {
0N/A this.url = url;
0N/A this.method = method;
0N/A this.contentType = "content/unknown";
0N/A this.progress = 0;
0N/A this.lastProgress = 0;
0N/A this.expected = expected;
0N/A this.state = State.NEW;
0N/A this.progressMonitor = ProgressMonitor.getDefault();
0N/A this.threshold = progressMonitor.getProgressUpdateThreshold();
0N/A }
0N/A
0N/A public boolean connected() {
0N/A if (!connected) {
0N/A connected = true;
0N/A state = State.CONNECTED;
0N/A return false;
0N/A }
0N/A return true;
0N/A }
0N/A
0N/A /**
0N/A * Close progress source.
0N/A */
0N/A public void close() {
0N/A state = State.DELETE;
0N/A }
0N/A
0N/A /**
0N/A * Return URL of progress source.
0N/A */
0N/A public URL getURL() {
0N/A return url;
0N/A }
0N/A
0N/A /**
0N/A * Return method of URL.
0N/A */
0N/A public String getMethod() {
0N/A return method;
0N/A }
0N/A
0N/A /**
0N/A * Return content type of URL.
0N/A */
0N/A public String getContentType() {
0N/A return contentType;
0N/A }
0N/A
0N/A // Change content type
0N/A public void setContentType(String ct) {
0N/A contentType = ct;
0N/A }
0N/A
0N/A /**
0N/A * Return current progress.
0N/A */
0N/A public long getProgress() {
0N/A return progress;
0N/A }
0N/A
0N/A /**
0N/A * Return expected maximum progress; -1 if expected is unknown.
0N/A */
0N/A public long getExpected() {
0N/A return expected;
0N/A }
0N/A
0N/A /**
0N/A * Return state.
0N/A */
0N/A public State getState() {
0N/A return state;
0N/A }
0N/A
0N/A /**
0N/A * Begin progress tracking.
0N/A */
0N/A public void beginTracking() {
0N/A progressMonitor.registerSource(this);
0N/A }
0N/A
0N/A /**
0N/A * Finish progress tracking.
0N/A */
0N/A public void finishTracking() {
0N/A progressMonitor.unregisterSource(this);
0N/A }
0N/A
0N/A /**
0N/A * Update progress.
0N/A */
0N/A public void updateProgress(long latestProgress, long expectedProgress) {
0N/A lastProgress = progress;
0N/A progress = latestProgress;
0N/A expected = expectedProgress;
0N/A
0N/A if (connected() == false)
0N/A state = State.CONNECTED;
0N/A else
0N/A state = State.UPDATE;
0N/A
0N/A // The threshold effectively divides the progress into
0N/A // different set of ranges:
0N/A //
0N/A // Range 0: 0..threshold-1,
0N/A // Range 1: threshold .. 2*threshold-1
0N/A // ....
0N/A // Range n: n*threshold .. (n+1)*threshold-1
0N/A //
0N/A // To determine which range the progress belongs to, it
0N/A // would be calculated as follow:
0N/A //
0N/A // range number = progress / threshold
0N/A //
0N/A // Notification should only be triggered when the current
0N/A // progress and the last progress are in different ranges,
0N/A // i.e. they have different range numbers.
0N/A //
0N/A // Using this range scheme, notification will be generated
0N/A // only once when the progress reaches each range.
0N/A //
0N/A if (lastProgress / threshold != progress / threshold) {
0N/A progressMonitor.updateProgress(this);
0N/A }
0N/A
0N/A // Detect read overrun
0N/A if (expected != -1) {
0N/A if (progress >= expected && progress != 0)
0N/A close();
0N/A }
0N/A }
0N/A
0N/A public Object clone() throws CloneNotSupportedException {
0N/A return super.clone();
0N/A }
0N/A
0N/A public String toString() {
0N/A return getClass().getName() + "[url=" + url + ", method=" + method + ", state=" + state
0N/A + ", content-type=" + contentType + ", progress=" + progress + ", expected=" + expected + "]";
0N/A }
0N/A}