Coverage Report - com.sun.javafx.runtime.async.AbstractAsyncOperation
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractAsyncOperation
0%
0/40
0%
0/6
0
AbstractAsyncOperation$1
0%
0/2
N/A
0
AbstractAsyncOperation$2
0%
0/10
0%
0/2
0
AbstractAsyncOperation$3
0%
0/5
N/A
0
AbstractAsyncOperation$4
0%
0/3
N/A
0
 
 1  
 /*
 2  
  * Copyright 2007 Sun Microsystems, Inc.  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.  Sun designates this
 8  
  * particular file as subject to the "Classpath" exception as provided
 9  
  * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 22  
  * CA 95054 USA or visit www.sun.com if you need additional information or
 23  
  * have any questions.
 24  
  */
 25  
 
 26  
 package com.sun.javafx.runtime.async;
 27  
 
 28  
 import java.util.concurrent.Callable;
 29  
 import java.util.concurrent.ExecutionException;
 30  
 import java.util.concurrent.FutureTask;
 31  
 
 32  
 import com.sun.javafx.runtime.Entry;
 33  
 
 34  
 /**
 35  
  * AbstractAsyncOperation.   Base class for result-bearing, asynchronous operations. Some operations are asynchronous
 36  
  * because they would potentially block the EDT for unacceptably long. Since JFX lacks a clear concurrency model,
 37  
  * allowing users to execute arbitrary JFX code in background threads would invariably cause problems.  Therefore,
 38  
  * we provide a number of Java classes for async operations, which will execute in a background thread, such as
 39  
  * "fetch a resource over the web".  Async operations should not access any JFX state except the immutable parameters
 40  
  * passed in, and should not have side effects other than those managed by thread-safe Java classes.
 41  
  *
 42  
  * Async operations are one-time use; subclasses should not attempt to reuse them.  
 43  
  *
 44  
  * @author Brian Goetz
 45  
  */
 46  0
 public abstract class AbstractAsyncOperation<V> implements Callable<V> {
 47  
 
 48  
     private final FutureTask<V> future;
 49  
     protected final AsyncOperationListener listener;
 50  
 
 51  0
     private int progressGranularity = 100;
 52  
     private int progressMax, lastProgress, progressIncrement, nextProgress, bytesRead;
 53  
 
 54  0
     protected AbstractAsyncOperation(final AsyncOperationListener<V> listener) {
 55  0
         this.listener = listener;
 56  
 
 57  0
         Callable<V> callable = new Callable<V>() {
 58  
             public V call() throws Exception {
 59  0
                 return AbstractAsyncOperation.this.call();
 60  
             }
 61  
         };
 62  
 
 63  0
         final Runnable completionRunnable = new Runnable() {
 64  
             public void run() {
 65  0
                 if (future.isCancelled()) {
 66  0
                     listener.onCancel();
 67  
                 }
 68  
                 else
 69  
                     try {
 70  0
                         listener.onCompletion(future.get());
 71  
                     }
 72  0
                     catch (InterruptedException e) {
 73  0
                         listener.onCancel();
 74  
                     }
 75  0
                     catch (ExecutionException e) {
 76  0
                         listener.onException(e);
 77  0
                     }
 78  0
             }
 79  
         };
 80  
 
 81  0
         future = new FutureTask<V>(callable) {
 82  
             @Override
 83  
             protected void done() {
 84  
                 try {
 85  0
                     Entry.deferTask(completionRunnable);
 86  
                 }
 87  
                 finally {
 88  0
                     super.done();
 89  0
                 }
 90  0
             }
 91  
         };
 92  0
     }
 93  
 
 94  
     public boolean isCancelled() {
 95  0
         return future.isCancelled();
 96  
     }
 97  
 
 98  
     public boolean isDone() {
 99  0
         return future.isDone();
 100  
     }
 101  
 
 102  
     public void cancel() {
 103  0
         future.cancel(true);
 104  0
     }
 105  
 
 106  
     public void start() {
 107  0
         BackgroundExecutor.getExecutor().execute(future);
 108  0
     }
 109  
 
 110  
     protected void notifyProgress() {
 111  0
         final int last = lastProgress;
 112  0
         final int max = progressMax;
 113  0
         Entry.deferTask(new Runnable() {
 114  
             public void run() {
 115  0
                 listener.onProgress(last, max);
 116  0
             }
 117  
         });
 118  0
     }
 119  
 
 120  
     protected void addProgress(int amount) {
 121  0
         bytesRead += amount;
 122  0
         if (bytesRead > nextProgress) {
 123  0
             lastProgress = bytesRead;
 124  0
             notifyProgress();
 125  0
             nextProgress = ((lastProgress / progressIncrement) + 1) * progressIncrement;
 126  
         }
 127  0
     }
 128  
 
 129  
     protected int getProgressMax() {
 130  0
         return progressMax;
 131  
     }
 132  
 
 133  
     protected void setProgressMax(int progressMax) {
 134  0
         if (progressMax == 0) {
 135  0
             progressIncrement = progressGranularity;
 136  
         }
 137  0
         else if (progressMax == -1) {
 138  0
             progressIncrement = progressGranularity;
 139  
         }
 140  
         else {
 141  0
             this.progressMax = progressMax;
 142  0
             progressIncrement = progressMax / progressGranularity;
 143  
         }
 144  0
         nextProgress = ((lastProgress / progressIncrement) + 1) * progressIncrement;
 145  0
         notifyProgress();
 146  0
     }
 147  
 
 148  
     protected int getProgressGranularity() {
 149  0
         return progressGranularity;
 150  
     }
 151  
 
 152  
     protected void setProgressGranularity(int progressGranularity) {
 153  0
         this.progressGranularity = progressGranularity;
 154  0
         progressIncrement = progressMax / progressGranularity;
 155  0
         nextProgress = ((lastProgress / progressIncrement) + 1) * progressIncrement;
 156  0
         notifyProgress();
 157  0
     }
 158  
 
 159  
 }