Android Open Source - task4java Task






From Project

Back to project page task4java.

License

The source code is released under:

Apache License

If you think the Android project task4java listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 *  Copyright (c) 2014 Andree Hagelstein, Maik Schulze, Deutsche Telekom AG. All Rights Reserved.
 *  /*w w w .  ja  v  a 2s .  c  o  m*/
 *  Filename: Task.java
 */
package com.task4java.util.concurrent;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.FutureTask;

import com.task4java.StringUtils;

/**
 * <p> The {@code Task} extends the {@link FutureTask} with new methods (see {@code continueWith}) to support
 * the composition of asynchronous operations. Therefor the {@code Task} can be used to wrap
 * a {@link Callable} and executes a callback function ({@link CallableTask}) if 
 * the {@code Task} is done.
 *
 * @param <V> The result type returned by this Task's {@code get} methods.
 */
public class Task<V> extends FutureTask<V> implements ITask, ITaskStart
{
    
    /** The _new task list. */
    private final ArrayList<ITaskStart> _newTaskList = new ArrayList<ITaskStart>();
    
    /** The _executor. */
    private Executor _executor;
    
    /** The _id. */
    private String _id;
    
    /** The boolean is result read. */
    private boolean _blnIsResultRead = false;
    
    /** The boolean is done. */
    private boolean _blnIsDone = false;
    
    /** The boolean is started. */
    private boolean _blnIsStarted = false;

    
    /**
     * Creates a {@code Task} that will, upon starting, execute the given {@code Callable}. 
     *
     * @param callable the callable task
     */
    public Task(Callable<V> callable)
    {
        this(callable, "");
    }
    
    /**
     * Creates a {@code Task} that will, upon starting, execute the given {@code Callable}.
     *
     * @param callable the callable task
     * @param id the id
     */
    public Task(Callable<V> callable, String id)
    {
        this(callable, TaskFactory.defaultExecutorService, id);
    }

    /**
     * Creates a {@code Task} that will, upon starting, execute the given {@code Callable}.
     *
     * @param callable the callable task
     * @param executor the executor to use for the execution of the task
     */
    public Task(Callable<V> callable, Executor executor)
    {
        this(callable, executor, "");
    }
    
    /**
     * Creates a {@code Task} that will, upon starting, execute the given {@code Callable}.
     *
     * @param callable the callable task
     * @param executor the executor to use for the execution of the task
     * @param id the id
     */
    public Task(Callable<V> callable, Executor executor, String id)
    {
        super(callable);

        _executor = executor;
        _id = id;

        if (_executor == null)
        {
            throw new IllegalArgumentException("The executor argument cannot be null.");
        }
    }

    /**
     * Finds the specified exception class within the stack trace of the given exception.
     *
     * @param <T> the generic type
     * @param ex the given exception 
     * @param target the exception class to look for
     * @return the first match of the target class
     */
    @SuppressWarnings("unchecked")
    public static <T> T findException(Exception ex, Class<T> target)
    {
        Throwable currentEx = ex;

        for (int i = 0; i < 100; i++)
        {
            if (currentEx == null)
            {
                break;
            }

            if (target.isAssignableFrom(currentEx.getClass()))
            {
                return (T) currentEx;
            }

            currentEx = currentEx.getCause();
        }

        return null;
    }
    
    /**
     * Finds the first exception whose type not equals the specified exception class.
     *
     * @param <T> the generic type
     * @param ex the given exception 
     * @param target the exception class to compare
     * @return the first match of an exception whose type not equals target.
     */
    @SuppressWarnings("unchecked")
    public static <T> T findExceptionExcept(Exception ex, Class<T> target)
    {
        Throwable currentEx = ex;

        for (int i = 0; i < 100; i++)
        {
            if (currentEx == null)
            {
                break;
            }

            if (! target.isAssignableFrom(currentEx.getClass()))
            {
                return (T) currentEx;
            }

            currentEx = currentEx.getCause();
        }

        return null;
    }

