You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by ga...@apache.org on 2008/03/07 20:56:28 UTC

svn commit: r634792 [9/9] - in /geronimo/sandbox/concurrent: ./ concurrent-deployer/ concurrent-deployer/src/ concurrent-deployer/src/main/ concurrent-deployer/src/main/plan/ concurrent/ concurrent/src/ concurrent/src/main/ concurrent/src/main/plan/ ge...

Added: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ContextService.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ContextService.java?rev=634792&view=auto
==============================================================================
--- geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ContextService.java (added)
+++ geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ContextService.java Fri Mar  7 11:56:14 2008
@@ -0,0 +1,277 @@
+/**
+ *  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 javax.util.concurrent;
+
+import java.util.Map;
+
+/**
+ * The ContextService provides methods for creating <i>contextual dynamic proxy</i>
+ * objects.
+ * <p>
+ *
+ * The proxy objects follow the same rules as defined for the
+ * {@link java.lang.reflect.Proxy} class with the following additions:
+ * <ul>
+ * <li>The proxy instance will retain the context of the application
+ * container's thread (creator's context).
+ * <li>The proxy instance will implement all of the interfaces specified on the
+ * <code>createContextObject</code> methods.
+ * <li>All interface method invocations on a proxy instance run in the
+ * creator's context.
+ * <li>Invocation of the <code>hashCode</code>, <code>equals</code>, and
+ * <code>toString</code> methods declared in <code>java.lang.Object</code>
+ * on a sproxy instance will not run in the creator's context.
+ * <li>The proxy instance must implement <code>java.io.Serializable</code>.
+ * <li>The proxied object instance must implement
+ * <code>java.io.Serializable</code> if the proxy instance is serialized.
+ * <li>Context properties can be stored with the proxy instance. Custom
+ * property keys must not begin with "ctxsvc.".
+ * <li>Context properties are to be used for controlling how various contextual
+ * information is retreived and applied to the thread. Although application
+ * components can store arbitrary property keys and values, it is not
+ * recommended. Java EE product providers may impose limits to the size of the
+ * keys and values.
+ * <li>Context property keys and values must all be of type
+ * <code>java.lang.String</code>. Use of the <code>put</code> and
+ * <code>putAll</code> methods on the <code>java.util.Hashtable</code>
+ * superclass are discouraged.
+ * </ul>
+ *
+ */
+public interface ContextService {
+    /**
+     * A contextual object property that disables the normal transaction
+     * suspension and UserTransaction access from the proxied methods.
+     * <p>
+     *
+     * If "false" (the default if unspecified), any transaction that is
+     * currently active on the thread will be suspended and a UserTransaction
+     * (accessible in the local JNDI namespace as "java:comp/UserTransaction")
+     * will be available. When the proxied method returns the original
+     * transaction is restored.
+     * <p>
+     *
+     * If "true", the proxied method will run within the transaction (if any) of
+     * the current thread. A UserTransaction will only be available if the the
+     * container thread (for example, a Servlet or Bean Managed Transaction
+     * EJB).
+     */
+    public String USE_PARENT_TRANSACTION = "ctxsvc.useparenttran";
+
+    /**
+     * Creates a new contextual object proxy for the input object instance.
+     * <p>
+     *
+     * Each method invocation will have the context of the application component
+     * instance that created the context object.
+     * <p>
+     *
+     * The contextual object is useful when developing or using Java SE
+     * threading mechanisms spraying events to other component instances or
+     * communicating with component instances on different Java processes.
+     * <p>
+     *
+     * If the application component that created the proxy is started or
+     * deployed, all methods on reflected interfaces will throw a
+     * <code>java.lang.IllegalState</code> exception.
+     * <p>
+     *
+     * For example, to call a normal Runnable with the correct context using a
+     * Java&trade; ExecutorService:
+     * <P>
+     *
+     * <pre>
+     * public class MyRunnable implements Runnable {
+     *     public void run() {
+     *         System.out.println(&quot;MyRunnable.run with J2EE Context available.&quot;);
+     *     }
+     * }
+     *
+     * InitialContext ctx = new InitialContext();
+     *
+     * ThreadFactory threadFactory = (ThreadFactory) ctx
+     *         .lookup(&quot;java:comp/env/concurrent/ThreadFactory&quot;);
+     *
+     * ContextService ctxService = (ContextService) ctx
+     *         .lookup(&quot;java:comp/env/concurrent/ContextService&quot;);
+     *
+     * Object rProxy = ctxService.createContextObject(myRunnableInstance,
+     *         new Class[] { Runnable.class });
+     *
+     * ExecutorService exSvc = Executors.newThreadPool(10, threadFactory);
+     *
+     * Future f = exSvc.submit((Runnable) rProxy);
+     * </pre>
+     *
+     * @param instance
+     *            the instance of the object to proxy.
+     * @param interfaces
+     *            the interfaces that the proxy should implement.
+     * @return a proxy for the input object that implements all of the specified
+     *         interfaces.
+     * @throws IllegalArgumentException
+     *             if the Class does not have an interface or there is not an
+     *             accessible default constructor.
+     */
+    public Object createContextObject(Object instance, Class<?>[] interfaces);
+
+    /**
+     * Creates a new contextual object proxy for the input object instance.
+     * <p>
+     *
+     * The contextual object is useful when developing or using Java SE
+     * threading mechanisms spraying events to other component instances or
+     * communicating with component instances on different Java processes.
+     * <p>
+     *
+     * If the application component that created the proxy is started or
+     * deployed, all methods on reflected interfaces will throw a
+     * <code>java.lang.IllegalState</code> exception.
+     * <p>
+     *
+     * This method accepts a {@link Properties} object which allows the
+     * contextual object creator to define what contexts or behaviors to capture
+     * when creating the contextual object. The specified properties will remain
+     * with the contextual object until the properties are updated or removed
+     * using the {@link #setProperties(Object, Properties)} method.
+     * <p>
+     *
+     * For example, to call a Message Driven Bean (MDB) with the sender's
+     * context, but within the MDB's transaction:
+     * <P>
+     *
+     * <pre>
+     *      public class MyServlet ... {
+     *        public void doPost() throws NamingException, JMSException {
+     *            InitialContext ctx = new InitialContext();
+     *
+     *            // Get the ContextService that only propagates
+     *            // security context.
+     *            ContextService ctxSvc = (ContextService)
+     *                ctx.lookup(&quot;java:comp/env/SecurityContext&quot;);
+     *
+     *            // Set any custom context data.
+     *            Properties ctxProps = new Properties();
+     *            ctxProps.setProperty(&quot;vendor_a.security.tokenexpiration&quot;, &quot;15000&quot;);
+     *
+     *            ProcessMessage msgProcessor =
+     *                (ProcessMessage) ctxSvc.createContextObject(new MessageProcessor(),
+     *                new Class[]{ProcessMessage.class},
+     *                ctxProps);
+     *
+     *            ConnectionFactory cf = (ConnectionFactory)
+     *                 ctx.lookup(&quot;java:comp/env/MyTopicConnectionFactory&quot;);
+     *            Destination dest = (Destination) ctx.lookup(&quot;java:comp/env/MyTopic&quot;);
+     *            Connection con = cf.createConnection();
+     *
+     *            Session session = con.createSession(true, Session.AUTO_ACKNOWLEDGE);
+     *            MessageProducer producer = session.createProducer(dest);
+     *
+     *            Message msg = session.createObjectMessage((Serializable)msgProcessor);
+     *            producer.send(dest, msg);
+     *            ...
+     *
+     *        }
+     *
+     *      public class MyMDB ... {
+     *        public void onMessage(Message msg) {
+     *            // Get the ProcessMessage context object from the message.
+     *            ObjectMessage omsg = (ObjectMessage)msg;
+     *            ProcessMessage msgProcessor = (ProcessMessage)omsg.getObject();
+     *
+     *            // Update the context object and verify that the processMessage()
+     *            // method runs inside the current transaction.  If we have a failure,
+     *            // we don't want to consume the message.
+     *            InitialContext ctx = new InitialContext();
+     *            ContextService ctxSvc = (ContextService)
+     *                ctx.lookup(&quot;java:comp/env/SecurityContext&quot;);
+     *            Properties ctxProps = ctxSvc.getProperties(msgProcessor);
+     *            ctxProps.setProperty(ContextService.USE_PARENT_TRANSACTION, &quot;true&quot;);
+     *            ctxSvc.setProperties(msgProcessor, ctxProps);
+     *
+     *            // Process the message in the specified context.
+     *            msgProcessor.processMessage(msg);
+     *        }
+     *      }
+     *
+     *      public interface  ProcessMessage {
+     *          public void processMessage(Message msg);
+     *      }
+     *
+     *      public class MessageProcessor implements ProcessMessage, Serializable {
+     *          public void processMessage(Message msg) {
+     *              // Process the message with the application container
+     *              // context that sent the message.
+     *
+     *          }
+     *      }
+     * </pre>
+     *
+     * @param instance
+     *            the instance of the object to proxy.
+     * @param interfaces
+     *            the interfaces that the proxy should implement.
+     * @param contextProperties
+     *            the properties to use when creating and running the context
+     *            object.
+     * @return a proxy for the input object that implements all of the specified
+     *         interfaces.
+     * @throws IllegalArgumentException
+     *             if the Class does not have an interface or there is not an
+     *             accessible default constructor.
+     * @throws ClassCastException
+     *             thrown if one of the keys or values in the specified
+     *             Properties object are not of type String.
+     */
+    public Object createContextObject(Object instance, Class<?>[] interfaces,
+            Map<String, String> contextProperties);
+
+    /**
+     * Sets the properties on the context proxy instance.
+     * <p>
+     *
+     * All property keys and values must be strings. Storing other class types
+     * may result in a <code>java.lang.ClassCastException</code>.
+     *
+     * @param contextObject
+     *            the contextual proxy instance to set the properties.
+     * @param contextProperties
+     *            the properties to use when running the context object. Specify
+     *            an empty Properties object to erase all current properties.
+     * @throws IllegalArgumentException
+     *             thrown if the input contextObject is not a valid contextual
+     *             object proxy created with the
+     *             <code>createContextObject</code> method.
+     * @throws ClassCastException
+     *             thrown if one of the keys or values in the specified
+     *             Properties object are not of type String.
+     */
+    public void setProperties(Object contextObject, Map<String, String> contextProperties);
+
+    /**
+     * Gets the current properties on the context proxy instance.
+     *
+     * @param contextObject
+     *            the contextual proxy instance to set the properties.
+     * @return the current context object properties
+     * @throws IllegalArgumentException
+     *             thrown if the input contextObject is not a valid contextual
+     *             object proxy created with the
+     *             <code>createContextObject</code> method.
+     */
+    public Map<String, String> getProperties(Object contextObject);
+}

