001: /*
002: * @(#)ProgressData.java 1.25 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027:
028: package sun.net;
029:
030: import java.util.Observer;
031: import java.util.Observable;
032: import java.net.URL;
033:
034: /* Making update(), register(), and unregister() unsynchronized
035: * since these make callbacks into arbitrary code and can cause
036: * deadlocks if holding a monitor while doing so. Synchronize only
037: * necessary blocks that add/delete entries. -brown 8/27/96
038: */
039:
040: public class ProgressData extends Observable {
041: // We create a single instance of this class.
042: // the Observer/Observable stuff only works with instances.
043: //
044: public static ProgressData pdata = new ProgressData();
045: public static final int NEW = 0;
046: public static final int CONNECTED = 1;
047: public static final int UPDATE = 2;
048: public static final int DELETE = 3;
049:
050: private ProgressEntry streams[] = new ProgressEntry[20];
051:
052: /** Get a snapshot of the internal state of of the streams */
053:
054: public synchronized ProgressEntry[] getStreams() {
055: return (ProgressEntry[]) streams.clone();
056: }
057:
058: /**
059: * Call this routine to register a new URL for the progress
060: * window. Until it is marked as connected this entry will have
061: * a busy indicator.
062: */
063: public void register(ProgressEntry te) {
064: int i;
065:
066: boolean localChanged = false;
067: for (i = 0; i < streams.length; i++) {
068: synchronized (this ) {
069: if (streams[i] == null) {
070: streams[i] = te;
071: te.what = NEW;
072: te.index = i;
073: localChanged = true;
074: break;
075: }
076: }
077: }
078: if (localChanged) {
079: setChanged();
080: /* only notify w/o holding lock */
081: notifyObservers(te);
082: }
083: }
084:
085: /**
086: * Call this routine to register a new URL for the progress
087: * window. until it is marked as connected this entry will have
088: * a busy indicator.
089: */
090: public void connected(URL m) {
091: /* AVH: I made this a noop since it sends a CONNECT
092: * message when the first data arrives.
093: */
094: }
095:
096: /**
097: * Call this routine to unregister a new URL for the progress
098: * window. This will nuke the indicator from the ProgressWindow.
099: */
100: public void unregister(ProgressEntry te) {
101:
102: synchronized (this ) {
103: int i = te.index;
104: if (i < 0 || i > streams.length || streams[i] != te) {
105: return;
106: }
107: te.what = DELETE;
108: streams[i] = null;
109: setChanged();
110: }
111: notifyObservers(te);
112: }
113:
114: public void update(ProgressEntry te) {
115: /* Should get the URLConnection,
116: * instead of the URL, in order to
117: * get the content-type
118: */
119: synchronized (this ) {
120: int i = te.index;
121: if (i < 0 || i > streams.length || streams[i] != te) {
122: return;
123: }
124: // te.update(total_read, total_need);
125: te.what = UPDATE;
126: if (!te.connected()) {
127: // te.setType(m.getFile(), null/*m.content_type*/);
128: te.what = CONNECTED;
129: }
130: if (te.read >= te.need && te.read != 0) {
131: streams[i] = null;
132: te.what = DELETE;
133: }
134: setChanged();
135: } /* end sync block */
136: /* <DEBUG> -- try to force potential deadlocks in finalizers */
137: // Runtime.getRuntime().gc();
138: // Runtime.getRuntime().runFinalization();
139: /* </DEBUG> */
140: notifyObservers(te);
141: }
142:
143: }
|