001: /*
002: * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025: package sun.net;
026:
027: import java.net.URL;
028:
029: /**
030: * ProgressSource represents the source of progress changes.
031: *
032: * @author Stanley Man-Kit Ho
033: */
034: public class ProgressSource {
035: public enum State {
036: NEW, CONNECTED, UPDATE, DELETE
037: };
038:
039: // URL
040: private URL url;
041: // URL method
042: private String method;
043: // Content type
044: private String contentType;
045: // bytes read
046: private int progress = 0;
047: // last bytes read
048: private int lastProgress = 0;
049: //bytes expected
050: private int expected = -1;
051: // the last thing to happen with this source
052: private State state;
053: // connect flag
054: private boolean connected = false;
055: // threshold for notification
056: private int threshold = 8192;
057: // progress monitor
058: private ProgressMonitor progressMonitor;
059:
060: /**
061: * Construct progress source object.
062: */
063: public ProgressSource(URL url, String method) {
064: this (url, method, -1);
065: }
066:
067: /**
068: * Construct progress source object.
069: */
070: public ProgressSource(URL url, String method, int expected) {
071: this .url = url;
072: this .method = method;
073: this .contentType = "content/unknown";
074: this .progress = 0;
075: this .lastProgress = 0;
076: this .expected = expected;
077: this .state = State.NEW;
078: this .progressMonitor = ProgressMonitor.getDefault();
079: this .threshold = progressMonitor.getProgressUpdateThreshold();
080: }
081:
082: public boolean connected() {
083: if (!connected) {
084: connected = true;
085: state = State.CONNECTED;
086: return false;
087: }
088: return true;
089: }
090:
091: /**
092: * Close progress source.
093: */
094: public void close() {
095: state = State.DELETE;
096: }
097:
098: /**
099: * Return URL of progress source.
100: */
101: public URL getURL() {
102: return url;
103: }
104:
105: /**
106: * Return method of URL.
107: */
108: public String getMethod() {
109: return method;
110: }
111:
112: /**
113: * Return content type of URL.
114: */
115: public String getContentType() {
116: return contentType;
117: }
118:
119: // Change content type
120: public void setContentType(String ct) {
121: contentType = ct;
122: }
123:
124: /**
125: * Return current progress.
126: */
127: public int getProgress() {
128: return progress;
129: }
130:
131: /**
132: * Return expected maximum progress; -1 if expected is unknown.
133: */
134: public int getExpected() {
135: return expected;
136: }
137:
138: /**
139: * Return state.
140: */
141: public State getState() {
142: return state;
143: }
144:
145: /**
146: * Begin progress tracking.
147: */
148: public void beginTracking() {
149: progressMonitor.registerSource(this );
150: }
151:
152: /**
153: * Finish progress tracking.
154: */
155: public void finishTracking() {
156: progressMonitor.unregisterSource(this );
157: }
158:
159: /**
160: * Update progress.
161: */
162: public void updateProgress(int latestProgress, int expectedProgress) {
163: lastProgress = progress;
164: progress = latestProgress;
165: expected = expectedProgress;
166:
167: if (connected() == false)
168: state = State.CONNECTED;
169: else
170: state = State.UPDATE;
171:
172: // The threshold effectively divides the progress into
173: // different set of ranges:
174: //
175: // Range 0: 0..threshold-1,
176: // Range 1: threshold .. 2*threshold-1
177: // ....
178: // Range n: n*threshold .. (n+1)*threshold-1
179: //
180: // To determine which range the progress belongs to, it
181: // would be calculated as follow:
182: //
183: // range number = progress / threshold
184: //
185: // Notification should only be triggered when the current
186: // progress and the last progress are in different ranges,
187: // i.e. they have different range numbers.
188: //
189: // Using this range scheme, notification will be generated
190: // only once when the progress reaches each range.
191: //
192: if (lastProgress / threshold != progress / threshold) {
193: progressMonitor.updateProgress(this );
194: }
195:
196: // Detect read overrun
197: if (expected != -1) {
198: if (progress >= expected && progress != 0)
199: close();
200: }
201: }
202:
203: public Object clone() throws CloneNotSupportedException {
204: return super .clone();
205: }
206:
207: public String toString() {
208: return getClass().getName() + "[url=" + url + ", method="
209: + method + ", state=" + state + ", content-type="
210: + contentType + ", progress=" + progress
211: + ", expected=" + expected + "]";
212: }
213: }
|