Propchange: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ContextService.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ExecutorNotAvailableException.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ExecutorNotAvailableException.java?rev=634792&view=auto
==============================================================================
--- geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ExecutorNotAvailableException.java (added)
+++ geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ExecutorNotAvailableException.java Fri Mar  7 11:56:14 2008
@@ -0,0 +1,78 @@
+/**
+ *  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 javax.util.concurrent;
+
+import java.util.concurrent.ExecutionException;
+
+/**
+ * Exception indicating that the result of a value-producing task cannot be retrieved because the
+ * remote executor that the task is running on is no longer available.<p>
+ *
+ * Use the {@link java.lang.Throwable#getCause()} method to determine why the executor is no longer available.
+ */
+public class ExecutorNotAvailableException extends ExecutionException {
+
+    private static final long serialVersionUID = 4086046729432722254L;
+
+    /**
+     * Constructs an ExecutorNotAvailableException with <code>null</code> as its detail message.
+     * The cause is not initialized, and may subsequently be initialized by a call to
+     * {@link java.lang.Throwable#initCause(java.lang.Throwable)}.
+     */
+    public ExecutorNotAvailableException() {
+        super();
+    }
+
+    /**
+     * Constructs an ExecutorNotAvailableException exception with the specified detail message.<p>
+     *
+     * The cause is not initialized, and may subsequently be initialized by a call to
+     * {@link java.lang.Throwable#initCause(java.lang.Throwable)}.
+     *
+     * @param message the detail message (which is saved for later retrieval by the {@link java.lang.Throwable#getMessage()} method).
+     */
+    public ExecutorNotAvailableException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs an ExecutorNotAvailableException exception with the specified detail message and cause.<p>
+     *
+     * Note that the detail message associated with cause is not automatically incorporated in
+     * this exception's detail message.
+     *
+     * @param message the detail message (which is saved for later retrieval by the {@link java.lang.Throwable#getMessage()} method).
+     * @param cause the cause (which is saved for later retrieval by the {@link java.lang.Throwable#getCause()} method).
+     * (A null value is permitted, and indicates that the cause is nonexistent or unknown.)
+     */
+    public ExecutorNotAvailableException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Constructs an ExecutorNotAvailableException exception with the specified cause and a
+     * detail message of (cause==null ? null : cause.toString())
+     * (which typically contains the class and detail message of cause).
+     *
+     * @param cause the cause (which is saved for later retrieval by the {@link java.lang.Throwable#getCause()} method).
+     * (A null value is permitted, and indicates that the cause is nonexistent or unknown.)
+     */
+    public ExecutorNotAvailableException(Throwable cause) {
+        super(cause);
+    }
+
+}

Propchange: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ExecutorNotAvailableException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/Identifiable.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/Identifiable.java?rev=634792&view=auto
==============================================================================
--- geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/Identifiable.java (added)
+++ geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/Identifiable.java Fri Mar  7 11:56:14 2008
@@ -0,0 +1,45 @@
+/**
+ *  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 javax.util.concurrent;
+
+import java.util.Locale;
+
+/**
+ * A tasks submitted to an {@link javax.util.concurrent.ManagedExecutorService}
+ * can optionally implement this interface.<p>
+ *
+ * The intent of this interface is to allow management facilities to inspect the task to determine
+ * the intent of the task and its state.  Implementations should not depend upon any thread execution
+ * context and should typically return only readily-available instance data.
+ */
+public interface Identifiable {
+
+    /**
+     * The name or ID of the identifiable object.
+     * @return the name or ID of the identifiable object.
+     */
+    public String getIdentityName();
+
+    /**
+     * The description of the identifiable object translated for a given locale.
+     * @param locale the locale to use to generate the description.  If null, the default locale will be
+     * used.
+     * @return the description of the identifiable object  in the specified locale.
+     */
+    public String getIdentityDescription(Locale locale);
+
+}

Propchange: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/Identifiable.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedExecutorService.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedExecutorService.java?rev=634792&view=auto
==============================================================================
--- geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedExecutorService.java (added)
+++ geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedExecutorService.java Fri Mar  7 11:56:14 2008
@@ -0,0 +1,283 @@
+/**
+ *  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 javax.util.concurrent;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+
+
+/**
+ * A manageable version of a {@link java.util.concurrent.ExecutorService}.<p>
+ *
+ * A ManagedExecutorService provides methods for submitting tasks for execution
+ * in a managed environment.  Implementations of the ManagedExecutorService are
+ * provided by a Java&trade; EE Product Provider.  Application Component Providers
+ * use the Java Naming and Directory Interface&trade; (JNDI) to look-up instances of one
+ * or more ManagedExecutorService objects using resource environment references.<p>
+ *
+ * The Concurrency Utilities for Java&trade; EE specification describes several
+ * behaviors that a ManagedExecutorService can implement.  The Application
+ * Component Provider and Deployer identify these requirements and map the
+ * resource environment reference appropriately.<p>
+ *
+ * The most common uses for a ManagedExecutorService is to run short-duration asynchronous
+ * tasks in the local JVM from a container such as an Enterprise
+ * JavaBean&trade; (EJB&trade;) or servlet.  Use a managed ThreadFactory for long-running
+ * daemon tasks.<p>
+ *
+ * Tasks run within the application component context that either
+ * submitted the task or created the ManagedExecutorService instance (server-managed or component-managed).
+ * All tasks run without an explicit transaction (they do not enlist in the application
+ * component's transaction).  If a transaction is required, use a
+ * {@link javax.transaction.UserTransaction} instance.  A UserTransaction instance is
+ * available in JNDI using the name: &QUOT;java:comp/UserTransaction&QUOT<p>
+ *
+ * Example:<pre>
+ * public run() {
+ *     // Begin of task
+ *     InitialContext ctx = new InitialContext();
+ *     UserTransaction ut = (UserTransaction) ctx.lookup("java:comp/UserTransaction");
+ *     ut.begin();
+ *
+ *     // Perform transactional business logic
+ *
+ *     ut.commit();
+ * }</PRE>
+ *
+ * Asynchronous tasks are typically submitted to the ManagedExecutorService using one
+ * of the <code>submit</code> methods, each of which return a {@link java.util.concurrent.Future}
+ * instance.  The <code>Future</code> represents the result of the task and can also be used to
+ * check if the task is complete or wait for its completion.<p>
+ *
+ * If the task is cancelled, the result fo the task is a
+ * {@link java.util.concurrent.CancellationException} exception.  If the task is unable
+ * to run due to start due to a reason other than cancellation, the result is a
+ * {@link javax.util.concurrent.AbortedException} exception.<p>
+ *
+ * Example:<pre>
+ * &#47;**
+ *  * Retrieve all accounts from several account databases in parallel.
+ *  * Resource Mappings:
+ *  *  type:      javax.util.concurrent.ManagedExecutorService
+ *  *  jndi-name: mes/ThreadPool
+ *  *  attributes:
+ *  *    Run Location = Local
+ *  *&#47;
+ * public List<Account> getAccounts(long accountId) {
+ *     try {
+ *         javax.naming.InitialContext ctx = new InitialContext();
+ *         <b>ManagedExecutorService mes = (ManagedExecutorService)
+ *             ctx.lookup("java:comp/env/concurrent/ThreadPool");</b>
+ *
+ *         // Create a set of tasks to perform the account retrieval.
+ *         ArrayList<Callable<Account>> retrieverTasks = new ArrayList<Callable<Account>>();
+ *         retrieverTasks.add(new EISAccountRetriever());
+ *         retrieverTasks.add(new RDBAccountRetriever());
+ *
+ *         // Submit the tasks to the thread pool and wait for them
+ *         // to complete (successfully or otherwise).
+ *         <b>List<Future<Account>> taskResults= mes.invokeAll(retrieverTasks);</b>
+ *
+ *         // Retrieve the results from the resulting Future list.
+ *         ArrayList<Account> results = new ArrayList<Account>();
+ *         for(Future<Account> taskResult : taskResults) {
+ *             try {
+ *                 <b>results.add(taskResult.get());</b>
+ *             } catch (ExecutionException e) {
+ *                 Throwable cause = e.getCause();
+ *                 // Handle the AccountRetrieverError.
+ *             }
+ *         }
+ *
+ *         return results;
+ *
+ *     } catch (NamingException e) {
+ *         // Throw exception for fatal error.
+ *     } catch (InterruptedException e) {
+ *         // Throw exception for shutdown or other interrupt condition.
+ *     }
+ *   }
+ *
+ * }
+ *
+ * public class EISAccountRetriever implements Callable<Account> {
+ *     public Account call() {
+ *         // Connect to our eis system and retrieve the info for the account.
+ *         //...
+ *         return null;
+ *     }
+ * }
+ *
+ * public class RDBAccountRetriever implements Callable<Account> {
+ *     public Account call() {
+ *         // Connect to our database and retrieve the info for the account.
+ *         //...
+ *     }
+ * }
+ *
+ * public class Account {
+ *     // Some account data...
+ * }
+ *
+ *</pre>
+ */
+public interface ManagedExecutorService extends ExecutorService
+{
+    /**
+     * This method has the same semantics as {@link ExecutorService#submit(java.lang.Runnable)}
+     * but also includes the ability to be notified when the task's lifecycle changes.
+     *
+     * @param task the task to submit
+     * @param taskListener the ManagedTaskListener instance to receive a task's lifecycle events.
+     * @return a Future representing pending completion of the task,
+     * and whose <tt>get()</tt> method will return <tt>null</tt>
+     * upon completion.
+     * @throws RejectedExecutionException if task cannot be scheduled
+     * for execution
+     * @throws NullPointerException if task null
+     */
+    Future<?> submit(Runnable task, ManagedTaskListener taskListener);
+
+    /**
+     * This method has the same semantics as {@link ExecutorService#submit(java.lang.Runnable, T)}
+     * but also includes the ability to be notified when the task's lifecycle changes.
+     *
+     * @param task the task to submit
+     * @param taskListener the ManagedTaskListener instance to receive a task's lifecycle events.
+     * @param result the result to return
+     * @return a Future representing pending completion of the task,
+     * and whose <tt>get()</tt> method will return the given result
+     * upon completion.
+     * @throws RejectedExecutionException if task cannot be scheduled
+     * for execution
+     * @throws NullPointerException if task null
+     */
+    <T> Future<T> submit(Runnable task, T result, ManagedTaskListener taskListener);
+
+    /**
+     * This method has the same semantics as {@link ExecutorService#submit(java.util.concurrent.Callable)}
+     * but also includes the ability to be notified when the task's lifecycle changes.
+     *
+     * @param task the task to submit
+     * @param taskListener the ManagedTaskListener instance to receive a task's lifecycle events.
+     * @return a Future representing pending completion of the task
+     * @throws RejectedExecutionException if task cannot be scheduled
+     * for execution
+     * @throws NullPointerException if task null
+     */
+    <T> Future<T> submit(Callable<T> task, ManagedTaskListener taskListener);
+
+    /**
+     * This method has the same semantics as {@link ExecutorService#invokeAll(java.util.Collection)}
+     * but also includes the ability to be notified when each task's lifecycle changes.
+     *
+     * @param tasks the collection of tasks
+     * @param taskListener the ManagedTaskListener instance to receive a task's lifecycle events.
+     * @return A list of Futures representing the tasks, in the same
+     * sequential order as produced by the iterator for the given task
+     * list, each of which has completed.
+     * @throws InterruptedException if interrupted while waiting, in
+     * which case unfinished tasks are cancelled.
+     * @throws NullPointerException if tasks or any of its elements are <tt>null</tt>
+     * @throws RejectedExecutionException if any task cannot be scheduled
+     * for execution
+     */
+    <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks, ManagedTaskListener taskListener)
+        throws InterruptedException;
+
+    /**
+     * This method has the same semantics as
+     * {@link ExecutorService#invokeAll(java.util.Collection, long, java.util.concurrent.TimeUnit)}
+     * but also includes the ability to be notified when each task's lifecycle changes.
+     *
+     * @param tasks the collection of tasks
+     * @param timeout the maximum time to wait
+     * @param unit the time unit of the timeout argument
+     * @param taskListener the ManagedTaskListener instance to receive a task's lifecycle events.
+     * @return A list of Futures representing the tasks, in the same
+     * sequential order as produced by the iterator for the given
+     * task list. If the operation did not time out, each task will
+     * have completed. If it did time out, some of these tasks will
+     * not have completed.
+     * @throws InterruptedException if interrupted while waiting, in
+     * which case unfinished tasks are cancelled.
+     * @throws NullPointerException if tasks, any of its elements, or
+     * unit are <tt>null</tt>
+     * @throws RejectedExecutionException if any task cannot be scheduled
+     * for execution
+     */
+    <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks,
+                                    long timeout, TimeUnit unit, ManagedTaskListener taskListener)
+        throws InterruptedException;
+
+    /**
+     * This method has the same semantics as
+     * {@link ExecutorService#invokeAny(java.util.Collection)}
+     * but also includes the ability to be notified when each task's lifecycle changes.
+     *
+     * Executes the given tasks, returning the result
+     * of one that has completed successfully (i.e., without throwing
+     * an exception), if any do. Upon normal or exceptional return,
+     * tasks that have not completed are cancelled.
+     * The results of this method are undefined if the given
+     * collection is modified while this operation is in progress.
+     * @param tasks the collection of tasks
+     * @param taskListener the ManagedTaskListener instance to receive a task's lifecycle events.
+     * @return The result returned by one of the tasks.
+     * @throws InterruptedException if interrupted while waiting
+     * @throws NullPointerException if tasks or any of its elements
+     * are <tt>null</tt>
+     * @throws IllegalArgumentException if tasks empty
+     * @throws ExecutionException if no task successfully completes
+     * @throws RejectedExecutionException if tasks cannot be scheduled
+     * for execution
+     */
+    <T> T invokeAny(Collection<Callable<T>> tasks, ManagedTaskListener taskListener)
+        throws InterruptedException, ExecutionException;
+
+    /**
+     * This method has the same semantics as
+     * {@link ExecutorService#invokeAny(java.util.Collection, long, java.util.concurrent.TimeUnit)}
+     * but also includes the ability to be notified when each task's lifecycle changes.
+     *
+     * @param tasks the collection of tasks
+     * @param timeout the maximum time to wait
+     * @param unit the time unit of the timeout argument
+     * @return The result returned by one of the tasks.
+     * @throws InterruptedException if interrupted while waiting
+     * @throws NullPointerException if tasks, any of its elements, or
+     * unit are <tt>null</tt>
+     * @throws TimeoutException if the given timeout elapses before
+     * any task successfully completes
+     * @throws ExecutionException if no task successfully completes
+     * @throws RejectedExecutionException if tasks cannot be scheduled
+     * for execution
+     */
+    <T> T invokeAny(Collection<Callable<T>> tasks,
+                    long timeout, TimeUnit unit, ManagedTaskListener taskListener)
+        throws InterruptedException, ExecutionException, TimeoutException;
+
+
+}

Propchange: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedExecutorService.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedScheduledExecutorService.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedScheduledExecutorService.java?rev=634792&view=auto
==============================================================================
--- geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedScheduledExecutorService.java (added)
+++ geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedScheduledExecutorService.java Fri Mar  7 11:56:14 2008
@@ -0,0 +1,206 @@
+/**
+ *  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 javax.util.concurrent;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+
+
+/**
+ * A manageable version of a {@link java.util.concurrent.ScheduledExecutorService}.<p>
+ *
+ * A ManagedScheduledExecutorService provides methods for submitting delayed or
+ * periodic tasks for execution in a managed environment.
+ * Implementations of the ManagedScheduledExecutorService are
+ * provided by a Java&trade; EE Product Provider.  Application Component Providers
+ * use the Java Naming and Directory Interface&trade; (JNDI) to look-up instances of one
+ * or more ManagedExecutorService objects using resource environment references.<p>
+ *
+ * The Concurrency Utilities for Java&trade; EE specification describes several
+ * behaviors that a ManagedScheduledExecutorService can implement.  The Application
+ * Component Provider and Deployer identify these requirements and map the
+ * resource environment reference appropriately.<p>
+ *
+ * Tasks run within the application component context that either
+ * submitted the task or created the ManagedExecutorService instance (server-managed or component-managed).
+ * All tasks run without an explicit transaction (they do not enlist in the application
+ * component's transaction).  If a transaction is required, use a
+ * {@link javax.transaction.UserTransaction} instance.  A UserTransaction instance is
+ * available in JNDI using the name: &QUOT;java:comp/UserTransaction&QUOT<p>
+ *
+ * Example:<pre>
+ * public run() {
+ *     // Begin of task
+ *     InitialContext ctx = new InitialContext();
+ *     UserTransaction ut = (UserTransaction) ctx.lookup("java:comp/UserTransaction");
+ *     ut.begin();
+ *
+ *     // Perform transactional business logic
+ *
+ *     ut.commit();
+ * }</PRE>
+ *
+ * Asynchronous tasks are typically submitted to the ManagedScheduledExecutorService using one
+ * of the <code>submit</code> or <code>schedule</code>methods, each of which return a {@link java.util.concurrent.Future}
+ * instance.  The Future represents the result of the task and can also be used to
+ * check if the task is complete or wait for its completion.<p>
+ *
+ * If the task is cancelled, the result fo the task is a
+ * {@link java.util.concurrent.CancellationException} exception.  If the task is unable
+ * to run due to start due to a reason other than cancellation, the result is a
+ * {@link javax.util.concurrent.AbortedException} exception.  If the task is scheduled
+ * with a {@link javax.util.concurrent.Trigger} and the Trigger forces the task to be skipped,
+ * the result will be a {@link javax.util.concurrent.SkippedException} exception.<p>
+ *
+ * Tasks can be scheduled to run periodically using the <code>schedule</code> methods that
+ * take a <code>Trigger</code> as an argument and the <code>scheduleAtFixedRate</code> and
+ * <code>scheduleWithFixedDelay</code> methods.  The result of the <code>Future</code> will
+ * be represented by the currently scheduled or running instance of the task.  Future and past executions
+ * of the task are not represented by the Future.  The state of the <code>Future</code> will therefore change
+ * and multiple results are expected.<p>
+ *
+ * For example, if a task is repeat, the lifecycle of the task would be:<br>
+ * (Note:  See {@link javax.util.concurrent.ManagedTaskListener} for task lifecycle management details.)<p>
+ *
+ * <table>
+ * <tr><td valign="top"><strong>Sequence</strong></td><td valign="top"><strong>State</strong></td><td valign="top"><strong>Action</strong></td><td valign="top"><strong>Listener</strong></td><td valign="top"><strong>Next state</strong></td></tr>
+ * <tr><td valign="top">1A.</td><td valign="top">None</td><td valign="top">submit()</td><td valign="top">taskSubmitted</td><td valign="top">Submitted</td></tr>
+ * <tr><td valign="top">2A.</td><td valign="top">Submitted</td><td valign="top">About to call run()</td><td valign="top">taskStarting</td><td valign="top">Started</td></tr>
+ * <tr><td valign="top">3A.</td><td valign="top">Started</td><td valign="top">Exit run()</td><td valign="top">taskDone</td><td valign="top">Reschedule</td></tr>
+ * <tr><td valign="top">1B.</td><td valign="top">Reschedule</td><td valign="top"></td><td valign="top">taskSubmitted</td><td valign="top">Submitted</td></tr>
+ * <tr><td valign="top">2B.</td><td valign="top">Submitted</td><td valign="top">About to call run()</td><td valign="top">taskStarting</td><td valign="top">Started</td></tr>
+ * <tr><td valign="top">3B.</td><td valign="top">Started</td><td valign="top">Exit run()</td><td valign="top">taskDone</td><td valign="top">Reschedule</td></tr>
+ * </table>
+ *
+ *
+ *
+ */
+public interface ManagedScheduledExecutorService extends ScheduledExecutorService, ManagedExecutorService
+{
+    /**
+     * Creates and executes a task based on a Trigger.  The Trigger determines
+     * when the task should run and how often.
+     *
+     * @param command the task to execute.
+     * @param trigger the trigger that determines when the task should fire.
+     * @param taskListener the ManagedTaskListener instance to receive a task's lifecycle events.
+     * @return a Future representing pending completion of the task,
+     * and whose <tt>get()</tt> method will return <tt>null</tt>
+     * upon completion.
+     * @throws RejectedExecutionException if task cannot be scheduled
+     * for execution.
+     * @throws NullPointerException if command is null
+     */
+    public ScheduledFuture<?> schedule(Runnable command, Trigger trigger, ManagedTaskListener taskListener);
+
+    /**
+     * Creates and executes a task based on a Trigger.  The Trigger determines
+     * when the task should run and how often.
+     *
+     * @param callable the function to execute.
+     * @param trigger the trigger that determines when the task should fire.
+     * @param taskListener the ManagedTaskListener instance to receive a task's lifecycle events.
+     * @return a ScheduledFuture that can be used to extract result or cancel.
+     * @throws RejectedExecutionException if task cannot be scheduled
+     * for execution.
+     * @throws NullPointerException if callable is null
+     */
+    public <V> ScheduledFuture<V> schedule(Callable<V> callable, Trigger trigger, ManagedTaskListener taskListener);
+
+    /**
+     * Creates and executes a one-shot action that becomes enabled
+     * after the given delay.
+     * @param command the task to execute.
+     * @param delay the time from now to delay execution.
+     * @param unit the time unit of the delay parameter.
+     * @param taskListener the ManagedTaskListener instance to receive a task's lifecycle events.
+     * @return a Future representing pending completion of the task,
+     * and whose <tt>get()</tt> method will return <tt>null</tt>
+     * upon completion.
+     * @throws RejectedExecutionException if task cannot be scheduled
+     * for execution.
+     * @throws NullPointerException if command is null
+     */
+    public ScheduledFuture<?> schedule(Runnable command, long delay,  TimeUnit unit, ManagedTaskListener taskListener);
+
+    /**
+     * Creates and executes a ScheduledFuture that becomes enabled after the
+     * given delay.
+     * @param callable the function to execute.
+     * @param delay the time from now to delay execution.
+     * @param unit the time unit of the delay parameter.
+     * @param taskListener the ManagedTaskListener instance to receive a task's lifecycle events.
+     * @return a ScheduledFuture that can be used to extract result or cancel.
+     * @throws RejectedExecutionException if task cannot be scheduled
+     * for execution.
+     * @throws NullPointerException if callable is null
+     */
+    public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit, ManagedTaskListener taskListener);
+
+    /**
+     * Creates and executes a periodic action that becomes enabled first
+     * after the given initial delay, and subsequently with the given
+     * period; that is executions will commence after
+     * <tt>initialDelay</tt> then <tt>initialDelay+period</tt>, then
+     * <tt>initialDelay + 2 * period</tt>, and so on.
+     * If any execution of the task
+     * encounters an exception, subsequent executions are suppressed.
+     * Otherwise, the task will only terminate via cancellation or
+     * termination of the executor.
+     * @param command the task to execute.
+     * @param initialDelay the time to delay first execution.
+     * @param period the period between successive executions.
+     * @param unit the time unit of the initialDelay and period parameters
+     * @param taskListener the ManagedTaskListener instance to receive a task's lifecycle events.
+     * @return a Future representing pending completion of the task,
+     * and whose <tt>get()</tt> method will throw an exception upon
+     * cancellation.
+     * @throws RejectedExecutionException if task cannot be scheduled
+     * for execution.
+     * @throws NullPointerException if command is null
+     * @throws IllegalArgumentException if period less than or equal to zero.
+     */
+    public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay,  long period, TimeUnit unit, ManagedTaskListener taskListener);
+
+    /**
+     * Creates and executes a periodic action that becomes enabled first
+     * after the given initial delay, and subsequently with the
+     * given delay between the termination of one execution and the
+     * commencement of the next. If any execution of the task
+     * encounters an exception, subsequent executions are suppressed.
+     * Otherwise, the task will only terminate via cancellation or
+     * termination of the executor.
+     * @param command the task to execute.
+     * @param initialDelay the time to delay first execution.
+     * @param delay the delay between the termination of one
+     * execution and the commencement of the next.
+     * @param unit the time unit of the initialDelay and delay parameters
+     * @param taskListener the ManagedTaskListener instance to receive a task's lifecycle events.
+     * @return a Future representing pending completion of the task,
+     * and whose <tt>get()</tt> method will throw an exception upon
+     * cancellation.
+     * @throws RejectedExecutionException if task cannot be scheduled
+     * for execution.
+     * @throws NullPointerException if command is null
+     * @throws IllegalArgumentException if delay less than or equal to zero.
+     */
+    public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay,  long delay, TimeUnit unit, ManagedTaskListener taskListener);
+}

Propchange: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedScheduledExecutorService.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedTaskListener.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedTaskListener.java?rev=634792&view=auto
==============================================================================
--- geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedTaskListener.java (added)
+++ geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedTaskListener.java Fri Mar  7 11:56:14 2008
@@ -0,0 +1,136 @@
+/**
+ *  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 javax.util.concurrent;
+
+import java.util.concurrent.Future;
+
+
+
+/**
+ * A ManagedTaskListener is used to monitor the state of a task's Future.
+ * It can be registered with a {@link javax.util.concurrent.ManagedExecutorService} using the
+ * <code>submit</code> methods and will be invoked when the state of the Future changes.
+ * Each listener method will run with the same context in which the task runs.
+ * The listener becomes a Contextual Task.  All listeners run without an explicit transaction (they do not enlist in the application
+ * component's transaction).  If a transaction is required, use a
+ * {@link javax.transaction.UserTransaction} instance.<p>
+ *
+ * Each listener instance will be invoked within the same process in which the listener was registered.
+ * If a single listener is submitted to multiple ManagedExecutorService instances, the
+ * listener object may be invoked concurrently by multiple threads.<p>
+ *
+ * Each listener method supports a minimum quality of service of at-most-once.  A listener is not
+ * guaranteed to be invoked due to a process failure or termination.
+ *
+ * <b>State Transition Diagram</b>
+ * The following state transition figure and tables describe
+ * the possible task lifecycle events that can occur when a
+ * ManagedTaskListener is associated with a task.  Each method is invoked
+ * when the state of the future moves from one state to another.<p>
+ * <img src="doc-files/TaskListener_StateDiagram.gif"><p>
+ *
+ * <b>A. The task runs normally:</b>
+ * <table>
+ * <tr><td valign="top"><strong><u>Sequence</u></strong></td><td valign="top"><strong><u>State</u></strong></td><td valign="top"><strong><u>Action</u></strong></td><td valign="top"><strong><u>Listener</u></strong></td><td valign="top"><strong><u>Next state</u></strong></td></tr>
+ * <tr><td valign="top">1.</td><td valign="top">None</td><td valign="top">submit()</td><td valign="top">taskSubmitted</td><td valign="top">Submitted</td></tr>
+ * <tr><td valign="top">2.</td><td valign="top">Submitted</td><td valign="top">About to call run()</td><td valign="top">taskStarting</td><td valign="top">Started</td></tr>
+ * <tr><td valign="top">3.</td><td valign="top">Started</td><td valign="top">Exit run()</td><td valign="top">taskDone</td><td valign="top">Done</td></tr>
+ * </table><p>
+ *
+ * <b>B. The task is cancelled during taskSubmitted():</b>
+ * <table>
+ * <tr><td valign="top"><strong><u>Sequence</u></strong></td><td valign="top"><strong><u>State</u></strong></td><td valign="top"><strong><u>Action</u></strong></td><td valign="top"><strong><u>Listener</u></strong></td><td valign="top"><strong><u>Next state</u></strong></td></tr>
+ * <tr><td valign="top">1.</td><td valign="top">None</td><td valign="top">submit()</td><td valign="top">taskSubmitted<br>Future is cancelled.</td><td valign="top">Cancelling</td></tr>
+ * <tr><td valign="top">2.</td><td valign="top">Cancelling</td><td valign="top">&nbsp;</td><td valign="top">taskAborted</td><td valign="top">Cancelled</td></tr>
+ * <tr><td valign="top">3.</td><td valign="top">Cancelled</td><td valign="top">&nbsp;</td><td valign="top">taskDone</td><td valign="top">Done</td></tr>
+ * </table><p>
+ *
+ * <b>C. The task is cancelled or aborted after submitted, but before started:</b>
+ * <table>
+ * <tr><td valign="top"><strong><u>Sequence</u></strong></td><td valign="top"><strong><u>State</u></strong></td><td valign="top"><strong><u>Action</u></strong></td><td valign="top"><strong><u>Listener</u></strong></td><td valign="top"><strong><u>Next state</u></strong></td></tr>
+ * <tr><td valign="top">1.</td><td valign="top">None</td><td valign="top">submit()</td><td valign="top">taskSubmitted</td><td valign="top">Submitted</td></tr>
+ * <tr><td valign="top">2.</td><td valign="top">Submitted</td><td valign="top">cancel() or abort</td><td valign="top">taskAborted</td><td valign="top">Cancelled</td></tr>
+ * <tr><td valign="top">3.</td><td valign="top">Cancelled</td><td valign="top">&nbsp;</td><td valign="top">taskDone</td><td valign="top">Done</td></tr>
+ * </table><p>
+ *
+ * <b>D. The task is cancelled when it is starting:</b>
+ * <table>
+ * <tr><td valign="top"><strong><u>Sequence</u></strong></td><td valign="top"><strong><u>State</u></strong></td><td valign="top"><strong><u>Action</u></strong></td><td valign="top"><strong><u>Listener</u></strong></td><td valign="top"><strong><u>Next state</u></strong></td></tr>
+ * <tr><td valign="top">1.</td><td valign="top">None</td><td valign="top">submit()</td><td valign="top">taskSubmitted</td><td valign="top">Submitted</td></tr>
+ * <tr><td valign="top">2.</td><td valign="top">Submitted</td><td valign="top">About to call run()</td><td valign="top">taskStarting<br>Future is cancelled.</td><td valign="top">Cancelling</td></tr>
+ * <tr><td valign="top">3.</td><td valign="top">Cancelling</td><td valign="top">&nbsp;</td><td valign="top">taskAborted</td><td valign="top">Cancelled</td></tr>
+ * <tr><td valign="top">4.</td><td valign="top">Cancelled</td><td valign="top">&nbsp;</td><td valign="top">taskDone</td><td valign="top">Done</td></tr>
+ * </table>
+ */
+public interface ManagedTaskListener
+{
+    /**
+     * Called after the task has been submitted to the Executor.
+     * The task will not enter the starting state until the taskSubmitted
+     * listener has completed.  This method may be called from
+     * the same thread that the task was submitted with. <p>
+     *
+     * This event does not indicate that the task has been scheduled for execution.
+     *
+     * @param future the future instance that was created when the task was submitted.
+     * The <code>Future.get()</code> methods should not be used within the scope
+     * of this listener method, as they may cause deadlocks.
+     * @param executor the executor used to run the associated Future.
+     */
+    void taskSubmitted(Future<?> future, ManagedExecutorService executor);
+
+    /**
+     * Called when a task’s Future has been cancelled anytime
+     * during the life of a task.  This method may be called after taskDone().
+     *
+     * The <code>Future.isCancelled()</code> method returns false if the task was aborted
+     * through another means other than Future.cancel().  The Future.get() method will throw
+     * an exception that will represent the cause of the cancellation:
+     * <ul>
+     * <li>{@link java.util.concurrent.CancellationException} if the task was cancelled,
+     * <li>{@link javax.util.concurrent.SkippedException} if the task was skipped or
+     * <li>{@link javax.util.concurrent.AbortedException} if the task failed to start for another reason.
+     * </ul>
+     * The <code>AbortedException#getCause()</code> method will return the exception
+     * that caused the task to fail to start.
+     *
+     * @param future the future instance that was created when the task was submitted.
+     * @param executor the executor used to run the associated Future.
+     */
+    void taskAborted(Future<?> future, ManagedExecutorService executor, Throwable exception);
+
+    /**
+     * Called when a submitted task has completed running, successful or otherwise after
+     * submitted.
+     * @param future the future instance that was created when the task was submitted.
+     * @param executor the executor used to run the associated Future.
+     */
+    void taskDone(Future<?> future, ManagedExecutorService executor, Throwable exception);
+
+    /**
+     * Called when a task is about to start running.<p>
+     *
+     * This method may be called from the same thread that the task was submitted with.
+     *
+     * @param future the future instance that was created when the task was submitted.
+     * The <code>Future.get()</code> methods should not be used within the scope
+     * of this listener method, as they may cause deadlocks.
+     * @param executor the executor used to run the associated Future.
+     */
+    void taskStarting(Future<?> future, ManagedExecutorService executor);
+
+}

Propchange: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedTaskListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedThreadFactory.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedThreadFactory.java?rev=634792&view=auto
==============================================================================
--- geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedThreadFactory.java (added)
+++ geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedThreadFactory.java Fri Mar  7 11:56:14 2008
@@ -0,0 +1,79 @@
+/**
+ *  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 javax.util.concurrent;
+
+import java.util.concurrent.ThreadFactory;
+
+/**
+ * A manageable version of a {@link java.util.concurrent.ThreadFactory}.<p>
+ *
+ * A ManagedThreadFactory provides a method for creating threads for execution
+ * in a managed environment.  Implementations of the ManagedThreadFactory are
+ * provided by a Java&TRADE; EE Product Provider.  Application Component Providers
+ * use the Java Naming and Directory Interface&trade; (JNDI) to look-up instances of one
+ * or more ManagedThreadFactory objects using resource environment references.<p>
+ *
+ * The Concurrency Utilities for Java&trade; EE specification describes several
+ * behaviors that a ManagedThreadFactory can implement.  The Application
+ * Component Provider and Deployer identify these requirements and map the
+ * resource environment reference appropriately.<p>
+ *
+ * The Runnable task that is allocated to the new thread using the
+ * {@link java.util.concurrent.ThreadFactory#newThread(java.lang.Runnable)} method
+ * will run with the application component context of the component instance
+ * that created (looked-up) this ManagedThreadFactory instance.<p>
+ *
+ * The task runs without an explicit transaction (they do not enlist in the application
+ * component's transaction).  If a transaction is required, use a
+ * {@link javax.transaction.UserTransaction} instance.  A UserTransaction instance is
+ * available in JNDI using the name: &QUOT;java:comp/UserTransaction&QUOT<p>
+ *
+ * Example:<pre>
+ * public run() {
+ *     // Begin of task
+ *     InitialContext ctx = new InitialContext();
+ *     UserTransaction ut = (UserTransaction) ctx.lookup("java:comp/UserTransaction");
+ *     ut.begin();
+ *
+ *     // Perform transactional business logic
+ *
+ *     ut.commit();
+ * }</PRE>
+ *
+ * A ManagedThreadFactory can be used with Java SE ExecutorService implementations directly.<p>
+ *
+ * Example:<pre>
+ * &#47;**
+ *  * Create a ThreadPoolExecutor using a ManagedThreadFactory.
+ *  * Resource Mappings:
+ *  *  type:      javax.util.concurrent.ManagedThreadFactory
+ *  *  jndi-name: concurrent/tf/DefaultThreadFactory
+ *  *&#47;
+ * public ExecutorService getManagedThreadPool() {
+ *     InitialContext ctx = new InitialContext();
+ *     ManagedThreadFactory tf = (ManagedThreadFactory)
+ *         ctx.lookup("java:comp/env/concurrent/tf/DefaultThreadFactory");
+ *
+ *     // All threads will run as part of this application component.
+ *     return new ThreadPoolExecutor(5, 10, 5, TimeUnit.SECONDS,
+ *         new ArrayBlockingQueue&LT;Runnable&GT;(10), tf);
+ * }
+ * </pre>
+ */
+public interface ManagedThreadFactory extends ThreadFactory {
+
+}

Propchange: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedThreadFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/SkippedException.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/SkippedException.java?rev=634792&view=auto
==============================================================================
--- geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/SkippedException.java (added)
+++ geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/SkippedException.java Fri Mar  7 11:56:14 2008
@@ -0,0 +1,80 @@
+/**
+ *  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 javax.util.concurrent;
+
+import java.util.concurrent.ExecutionException;
+
+/**
+ * Exception indicating that the result of a value-producing task, cannot be retrieved because the
+ * task run was skipped.  A task can be skipped if the {@link Trigger#skipRun(Future, Date)}
+ * method returns false or if it throws an unchecked exception.<p>
+ *
+ * Use the {@link java.lang.Throwable#getCause()} method to determine if an unchecked exception was
+ * thrown from the Trigger.
+ */
+public class SkippedException extends ExecutionException {
+
+    private static final long serialVersionUID = 6962107961025815578L;
+
+    /**
+     * Constructs an SkippedException with <code>null</code> as its detail message.
+     * The cause is not initialized, and may subsequently be initialized by a call to
+     * {@link java.lang.Throwable#initCause(java.lang.Throwable)}.
+     */
+    public SkippedException() {
+        super();
+    }
+
+    /**
+     * Constructs an SkippedException exception with the specified detail message.<p>
+     *
+     * The cause is not initialized, and may subsequently be initialized by a call to
+     * {@link java.lang.Throwable#initCause(java.lang.Throwable)}.
+     *
+     * @param message the detail message (which is saved for later retrieval by the {@link java.lang.Throwable#getMessage()} method).
+     */
+    public SkippedException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs an SkippedException exception with the specified detail message and cause.<p>
+     *
+     * Note that the detail message associated with cause is not automatically incorporated in
+     * this exception's detail message.
+     *
+     * @param message the detail message (which is saved for later retrieval by the {@link java.lang.Throwable#getMessage()} method).
+     * @param cause the cause (which is saved for later retrieval by the {@link java.lang.Throwable#getCause()} method).
+     * (A null value is permitted, and indicates that the cause is nonexistent or unknown.)
+     */
+    public SkippedException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Constructs an SkippedException exception with the specified cause and a
+     * detail message of (cause==null ? null : cause.toString())
+     * (which typically contains the class and detail message of cause).
+     *
+     * @param cause the cause (which is saved for later retrieval by the {@link java.lang.Throwable#getCause()} method).
+     * (A null value is permitted, and indicates that the cause is nonexistent or unknown.)
+     */
+    public SkippedException(Throwable cause) {
+        super(cause);
+    }
+
+}

Propchange: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/SkippedException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/Trigger.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/Trigger.java?rev=634792&view=auto
==============================================================================
--- geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/Trigger.java (added)
+++ geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/Trigger.java Fri Mar  7 11:56:14 2008
@@ -0,0 +1,127 @@
+/**
+ *  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 javax.util.concurrent;
+
+import java.util.Date;
+import java.util.concurrent.Future;
+
+/**
+ * Triggers allow application developers to plug in rules
+ * for when and how often a task should run.
+ * The trigger can be as simple as a single, absolute date-time or can include
+ * Java&trade; EE business calendar logic.
+ *
+ * A Trigger implementation is created by the application developer
+ * (or may be supplied to the application externally) and is registered
+ * with a task when it is submitted to a {@link javax.util.concurrent.ManagedScheduledExecutorService}
+ * using any of the <code>schedule</code> methods.
+ *
+ * Each method will run with the same context in which the task runs.
+ * The Trigger becomes a Contextual Task.<p>
+ *
+ * Each Trigger instance will be invoked within the same process in which it was registered.<p>
+ *
+ * Example:<pre>
+ *   &#47;**
+ *    * A trigger that only returns a single date.
+ *    *&#47;
+ *    public class SingleDateTrigger implements Trigger {
+ *        private Date fireTime;
+ *
+ *        public TriggerSingleDate(Date newDate) {
+ *            fireTime = newDate;
+ *        }
+ *
+ *        public Date getNextRunTime(
+ *           Future lastFuture, Date baseTime, Date lastActualRunTime,
+ *           Date lastScheduledRunTime, Date lastCompleteTime) {
+ *
+ *           if(baseTime.after(fireTime)) {
+ *               return null;
+ *           }
+ *           return fireTime;
+ *        }
+ *
+ *        public boolean skipRun(Future lastFuture, Date scheduledRunTime) {
+ *            return scheduledRunTime.after(fireTime);
+ *        }
+ *    }
+ *
+ *   &#47;**
+ *    * A fixed-rate trigger that will skip any runs if
+ *    * the latencyAllowance threshold is exceeded (the task
+ *    * ran too late).
+ *    *&#47;
+ *    public class TriggerFixedRateLatencySensitive implements Trigger {
+ *        private Date startTime;
+ *        private long delta;
+ *        private long latencyAllowance;
+ *
+ *        public TriggerFixedRateLatencySensitive(Date startTime, long delta, long latencyAllowance) {
+ *            this.startTime = startTime;
+ *            this.delta = delta;
+ *            this.latencyAllowance = latencyAllowance;
+ *        }
+ *
+ *        public Date getNextRunTime(Future lastFuture, Date baseTime, Date lastActualRunTime, Date lastScheduledRunTime, Date lastCompleteTime) {
+ *            if(lastActualRunTime==null) {
+ *                return startTime;
+ *            }
+ *            return new Date(lastScheduledRunTime.getTime() + delta);
+ *        }
+ *
+ *        public boolean skipRun(Future lastFuture, Date scheduledRunTime) {
+ *            return System.currentTimeMillis() - scheduledRunTime.getTime() > latencyAllowance;
+ *        }
+ *    }
+ *
+ * </pre>
+ *
+ */
+public interface Trigger {
+
+    /**
+     * Retrieve the next time that the task should run after.
+     *
+     * @param lastFuture the state of the Future after the last run.
+     *        This value will be null if the task has not yet run.
+     * @param submitTime the time in which the task was originally submitted.
+     * @param lastActualRunTime the time in which the last task actually ran.
+     *        This value will be null if the task has not yet run.
+     * @param lastScheduledRunTime the time in which the last task was scheduled to run.
+     *        This value will be null if the task has not yet run.
+     * @param lastCompleteTime the time in which the last task completed.
+     *        This value will be null if the task has not yet run.
+     * @return the date/time in which the next task iteration should execute on or after.
+     */
+    Date getNextRunTime(Future<?> lastFuture, Date submitTime, Date lastActualRunTime, Date lastScheduledRunTime, Date lastCompleteTime);
+
+    /**
+     * Return true if this run instance should be skipped.<p>
+     *
+     * This is useful if the task shouldn't run because it is late or if the task is
+     * paused or suspended.<p>
+     *
+     * Once this task is skipped, the state of it's Future's result will throw a {@link SkippedException}.
+     * Unchecked exceptions will be wrapped in a SkippedException.
+     *
+     * @param scheduledRunTime the date/time that the task was originally scheduled to run.
+     *
+     * @return true if the task should be skipped and rescheduled.
+     */
+    boolean skipRun(Future<?> lastFuture, Date scheduledRunTime);
+}

Propchange: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/Trigger.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: geronimo/sandbox/concurrent/geronimo.trunk.patch
URL: http://svn.apache.org/viewvc/geronimo/sandbox/concurrent/geronimo.trunk.patch?rev=634792&view=auto
==============================================================================
--- geronimo/sandbox/concurrent/geronimo.trunk.patch (added)
+++ geronimo/sandbox/concurrent/geronimo.trunk.patch Fri Mar  7 11:56:14 2008
@@ -0,0 +1,64 @@
+Index: plugins/j2ee/j2ee-deployer/src/main/plan/plan.xml
+===================================================================
+--- plugins/j2ee/j2ee-deployer/src/main/plan/plan.xml	(revision 633583)
++++ plugins/j2ee/j2ee-deployer/src/main/plan/plan.xml	(working copy)
+@@ -124,7 +124,7 @@
+                 <name>ResourceRefBuilder</name>
+             </pattern>
+             <pattern>
+-                <name>AdminObjectRefBuilder</name>
++                <name>ManagedResourceRefBuilder</name>
+             </pattern>
+             <pattern>
+                 <name>EnvironmentEntryBuilder</name>
+Index: assemblies/geronimo-jetty6-javaee5/pom.xml
+===================================================================
+--- assemblies/geronimo-jetty6-javaee5/pom.xml	(revision 633583)
++++ assemblies/geronimo-jetty6-javaee5/pom.xml	(working copy)
+@@ -567,6 +567,21 @@
+             <version>${version}</version>
+             <type>car</type>
+         </dependency>
++
++        <dependency>
++            <groupId>org.apache.geronimo.configs</groupId>
++            <artifactId>concurrent</artifactId>
++            <version>${version}</version>
++            <type>car</type>
++        </dependency>
++
++        <dependency>
++            <groupId>org.apache.geronimo.configs</groupId>
++            <artifactId>concurrent-deployer</artifactId>
++            <version>${version}</version>
++            <type>car</type>
++        </dependency>
++
+     </dependencies>
+ 
+     <build>
+Index: assemblies/geronimo-tomcat6-javaee5/pom.xml
+===================================================================
+--- assemblies/geronimo-tomcat6-javaee5/pom.xml	(revision 633583)
++++ assemblies/geronimo-tomcat6-javaee5/pom.xml	(working copy)
+@@ -547,6 +547,20 @@
+             <type>car</type>
+         </dependency>
+ 
++        <dependency>
++            <groupId>org.apache.geronimo.configs</groupId>
++            <artifactId>concurrent</artifactId>
++            <version>${version}</version>
++            <type>car</type>
++        </dependency>
++
++        <dependency>
++            <groupId>org.apache.geronimo.configs</groupId>
++            <artifactId>concurrent-deployer</artifactId>
++            <version>${version}</version>
++            <type>car</type>
++        </dependency>
++
+     </dependencies>
+ 
+     <build>

Added: geronimo/sandbox/concurrent/pom.xml
URL: http://svn.apache.org/viewvc/geronimo/sandbox/concurrent/pom.xml?rev=634792&view=auto
==============================================================================
--- geronimo/sandbox/concurrent/pom.xml (added)
+++ geronimo/sandbox/concurrent/pom.xml Fri Mar  7 11:56:14 2008
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+
+<!-- $Rev: 513306 $ $Date: 2008/03/04 19:02:07 $ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.geronimo.plugins</groupId>
+        <artifactId>plugins</artifactId>
+        <version>2.2-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>concurrent</artifactId>
+    <name>Geronimo Plugins, Concurrency Utilities for Java EE</name>
+    <packaging>pom</packaging>
+
+    <description>
+        Implementation of the Concurrency Utilities for Java EE specification.
+    </description>
+
+    <modules>
+        <module>geronimo-concurrent_spec</module>
+        <module>geronimo-concurrent-management</module>
+        <module>geronimo-concurrent-core</module>
+        <module>geronimo-concurrent</module>
+        <module>geronimo-concurrent-builder</module>
+        <module>concurrent</module>
+        <module>concurrent-deployer</module>
+    </modules>
+
+</project>

Propchange: geronimo/sandbox/concurrent/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/concurrent/pom.xml
------------------------------------------------------------------------------
    svn:executable =