
com.github.sviperll.tasks.Task Maven / Gradle / Ivy
Show all versions of chicory-task Show documentation
/*
* Copyright (c) 2014, Victor Nazarov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the Victor Nazarov nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.github.sviperll.tasks;
import com.github.sviperll.ResourceProviderDefinition;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
/**
* Wrapper that adds convinience methods to any task
*/
public class Task implements TaskDefinition {
private static final Task DO_NOTHING_TASK = new Task(new DoNothingTask());
/**
* @return new task that does nothing
*/
public static Task doNothing() {
return DO_NOTHING_TASK;
}
/**
* Creates task from Runnable object
*
* When TaskDefinition#run method of created task is called Runnable#run method is called in response
*
* TaskDefinition#close and TaskDefinition#stop methods of created task does nothong
*
* @param runnable runnable to base task on
* @return new task
*/
public static Task runnable(Runnable runnable) {
return new Task(new RunnableTask(runnable));
}
/**
* @param tasks array of subtasks
* @return new task that performs each of it's subtasks in order
*/
public static Task sequence(TaskDefinition... tasks) {
return new Task(new SequenceTask(tasks));
}
/**
* @param tasks list of subtasks
* @return new task that performs each of it's subtasks in order
*/
public static Task sequence(List extends TaskDefinition> tasks) {
TaskDefinition[] taskArray = tasks.toArray(new TaskDefinition[tasks.size()]);
return sequence(taskArray);
}
/**
* @param tasks array of subtasks
* @return new task that performs all it's subtasks in parallel
*/
public static Task parallel(TaskDefinition... tasks) {
return new Task(new ParallelTask(tasks));
}
/**
* @param tasks list of subtasks
* @return new task that performs all it's subtasks in parallel
*/
public static Task parallel(List extends TaskDefinition> tasks) {
TaskDefinition[] taskArray = tasks.toArray(new TaskDefinition[tasks.size()]);
return parallel(taskArray);
}
public static Task of(ResourceProviderDefinition extends TaskDefinition> source) {
return new Task(new SourceableResourceTask(source));
}
public static Task of(TaskDefinition task) {
if (task instanceof Task)
return (Task)task;
else
return new Task(task);
}
private final TaskDefinition task;
private final Object lock = new Object();
private Thread thread = null;
/**
*
* @param task task to inherit behaviour from
*/
private Task(TaskDefinition task) {
this.task = task;
}
public void start() {
synchronized (lock) {
if (thread == null) {
thread = new Thread(this.asRunnable());
thread.start();
}
}
}
/**
* @inheritDoc
*/
@Override
public void stop() {
task.stop();
}
public void join() throws InterruptedException {
Thread currentThread = null;
synchronized (lock) {
currentThread = thread;
}
if (currentThread != null)
currentThread.join();
}
/**
* @inheritDoc
*/
@Override
public void run() {
try {
task.run();
} finally {
synchronized (lock) {
thread = null;
}
}
}
/**
* @inheritDoc
*/
@Override
public void close() {
task.close();
}
/**
* Returns new task. When run new task calls #run method of this task
* repeatly with the pause passed as a parameter
*
* @param pause pause between invocations of this task's #run method
* @param unit TimeUnit to use for pause
* @return returns new task
*/
public Task repeat(long pause, TimeUnit unit) {
return new Task(new RepeatingTask(task, unit.toMillis(pause)));
}
/**
* Returns new task. When run new task calls #run method of this task
* repeatly without pauses
*
* @return returns new task
*/
public Task repeat() {
return repeat(0, TimeUnit.MILLISECONDS);
}
/**
* Returns new task.
* When methods of new task are called their invocations are logged by the logger passed as a parameter
*
* @param logger logger that is used to log method invocations
* @param name name of the task to use in log records
* @return returns new task
*/
public Task log(Logger logger, String name) {
return new Task(new LoggingTask(name, logger, task));
}
/**
* Returns new task.
* When methods of new task it calls according methods of this task
* When any exceptions are thrown by the invocation of this task's methods
* exceptions are not propogated, instead they are logged by given logger
* and suppressed
*
* @param logger logger that is used to log exceptions
* @return returns new task
*/
public Task swallowExceptions(Logger logger, long pause, TimeUnit unit) {
return new Task(new ExceptionSwallowingTask(task, logger, unit.toMillis(pause)));
}
/**
* Returns new task.
* When #run method is called, at first the #run method of this task is called
* and then the #run method of thatTask is called
*
* @param thatTask task to run after this task
* @return returns new task
*/
public Task andThen(TaskDefinition thatTask) {
return sequence(this.task, thatTask);
}
/**
* Returns new task.
* When #run method is called, at first the #run method of this task is called
* and then the #close method of this task is called
*
* Close method of resulting task does nothing
*
* @return returns new task
*/
public Task closeAfterEachRun() {
return new Task(new CloseOnEachRunTask(task));
}
/**
* Returns new task.
* New task is unstoppable, i. e. #stop method of resulting task does nothing
*
* @return returns new task
*/
public Task unstoppable() {
return new Task(new UnstoppableTask(task));
}
/**
* Returns new task.
* New task performs no cleanup, i. e. #close method of resulting task does nothing
*
* @return returns new task
*/
public Task withoutClose() {
return new Task(new WithoutCloseTask(task));
}
/**
* Returns new task.
* New task performs cleanup of this task as it's main work, i. e.
* when #run method of resulting task is called #close method of this task is called in response
*
* @return returns new task
*/
public Task closingTask() {
return new Task(new ClosingTask(task));
}
/**
* Returns new task.
* New task performs cleanup action in additinal to this task original cleanup, i. e.
* when #close method of resulting task is called #close method of this task is called in response
* and than closingAction passed as a parameter is called
*
* @param closingAction additinal closing action
* @return returns new task
*/
public Task withAdditinalClosingAction(Runnable closingAction) {
return new Task(new AdditionalClosingActionTask(task, closingAction));
}
public Runnable asRunnable() {
return new TaskRunnable(task);
}
}