001 
002 /*
003  *  JScripter Standard 1.0 - To Script In Java
004  *  Copyright (C) 2008-2011  J.J.Liu<jianjunliu@126.com> <http://www.jscripter.org>
005  *  
006  *  This program is free software: you can redistribute it and/or modify
007  *  it under the terms of the GNU Affero General Public License as published by
008  *  the Free Software Foundation, either version 3 of the License, or
009  *  (at your option) any later version.
010  *  
011  *  This program is distributed in the hope that it will be useful,
012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014  *  GNU Affero General Public License for more details.
015  *  
016  *  You should have received a copy of the GNU Affero General Public License
017  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
018  */
019 
020 package jsx;
021 
022 import js.Disposable;
023 import js.Function;
024 import js.Js;
025 import js.core.JsFunction;
026 
027 /**
028  * <p>An abstract base class for runnable tasks.</p>
029  * <p>As a runnable object, a runnable task can be run by a call to its {@link Task#run()} 
030  * method. In addition, you can get its function version with a simple call to its 
031  * {@link Task#getFunction()} method.</p>
032  * <p>To make a task concretely runnable, a subclass of this one must decide to either 
033  * override the {@link Task#run()} method, and in its constructor, with a call to the 
034  * {@link Task#getFunction()} method, set the {@link Task#funct} field to a function running the 
035  * {@link Task#run()} method , or set the {@link Task#funct} field directly in its constructor 
036  * to an existed function and run the {@link Task#funct} function in the method overriding 
037  * the {@link Task#run()} method of this class.</p>
038  * <p>A subclass of this class must follow the above rule to make sure that its function 
039  * version and method {@link Task#run()} are both running the same execution code.</p>
040  * 
041  * @author <a href="mailto:jianjunliu@126.com">J.J.Liu (Jianjun Liu)</a> at <a href="http://www.jscripter.org" target="_blank">http://www.jscripter.org</a>
042  * @see TaskManager
043  */
044 public abstract class Task extends Disposable implements Runnable
045 {
046     /**
047      * <p>The function version of this runnable task.</p>
048      * <p>If a subclass sets this field to a desired existing function in its constructor, 
049      * it must override the {@link Task#run()} method and run this function in that method. 
050      * On the contrary, if a subclass chooses to override the {@link Task#run()} method to 
051      * provide the task functionality, then it must, in its constructor, set this field to 
052      * a function returned by calling the {@link Task#getFunction()} method.</p>
053      * 
054      * @since 1.0
055      */
056     protected JsFunction<Void> funct;
057 
058     /**
059      * <p>The default constructor.</p>
060      * <p>This constructor does not set the {@link Task#funct} field. A call to the {@link Task#getFunction()} 
061      * method will set it up anyway. A subclass, in its need, may choose to set the {@link Task#funct} 
062      * field in any of its constructors including the default one.</p>
063      * @since 1.0
064      */
065     protected Task() {}
066 
067     /**
068      * <p>Runs the runnable task.</p>
069      * <p>If a subclass chooses to override this method to provide the task functionality, then 
070      * it must, in its constructor, set the {@link Task#funct} field to a function returned by 
071      * calling the {@link Task#getFunction()} method. On the contrary, if a subclass sets the {@link Task#getFunction()} 
072      * field to a desired existing function in its constructor, then it must override this 
073      * method and run that function in the overriding method.</p>
074      * @since 1.0
075      */
076     public abstract void run();
077 
078     /**
079      * <p>Gets the function version of this runnable task.</p>
080      * <p>This method returns the function if it already exists. Otherwise, it creates one that 
081      * simply runs the {@link #run()} method.</p>
082      * @return The function for the current runnable task if it exists. Otherwise the method 
083      * creates one and returns it.
084      * @since 1.0
085      */
086     public final JsFunction<Void> getFunction() {
087         if (Js.not(funct)) {
088             funct = makeFunction(this);
089         }
090         return funct;
091     }
092 
093     /**
094      * <p>A utility to create a function from a runnable object.</p>
095      * <p>The function simply runs the {@link Runnable#run()} method of the runnable object 
096      * and returns nothing (<tt>null</tt> for undefined).</p>
097      * @param r A runnable object.
098      * @return The function for the runnable object.
099      * @since 1.0
100      */
101     public static final JsFunction<Void> makeFunction(final Runnable r) {
102         return new Function<Void>() {
103             @Override
104             protected Void function(Object jsthis, Call<Void> callee) {
105                 r.run();
106                 return null;
107             }
108         }.var();
109     }
110 }