    /**
     * Creates a {@code Task} from the specified {@link TaskCompletionSource}.
     *
     * @param <V> The result type returned by the Task's {@code get} methods.
     * @param source the source to create the task from
     * @return the task
     */
    public static <V> Task<V> fromSource(final TaskCompletionSource<V> source)
    {
        final Task<V> task = new Task<V>(new Callable<V>()
        {
            @Override
            public V call() throws Exception
            {
                return null;
            }
        });

        source.setSetCallback(new CallableValue<Void, V>() {
            @Override
            public Void call(V value) {

                task.set(value);

                return null;
            }
        });

        source.setExceptionCallback(new CallableValue<Void, Throwable>() {
            @Override
            public Void call(Throwable value) {

                task.setException(value);

                return null;
            }
        });

        return task;
    }

    /**
     * Creates a {@code Task} from the specified data.
     *
     * @param <V> The result type returned by the Task's {@code get} methods.
     * @param data the data
     * @return the task
     */
    public static <V> Task<V> fromResult(final V data)
    {
        return fromResult(data, "");
    }
    
    /**
     * Creates a {@code Task} from the specified data.
     *
     * @param <V> The result type returned by the Task's {@code get} methods.
     * @param data the data
     * @param id the id
     * @return the task
     */
    public static <V> Task<V> fromResult(final V data, String id)
    {
        Task<V> task = new Task<V>(new Callable<V>()
        {
            @Override
            public V call() throws Exception
            {
                return data;
            }
        }, id);

        task.set(data);

        return task;
    }
    
    /**
     * Creates a {@code Task} from the specified {@link Throwable}.
     *
     * @param <V> The result type returned by the Task's {@code get} methods.
     * @param t the t
     * @return the task
     */
    public static <V> Task<V> fromException(final Throwable t)
    {
        return fromException(t, "");
    }
    
    /**
     * Creates a {@code Task} from the specified {@link Throwable}.
     *
     * @param <V> The result type returned by the Task's {@code get} methods.
     * @param t the t
     * @param id the id
     * @return the task
     */
    public static <V> Task<V> fromException(final Throwable t, String id)
    {
        Task<V> task = new Task<V>(new Callable<V>()
        {
            @Override
            public V call() throws Exception
            {
                return null;
            }
        }, id);

        task.setException(t);

        return task;
    }

    /**
     * Waits for the completion of all specified tasks.
     *
     * @param <VResult> the generic type
     * @param tasks the tasks to wait for
     * @return the task
     */
    public static <VResult> Task<List<Task<VResult>>> whenAll(final Task<VResult> ... tasks)
    {
        List<Task<VResult>> list = new ArrayList<Task<VResult>>();
        
        if (tasks != null)
        {
            for (Task<VResult> task: tasks)
            {
                list.add(task);
            }
        }
        
        return whenAll(list);
    }
    
    /**
     * Waits for the completion of all specified tasks.
     *
     * @param <VResult> the generic type
     * @param tasks the tasks to wait for
     * @return the task
     */
    public static <VResult> Task<List<Task<VResult>>> whenAll(final List<Task<VResult>> tasks)
    {       
        if (tasks == null || tasks.size() == 0)
        {
          List<Task<VResult>> emptyList = new ArrayList<Task<VResult>>();
            return Task.fromResult(emptyList);
        }
        
        Task<VResult> task = tasks.get(0);

        for (int i = 1; i < tasks.size(); i++)
        {
            final int finalI = i;
            
            task = task.continueWith(new CallableTask<Task<VResult>, VResult>()
            {
                @Override
                public Task<VResult> call(Task<VResult> task) throws Exception
                {
                    task.markAsReaded();
                    
                    return tasks.get(finalI);
                }
            }).unwrap();
        }
        
        return task.continueWith(new CallableTask<List<Task<VResult>>, VResult>() {
            @Override
            public List<Task<VResult>> call(Task<VResult> task) throws Exception {
                
                task.markAsReaded();
                
                return tasks;
            }
        });
    }

    /**
     * Waits for the completion of any task.
     *
     * @param <VResult> the generic type
     * @param tasks the tasks to wait for
     * @return the task
     */
    public static <VResult> Task<VResult> whenAny(final Task<VResult> ... tasks)
    {
        List<Task<VResult>> list = new ArrayList<Task<VResult>>();

        if (tasks != null)
        {
            for (Task<VResult> task: tasks)
            {
                list.add(task);
            }
        }

        return whenAny(list);
    }

    /**
     * Waits for the completion of any task.
     *
     * @param <VResult> the generic type
     * @param tasks the tasks to wait for
     * @return the task
     */
    public static <VResult> Task<VResult> whenAny(final List<Task<VResult>> tasks)
    {
        if (tasks == null || tasks.size() == 0)
        {
            return Task.fromResult(null);
        }

        final Task<VResult> taskResult = new Task<VResult>(new Callable<VResult>()
            {
                @Override
                public VResult call() throws Exception
                {
                    return null;
                }
            });

        for (Task<VResult> task: tasks)
        {
            task.continueWith(new CallableTask<VResult, VResult>() {
                @Override
                public VResult call(Task<VResult> task) throws Exception {

                  synchronized (taskResult) {
                  
                      try
                      {
                          if (!taskResult.isDone())
                          {
                              taskResult._id = task._id;
                              taskResult.set(task.get());
                          }
                      }
                      catch (Throwable e)
                      {
                          taskResult.setException(e);
                      }
                  }

                    return task.get();
                }
            });
        }

        return taskResult;
    }

    /* (non-Javadoc)
     * @see de.telekom.util.concurrent.ITaskStart#start()
     */
    @Override
    public void start()
    {
        if (_blnIsStarted)
        {
            if (TaskFactory.unhandledExceptions != null)
            {
              TaskException ex = new TaskStartException("The task has already been started.", this);
              
                TaskFactory.unhandledExceptions.call(ex);
            }
        }
        
        _blnIsStarted = true;
        
        _executor.execute(this);
    }
    
    /* (non-Javadoc)
     * @see java.util.concurrent.FutureTask#run()
     */
    @Override
    public void run()
    {
        _blnIsStarted = true;
        
        super.run();
    }
    
    /* (non-Javadoc)
     * @see java.util.concurrent.FutureTask#get()
     */
    @Override
    public V get() throws InterruptedException, ExecutionException
    {
        _blnIsResultRead = true;
        
        return super.get();
    }
    
    /**
     * Gets the raw result from this {@code Task} if this {@code Task} has finished
     * or null if there is no result.
     *
     * @return the raw
     */
    public V getRaw()
    {
      
      if (this.isDone())
      {
        try {
        return this.get();
      } 
        catch (Exception e)
      {
      }
      }
    
      return null;
    }

    /**
     * Unwraps this {@code Task} if the result type is a {@code Task<Task<V>>}.
     *
     * @return the {@code Task<V>}
     */
    public V unwrap()
    {

        return this.continueWithInternal(new CallableTask<V, Task<V>>() {
            @Override
            public V call(Task<Task<V>> task) throws ExecutionException, InterruptedException {
                return task.get().get();
            }
        });
    }
    
    /**
     * Unwraps this {@code Task} if the result type is a {@code Task<Task<V>>}.
     *
     * @param executor the executor
     * @return the {@code Task<V>}
     */
    public V unwrap(Executor executor)
    {

        return this.continueWithInternal(new CallableTask<V, Task<V>>()
        {
            @Override
            public V call(Task<Task<V>> task) throws ExecutionException, InterruptedException
            {
                return task.get().get();
            }
        }, executor);
    }
    
    /**
     * To void.
     *
     * @return the task
     */
    public Task<Void> toVoid()
    {
      return this.continueWith(new CallableTask<Void, V>(){

      @Override
      public Void call(Task<V> task) throws Exception {
        task.get();
        return null;
      }});
    }
    
    /**
     * To null.
     *
     * @param <VNew> the generic type
     * @return the task
     */
    public <VNew> Task<VNew> toNull()
    {
      return this.continueWith(new CallableTask<VNew, V>(){

      @Override
      public VNew call(Task<V> task) throws Exception {
        
        task.get();
        
                return null;
            }});
    }
    
    /**
     * To object.
     *
     * @return the task
     */
    public Task<Object> toObject()
    {
        return this.continueWith(new CallableTask<Object, V>(){

            @Override
            public Object call(Task<V> task) throws Exception {
                return task.get();
            }});
    }
    
    /**
     * To type.
     *
     * @param <VNew> the generic type
     * @return the task
     */
    public <VNew> Task<VNew> toType()
    {
        return this.continueWith(new CallableTask<VNew, V>(){

            @SuppressWarnings("unchecked")
      @Override
            public VNew call(Task<V> task) throws Exception {
                return (VNew) task.get();
            }});
    }
    
    /**
     * To callable task.
     *
     * @return the callable task
     */
    public CallableTask<Task<V>, Void> toCallableTask()
    {
        return new CallableTask<Task<V>, Void>()
        {
            @Override
            public Task<V> call(Task<Void> task) throws Exception
            {
                task.get();
                
                return Task.this;
            }
        };
    }

    /**
     * Continue with.
     *
     * @param <VNew> the generic type
     * @param task the task
     * @return the task
     */
    private <VNew> Task<VNew> continueWith(Task<VNew> task)
    {
        boolean blnIsDone;

        synchronized (_newTaskList)
        {
            blnIsDone = _blnIsDone;

            if (!blnIsDone)
            {
                _newTaskList.add(task);
            }
        }

        if (blnIsDone)
        {
            task.start();
        }

        return task;
    }

    /**
     * Defines a {@link CallableTask} for continuation after this {@code Task} has finished.
     *
     * @param <VNew> the generic type
     * @param callableTask the callable task for continuation
     * @return the task
     */
    public <VNew> Task<VNew> continueWith(CallableTask<VNew, V> callableTask)
    {

        Task<VNew> newTask = new Task<VNew>(createCallable(this, callableTask), this._id);

        return continueWith(newTask);
    }

    /**
     * Defines a {@link CallableTask} for continuation after this {@code Task} has finished.
     *
     * @param <VNew> the generic type
     * @param callableTask the callable task for continuation
     * @param executor the executor
     * @return the task
     */
    public <VNew> Task<VNew> continueWith(CallableTask<VNew, V> callableTask, Executor executor)
    {

        Task<VNew> newTask = new Task<VNew>(createCallable(this, callableTask), executor, this._id);

        return continueWith(newTask);
    }
   
    /**
     * Mark as readed.
     */
    private void markAsReaded()
    {
        try
        {
            this.get();
        }
        catch (Exception e)
        {
        }
    }
    
    /**
     * Continue with internal.
     *
     * @param callableTask the callable task
     * @return the v
     */
    @SuppressWarnings("unchecked")
    private V continueWithInternal(CallableTask<V, Task<V>> callableTask)
    {
        Task<V> newTask = new Task<V>(createCallable((Task<Task<V>>) this, callableTask), this._id);

        return (V) continueWith(newTask);
    }

    /**
     * Continue with internal.
     *
     * @param callableTask the callable task
     * @param executor the executor
     * @return the v
     */
    @SuppressWarnings("unchecked")
    private V continueWithInternal(CallableTask<V, Task<V>> callableTask, Executor executor)
    {
        Task<V> newTask = new Task<V>(createCallable((Task<Task<V>>) this, callableTask), executor, this._id);

        return (V) continueWith(newTask);
    }

    /**
     * Creates the callable.
     *
     * @param <VNew> the generic type
     * @param <V> the value type
     * @param task the task
     * @param callableTask the callable task
     * @return the callable
     */
    private static <VNew, V> Callable<VNew> createCallable(final Task<V> task, final CallableTask<VNew, V> callableTask)
    {
        return new Callable<VNew>()
        {
            public VNew call() throws Exception
            {
                VNew result = callableTask.call(task);
                
                if (! task._blnIsResultRead)
                {
                    if (TaskFactory.unhandledExceptions != null)
                    {
                      TaskException ex = new TaskResultException("The task result has not been read within the ContinueWith method.", task);
                      
                        TaskFactory.unhandledExceptions.call(ex);
                    }
                }
                
                return result;
            }
        };
    }

    /**
     * Checks if is faulted.
     *
     * @return true, if is faulted
     */
    public boolean isFaulted()
    {
      boolean isFaulted = false;
      
        if (isDone())
        {
            try
            {
                this.get();
            }
            catch (Exception e)
            {
                isFaulted = true;
            } 
        }
        
        return isFaulted;
    }
    
    /* (non-Javadoc)
     * @see java.util.concurrent.FutureTask#done()
     */
    @Override
    protected void done()
    {
        super.done();

        synchronized (_newTaskList)
        {
            _blnIsDone = true;

            for (ITaskStart task : _newTaskList)
            {
                task.start();
            }

            _newTaskList.clear();
        }
    }
    
    /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString()
    {
        String id = this._id;
        
        if (StringUtils.IsNullOrEmpty(this._id))
        {
            id = "<undefined>";
        }
        
        StringBuilder stb = new StringBuilder();
        
        if (isFaulted())
        {
            try
            {
                this.get();        
            }
            catch(Exception e)
            {
                stb.append("Task {status: is faulted, id: ");
                stb.append(id);
                stb.append(", exception: ");
                stb.append(e.toString()); 
                stb.append("}");
            }
        }
        else if (isDone())
        {
            try
            {
                stb.append("Task {status: is done, id: ");
                stb.append(id);
                stb.append(", value: ");
                stb.append(this.get().toString()); 
                stb.append("}");
            }
            catch(Exception e)
            {
            }
        }
        else if (isCancelled())
        {
            stb.append("Task {status: is cancelled, id: ");
            stb.append(id);
            stb.append("}");
        }
        else
        {
            stb.append("Task {status: is running, id: ");
            stb.append(id);
            stb.append("}");
        }
        
        return stb.toString();
    }
}




Java Source Code List

com.task4java.IndexedList.java
com.task4java.KeyValuePair.java
com.task4java.Stopwatch.java
com.task4java.StringUtils.java
com.task4java.Tuple.java
com.task4java.android.activity.ActivityUtils.java
com.task4java.android.activity.BaseActivity.java
com.task4java.android.annotation.Annotations.java
com.task4java.android.examples.App.java
com.task4java.android.examples.activity.AboutActivity.java
com.task4java.android.examples.activity.ExpandableListAdapter.java
com.task4java.android.examples.activity.MainActivity.java
com.task4java.android.examples.activity.WelcomeActivity.java
com.task4java.android.examples.backend.AndroidServiceClient.java
com.task4java.android.util.concurrent.ActivityExecutor.java
com.task4java.android.util.concurrent.HandlerExecutor.java
com.task4java.data.backend.IServiceClient.java
com.task4java.data.backend.ServiceClient.java
com.task4java.data.backend.model.MainMenuAnnotation.java
com.task4java.data.frontend.ApplicationClient.java
com.task4java.data.frontend.model.MainMenuItemGroupList.java
com.task4java.data.frontend.model.MainMenuItemGroup.java
com.task4java.data.frontend.model.MainMenuItem.java
com.task4java.http.HttpHeaders.java
com.task4java.http.HttpMimeTypes.java
com.task4java.http.HttpRequestMethods.java
com.task4java.http.HttpStatusCodes.java
com.task4java.http.client.HttpContent.java
com.task4java.http.client.HttpStringContent.java
com.task4java.http.client.IImageClient.java
com.task4java.http.client.IRestClient.java
com.task4java.http.client.ImageClientGingerbread.java
com.task4java.http.client.ImageClient.java
com.task4java.http.client.ImageResponse.java
com.task4java.http.client.RestClientGingerbread.java
com.task4java.http.client.RestClient.java
com.task4java.http.client.RestResponse.java
com.task4java.lang.reflect.ReflectionCache.java
com.task4java.net.URLBuilder.java
com.task4java.util.concurrent.CallableTask.java
com.task4java.util.concurrent.CallableValue2.java
com.task4java.util.concurrent.CallableValue.java
com.task4java.util.concurrent.ITaskStart.java
com.task4java.util.concurrent.ITask.java
com.task4java.util.concurrent.TaskCompletionSource.java
com.task4java.util.concurrent.TaskContinuationOptions.java
com.task4java.util.concurrent.TaskException.java
com.task4java.util.concurrent.TaskFactory.java
com.task4java.util.concurrent.TaskResultException.java
com.task4java.util.concurrent.TaskStartException.java
com.task4java.util.concurrent.Task.java
com.task4java.util.log.ConsoleLogger.java
com.task4java.util.log.ILog.java
com.task4java.util.log.Logger.java