Home | History | Annotate | Download | only in net
      1 /*
      2  * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
      3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      4  *
      5  * This code is free software; you can redistribute it and/or modify it
      6  * under the terms of the GNU General Public License version 2 only, as
      7  * published by the Free Software Foundation.  Oracle designates this
      8  * particular file as subject to the "Classpath" exception as provided
      9  * by Oracle in the LICENSE file that accompanied this code.
     10  *
     11  * This code is distributed in the hope that it will be useful, but WITHOUT
     12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     14  * version 2 for more details (a copy is included in the LICENSE file that
     15  * accompanied this code).
     16  *
     17  * You should have received a copy of the GNU General Public License version
     18  * 2 along with this work; if not, write to the Free Software Foundation,
     19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     20  *
     21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     22  * or visit www.oracle.com if you need additional information or have any
     23  * questions.
     24  */
     25 package sun.net;
     26 
     27 import java.net.URL;
     28 
     29 /**
     30  * ProgressSource represents the source of progress changes.
     31  *
     32  * @author Stanley Man-Kit Ho
     33  */
     34 public class ProgressSource
     35 {
     36     public enum State { NEW, CONNECTED, UPDATE, DELETE };
     37 
     38     // URL
     39     private URL url;
     40     // URL method
     41     private String method;
     42     // Content type
     43     private String contentType;
     44     // bytes read
     45     private long progress = 0;
     46     // last bytes read
     47     private long lastProgress = 0;
     48     //bytes expected
     49     private long expected = -1;
     50     // the last thing to happen with this source
     51     private State state;
     52     // connect flag
     53     private boolean connected = false;
     54     // threshold for notification
     55     private int threshold = 8192;
     56     // progress monitor
     57     private ProgressMonitor progressMonitor;
     58 
     59     /**
     60      * Construct progress source object.
     61      */
     62     public ProgressSource(URL url, String method) {
     63         this(url, method, -1);
     64     }
     65 
     66     /**
     67      * Construct progress source object.
     68      */
     69     public ProgressSource(URL url, String method, long expected)  {
     70         this.url = url;
     71         this.method = method;
     72         this.contentType = "content/unknown";
     73         this.progress = 0;
     74         this.lastProgress = 0;
     75         this.expected = expected;
     76         this.state = State.NEW;
     77         this.progressMonitor = ProgressMonitor.getDefault();
     78         this.threshold = progressMonitor.getProgressUpdateThreshold();
     79     }
     80 
     81     public boolean connected() {
     82         if (!connected) {
     83             connected = true;
     84             state = State.CONNECTED;
     85             return false;
     86         }
     87         return true;
     88     }
     89 
     90     /**
     91      * Close progress source.
     92      */
     93     public void close() {
     94         state = State.DELETE;
     95     }
     96 
     97     /**
     98      * Return URL of progress source.
     99      */
    100     public URL getURL() {
    101         return url;
    102     }
    103 
    104     /**
    105      * Return method of URL.
    106      */
    107     public String getMethod()  {
    108         return method;
    109     }
    110 
    111     /**
    112      * Return content type of URL.
    113      */
    114     public String getContentType()  {
    115         return contentType;
    116     }
    117 
    118     // Change content type
    119     public void setContentType(String ct)  {
    120         contentType = ct;
    121     }
    122 
    123     /**
    124      * Return current progress.
    125      */
    126     public long getProgress()  {
    127         return progress;
    128     }
    129 
    130     /**
    131      * Return expected maximum progress; -1 if expected is unknown.
    132      */
    133     public long getExpected() {
    134         return expected;
    135     }
    136 
    137     /**
    138      * Return state.
    139      */
    140     public State getState() {
    141         return state;
    142     }
    143 
    144     /**
    145      * Begin progress tracking.
    146      */
    147     public void beginTracking() {
    148         progressMonitor.registerSource(this);
    149     }
    150 
    151     /**
    152      * Finish progress tracking.
    153      */
    154     public void finishTracking() {
    155         progressMonitor.unregisterSource(this);
    156     }
    157 
    158     /**
    159      * Update progress.
    160      */
    161     public void updateProgress(long latestProgress, long expectedProgress) {
    162         lastProgress = progress;
    163         progress = latestProgress;
    164         expected = expectedProgress;
    165 
    166         if (connected() == false)
    167             state = State.CONNECTED;
    168         else
    169             state = State.UPDATE;
    170 
    171         // The threshold effectively divides the progress into
    172         // different set of ranges:
    173         //
    174         //      Range 0: 0..threshold-1,
    175         //      Range 1: threshold .. 2*threshold-1
    176         //      ....
    177         //      Range n: n*threshold .. (n+1)*threshold-1
    178         //
    179         // To determine which range the progress belongs to, it
    180         // would be calculated as follow:
    181         //
    182         //      range number = progress / threshold
    183         //
    184         // Notification should only be triggered when the current
    185         // progress and the last progress are in different ranges,
    186         // i.e. they have different range numbers.
    187         //
    188         // Using this range scheme, notification will be generated
    189         // only once when the progress reaches each range.
    190         //
    191         if (lastProgress / threshold != progress / threshold)   {
    192             progressMonitor.updateProgress(this);
    193         }
    194 
    195         // Detect read overrun
    196         if (expected != -1) {
    197             if (progress >= expected && progress != 0)
    198                 close();
    199         }
    200     }
    201 
    202     public Object clone() throws CloneNotSupportedException {
    203         return super.clone();
    204     }
    205 
    206     public String toString()    {
    207         return getClass().getName() + "[url=" + url + ", method=" + method + ", state=" + state
    208             + ", content-type=" + contentType + ", progress=" + progress + ", expected=" + expected + "]";
    209     }
    210 }
    211