Package org.apache.geronimo.concurrent.executor

Source Code of org.apache.geronimo.concurrent.executor.ManagedFutureTask

/**
*  Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You under the Apache License, Version 2.0
*  (the "License"); you may not use this file except in compliance with
*  the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package org.apache.geronimo.concurrent.executor;

import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.geronimo.concurrent.ManagedContext;
import org.apache.geronimo.concurrent.ManagedTask;
import org.apache.geronimo.concurrent.ManagedTaskListenerSupport;
import org.apache.geronimo.concurrent.ManagedTaskUtils;
import org.apache.geronimo.concurrent.harmony.FutureTask;
import org.apache.geronimo.concurrent.thread.ManagedThread;

public class ManagedFutureTask<V> extends FutureTask<V> implements ManagedTask {

    protected final static Log LOG = LogFactory.getLog(ManagedFutureTask.class);
   
    protected ManagedContext managedContext;
    protected ManagedTaskListenerSupport listenerSupport;
   
    private Object task;
    private boolean associateTaskWithThread;
    protected boolean setContextOnRun = true;
       
    public ManagedFutureTask(Callable<V> callable,
                             ManagedContext managedContext,
                             ManagedTaskListenerSupport listener) {                            
        super(callable);
        this.task = callable;
        this.managedContext = managedContext;
        this.listenerSupport = listener;
        // always associate the task with the thread
        this.associateTaskWithThread = true;
        init();
    }
   
    public ManagedFutureTask(Runnable runnable, V result,
                             ManagedContext managedContext,
                             ManagedTaskListenerSupport listener) {                            
        super(runnable, result);
        this.task = runnable;
        this.managedContext = managedContext;
        this.listenerSupport = listener;
        // if the runnable is ManagedFutureTask, do not associate it with the thread
        // in this instance since the runnable will already do that
        this.associateTaskWithThread = !(runnable instanceof ManagedFutureTask);
        init();
    }
   
    private void init() {
        if (this.listenerSupport != null && this.managedContext == null) {
            throw new IllegalArgumentException("ManagedContext must be non-null if listener is specifed");
        }
    }
   
    boolean isSetContextOnRun() {
        return this.setContextOnRun;
    }

    /**
     * Sets if the context should be applied when the {@link #run() method is executed.
     * By default and in the server-managed executors the context is applied.
     * In component-managed executors the context is not applied as the right context is
     * already set by the thread.
     */
    void setSetContextOnRun(boolean setContextOnRun) {
        this.setContextOnRun = setContextOnRun;
    }

    public ManagedTaskListenerSupport getManagedTaskListenerSupport() {
        return this.listenerSupport;
    }
   
    public ManagedContext getManagedContext() {
        return this.managedContext;
    }
   
    @Override
    public boolean cancel(boolean mayInterruptIfRunning) {       
        boolean result = super.cancel(mayInterruptIfRunning);
        if (result && this.listenerSupport != null) {
            // always set the context
            Map<String, Object> threadContext = this.managedContext.set();
            try {
                this.listenerSupport.taskAborted(this, new CancellationException());
            } finally {
                this.managedContext.unset(threadContext);
            }
        }
        return result;       
    }

    @Override
    public void run() {
        if (this.setContextOnRun && this.managedContext != null) {
            Map<String, Object> threadContext = null;
            try {
                threadContext = this.managedContext.set();
            } catch (RuntimeException e) {
                LOG.warn("Failed to apply context to thread for task " + this + ": " +
                         e.getMessage() + ". Cancelling task");       
                cancelFutureTask(false);
                return;
            }
            try {
                super.run();
            } finally {
                this.managedContext.unset(threadContext);
            }
        } else {
            super.run();
        }
    }
   
    protected boolean cancelFutureTask(boolean mayInterruptIfRunning) {
        return super.cancel(mayInterruptIfRunning);
    }
   
    @Override
    protected void taskStart() {
        if (this.listenerSupport != null) {
            this.listenerSupport.taskStarting(this);
        }
       
        if (this.associateTaskWithThread) {
            // associate task with the thread
            Thread thread = Thread.currentThread();
            if (thread instanceof ManagedThread) {
                ManagedThread managedThread = (ManagedThread)thread;
                managedThread.startTask(this);
            } else {
                LOG.warn("taskStart was not called on ManagedThread: " + thread);
            }
        }
    }
   
    @Override
    protected void taskDone(Throwable exception) {
        if (this.listenerSupport != null) {
            this.listenerSupport.taskDone(this, exception);
        }
       
        if (this.associateTaskWithThread) {
            // de-associate task with the thread
            Thread thread = Thread.currentThread();
            if (thread instanceof ManagedThread) {
                ManagedThread managedThread = (ManagedThread)thread;
                managedThread.endTask();
            }
        }
    }

    public boolean cancel() {
        return cancel(true);
    }

    public String getIdentityDescription(String locale) {
        return ManagedTaskUtils.getTaskDescription(this.task, locale);
    }

    public String getIdentityName() {
        return ManagedTaskUtils.getTaskName(this.task);
    }
   
}
TOP

Related Classes of org.apache.geronimo.concurrent.executor.ManagedFutureTask

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.