⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 conditionalactionrunner.java

📁 手机邮箱撒的方式方式方式的
💻 JAVA
字号:
/*MujMail - Simple mail client for J2MECopyright (C) 2009 David Hauzar <david.hauzar.mujmail@gmail.com>This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */package mujmail.tasks;import java.util.Enumeration;import java.util.Vector;import mujmail.MujMail;import mujmail.util.Callback;import mujmail.util.Condition;import mujmail.util.Functions;import mujmail.util.Observable;import mujmail.util.Observer;/** * Runs given action when given condition is true. The condition is checked * every time some task is started or terminated. * * It is guaranteed that between testing the condition and doing the action * no task is started and no task is terminated. * Than, it is ensured that between testing the condition and doing the action * no condition of other instance of <code>ConditionalActionRunner</code> is * tested and no action of other instance of <code>ConditionalActionRunner</code> * is started. * * Ensures that the action is done only once. * * @author David Hauzar */public class ConditionalActionRunner implements Observer {    /** Flag signals if we want to print debug prints */    protected static final boolean DEBUG = false;    private final Callback action;    private final Condition condition;    private boolean actionWasDone = false;    private Callback actionWhenConditionNotHolds;    /**     * Creates the instance of ConditionalActionRunner.     * @param condition the condition that will be checked     * @param action the action that will be runned if the condition is true.     */    public ConditionalActionRunner(Condition condition, Callback action) {        this.condition = condition;        this.action = action;            }    /**     * Conditionally starts the action. That means that it checks whether the     * condition holds. If it holds, starts the action. If not, runs the action     * <code>actionWhenConditionNotHolds</code> and waits for the start or     * termination of some task to check the condition again.     *     * @param actionWhenConditionNotHolds the action that will be runned if the     *  condition does not hold before waiting for the next checking of the     *  condition.     */    public void startAction(Callback actionWhenConditionNotHolds) {        this.actionWhenConditionNotHolds = actionWhenConditionNotHolds;        actionWasDone = false;        registerObservers();        if (!testConditionAndDoAction(this, new ConditionArgument(), actionWhenConditionNotHolds)) {            actionWhenConditionNotHolds.callback(this, null);            return;        }    }    /**     * Tests the condition and if the condition holds, do the action.     * This method is synchronized so only one instance of this class can test     * the condition and do the action in one time.     * Ensures that no task is started and no task terminates between testing     * the condiotion and doing the action.     *      * @param actionRunner the action runner that condition will be tested and     *  that action could be done.     * @param conditionArgument the argument of the condition.     * @return true if the condtion holded and the action was done.     */    private static synchronized boolean testConditionAndDoAction(ConditionalActionRunner actionRunner, ConditionArgument conditionArgument, Callback actionWhenConditionNotHolds) {        BackgroundTask.disableStartingTasks();        BackgroundTask.disableTerminatingTasks();        if (actionRunner.actionWasDone) return true;        boolean result = actionRunner.condition.condition(conditionArgument);        if (result) {            if (actionWhenConditionNotHolds instanceof ConditionalActionRunnerUI) {                ((ConditionalActionRunnerUI)actionWhenConditionNotHolds).cancelDisplaying();            }            actionRunner.doTheAction();        }        BackgroundTask.enableStartingTasks();        BackgroundTask.enableTerminatingTasks();        return result;    }    /**     * Do the action without checking the condition.     * The action can be done only once so unregisters the this conditional     * action runner to don't check the condition when some task is started     * or terminated.     *      */    public void doTheAction() {        cancelAction();        if (DEBUG) System.out.println("do the action: " + this);        if (!actionWasDone) {            if (DEBUG) System.out.println("doing action");            action.callback(this, null);            actionWasDone = true;        }    }    /**     * Conditionally starts the action. That means that it checks whether the     * condition holds. If it holds, starts the action. If not, waits for the     * start or termination of some task to check the condition again.     */    public void startAction() {        startAction(Callback.NO_ACTION);    }    public synchronized void update(Observable o, Object arg) {        if (DEBUG) System.out.println("Update called");        ConditionArgument conditionArgument = new ConditionArgument();        conditionArgument.task = (BackgroundTask) arg;        if (o == TasksManager.endTaskObservable) {            conditionArgument.conditionCheckingReason = ReasonsForCheckingCondition.TERMINATED;        } else {            conditionArgument.conditionCheckingReason = ReasonsForCheckingCondition.STARTED;        }        testConditionAndDoAction(this, conditionArgument, actionWhenConditionNotHolds);    }    /**     * Cancels the action.     *      * This conditional action runner will not check the condition when some     * task will started or terminated.     */    public void cancelAction() {        if (DEBUG) System.out.println("cancel action" + this);        unregisterObservers();    }    /**     * Registers this object to update itself every time some task is started     * or terminated.     */    protected void registerObservers() {        TasksManager.addEndTaskObserver(this);        TasksManager.addStartTaskObserver(this);    }    /**     * Unregisters this object to not update itself every time some task is     * started or terminated.     */    protected void unregisterObservers() {        TasksManager.deleteEndTaskObserver(this);        TasksManager.deleteStartTaskObserver(this);    }    /**     * Object of this class is possed as argument to method     * {@link mujmail.util.Condition#condition(java.lang.Object)}     */    public static class ConditionArgument {        /** The task that caused checking of the condition. Null if this is initiall checking of the condition. */        public BackgroundTask task = null;        /** Why is the condition checked. */        public ReasonsForCheckingCondition conditionCheckingReason = ReasonsForCheckingCondition.INITIAL;    }    /**     * Enumeration class with reasons of checking of the condition.     */    public static class ReasonsForCheckingCondition {        private ReasonsForCheckingCondition() {};        /** Initial checking of the condition. */        public static ReasonsForCheckingCondition INITIAL = new ReasonsForCheckingCondition();        /** The condition is checked because some task started. */        public static ReasonsForCheckingCondition STARTED = new ReasonsForCheckingCondition();        /** The condition is checked because some task terminated. */        public static ReasonsForCheckingCondition TERMINATED = new ReasonsForCheckingCondition();    }    /**     * The condition for exiting application. The number of incompleted task     * must be zero.     * Singleton class with one instance condition.     */    public static class ExitApplicationCondition implements Condition {        private ExitApplicationCondition() {};        /** The condition when the application can be terminated. */        public static final ExitApplicationCondition CONDITION = new ExitApplicationCondition();        public boolean condition(Object argument) {            if (TasksManager.isSomeTaskRunningOrWaitingToStart()) return false;            return true;        }    }    /**     * The action for exiting the application.     * Singleton class with one instance ACTION.     */    public static class ExitApplicationAction implements Callback {        private ExitApplicationAction() {};        /** The action that exits application. */        public static final ExitApplicationAction ACTION  = new ExitApplicationAction();        public void callback(Object called, Object message) {            MujMail.mujmail.destroyApp(false);        }    }    /**     * The condition for starting new task. The number of started task must be     * less then {@link TasksManager#MAXIMUM_NUMBER_OF_RUNNING_TASKS}.     */    public static class StartNewTaskCondition implements Condition {        private final BackgroundTask taskToStart;        //private boolean conditionalActionRunnerUIWasShown = false;        public StartNewTaskCondition(BackgroundTask taskToStart) {            this.taskToStart = taskToStart;        }        public synchronized boolean condition(Object argument) {                        ConditionArgument condArgument = (ConditionArgument) argument;            if (condArgument.conditionCheckingReason == ReasonsForCheckingCondition.STARTED) {                return false;            }            if (testCondition()) {                // TODO: not needed anymore because this funcitonality is done                // by ConditionalActionRunner and ConditionalActionRunnerUI.                //if (conditionalActionRunnerUIWasShown) {                    //cancelDisplayingConditionalActionRunnerUI();                //}                return true;            } else {                //conditionalActionRunnerUIWasShown = true;                return false;            }        }        private boolean testCondition() {            Enumeration tasks = TasksManager.getRunningTasks().elements();            int numberOfTasksOfTheSameClass = 0;            while (tasks.hasMoreElements()) {                BackgroundTask task = (BackgroundTask) tasks.nextElement();                if (DEBUG) System.out.println(task.getClass());                if (DEBUG) System.out.println(taskToStart.getClass());                if (task.getClass() == taskToStart.getClass()) {                    numberOfTasksOfTheSameClass++;                    if (numberOfTasksOfTheSameClass >= TasksManager.MAXIMUM_NUMBER_OF_RUNNING_TASKS) {                        return false;                    }                }            }                        return true;        }        //private void cancelDisplayingConditionalActionRunnerUI() {            //taskToStart.conditionalActionRunnerUI.cancelDisplaying();        //}    }    /**     * The action for starting new tasks the application.     */    public static class StartNewTaskAction implements Callback {        private final BackgroundTask taskToStart;        public StartNewTaskAction(BackgroundTask taskToStart) {            this.taskToStart = taskToStart;        }        public void callback(Object called, Object message) {            taskToStart.immediatelyStart();        }    }    /**     * Used to start tasks. Contains all tasks that are actually waiting to     * start.     */    public static class ConditionalTaskRunner extends ConditionalActionRunner {        private BackgroundTask task;        private static Vector waitingTasks = new Vector();        public ConditionalTaskRunner(BackgroundTask task) {            super(new StartNewTaskCondition(task),                new StartNewTaskAction(task));            this.task = task;        }        /**         * Gets tasks that are waiting to start.         * @return tasks that are waiting to start.         */        public static Vector getWaitingTasks() {            return waitingTasks;        }        protected void registerObservers() {             waitingTasks.addElement(task);            super.registerObservers();        }        protected void unregisterObservers() {            waitingTasks.removeElement(task);            super.unregisterObservers();        }        /**         * Gets the number of tasks waiting to start.         * @return the number of tasks waiting to start.         */        public static int getNumberOfTasksWaitingForStart() {            return waitingTasks.size();        }    }        public static class SampleTestTask extends StoppableBackgroundTask {        public SampleTestTask() {            super("Sample task");        }        public void doWork() {            while (true) {                System.out.println("Do work");                if (stopped()) {                    System.out.println("Task was stopped.");                    break;                }                Functions.sleep(500);            }            System.out.println("After while.");        }    }    public static class SampleTestTask2 extends StoppableBackgroundTask {        public SampleTestTask2() {            super("Sample task 2");        }        public void doWork() {            while (true) {                System.out.println("Do work 2");                if (stopped()) {                    System.out.println("Task was stopped. 2");                    break;                }                Functions.sleep(500);            }            System.out.println("After while. 2");        }    }    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -