import redback components sources
http://svn.codehaus.org/redback/components/trunk/ r1724.
git-svn-id: https://svn.apache.org/repos/asf/archiva/redback/redback-components/trunk@1310262 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..ab4aabd
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,78 @@
+<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">
+ <parent>
+ <groupId>org.codehaus.redback.components</groupId>
+ <artifactId>redback-components</artifactId>
+ <version>1.3-SNAPSHOT</version>
+ <relativePath>../redback-components-parent/pom.xml</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>spring-taskqueue</artifactId>
+ <name>Spring Task Queue</name>
+ <version>1.1-SNAPSHOT</version>
+
+ <url>http://redback.codehaus.org/components/${project.artifactId}</url>
+
+ <distributionManagement>
+ <site>
+ <id>codehaus.org</id>
+ <url>dav:https://dav.codehaus.org/redback/components/${project.artifactId}</url>
+ </site>
+ </distributionManagement>
+
+ <scm>
+ <connection>scm:svn:https://svn.codehaus.org/redback/components/trunk/spring-taskqueue</connection>
+ <developerConnection>scm:svn:https://svn.codehaus.org/redback/components/trunk/spring-taskqueue</developerConnection>
+ <url>http://fisheye.codehaus.org/browse/redback/components/trunk/spring-taskqueue</url>
+ </scm>
+
+ <dependencies>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.inject</groupId>
+ <artifactId>javax.inject</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.annotation</groupId>
+ <artifactId>jsr250-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-beans</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context-support</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+</project>
diff --git a/src/main/java/org/codehaus/plexus/taskqueue/DefaultTaskQueue.java b/src/main/java/org/codehaus/plexus/taskqueue/DefaultTaskQueue.java
new file mode 100644
index 0000000..810b579
--- /dev/null
+++ b/src/main/java/org/codehaus/plexus/taskqueue/DefaultTaskQueue.java
@@ -0,0 +1,221 @@
+package org.codehaus.plexus.taskqueue;
+
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2004, The Codehaus
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+
+/**
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a>
+ * @version $Id$
+ */
+public class DefaultTaskQueue
+ implements TaskQueue
+{
+
+ private Logger logger = LoggerFactory.getLogger( getClass() );
+
+ private List<TaskEntryEvaluator> taskEntryEvaluators = new ArrayList<TaskEntryEvaluator>();
+
+ private List<TaskExitEvaluator> taskExitEvaluators = new ArrayList<TaskExitEvaluator>();
+
+ private List<TaskViabilityEvaluator> taskViabilityEvaluators = new ArrayList<TaskViabilityEvaluator>();
+
+ private BlockingQueue<Task> queue = new LinkedBlockingQueue<Task>();
+
+ // ----------------------------------------------------------------------
+ // Component Lifecycle
+ // ----------------------------------------------------------------------
+
+ // ----------------------------------------------------------------------
+ // TaskQueue Implementation
+ // ----------------------------------------------------------------------
+
+ // ----------------------------------------------------------------------
+ // Queue operations
+ // ----------------------------------------------------------------------
+
+ public boolean put( Task task )
+ throws TaskQueueException
+ {
+ // ----------------------------------------------------------------------
+ // Check that all the task entry evaluators accepts the task
+ // ----------------------------------------------------------------------
+
+ for ( TaskEntryEvaluator taskEntryEvaluator : taskEntryEvaluators )
+ {
+ boolean result = taskEntryEvaluator.evaluate( task );
+
+ if ( !result )
+ {
+ return false;
+ }
+ }
+
+ // ----------------------------------------------------------------------
+ // The task was accepted, enqueue it
+ // ----------------------------------------------------------------------
+
+ enqueue( task );
+
+ // ----------------------------------------------------------------------
+ // Check that all the task viability evaluators accepts the task
+ // ----------------------------------------------------------------------
+
+ for ( TaskViabilityEvaluator taskViabilityEvaluator : taskViabilityEvaluators )
+ {
+ Collection<Task> toBeRemoved =
+ taskViabilityEvaluator.evaluate( Collections.unmodifiableCollection( queue ) );
+
+ for ( Iterator<Task> it2 = toBeRemoved.iterator(); it2.hasNext(); )
+ {
+ Task t = it2.next();
+
+ queue.remove( t );
+ }
+ }
+
+ return true;
+ }
+
+ public Task take()
+ throws TaskQueueException
+ {
+ logger.debug( "take" );
+ while ( true )
+ {
+ Task task = dequeue();
+
+ if ( task == null )
+ {
+ return null;
+ }
+
+ for ( TaskExitEvaluator taskExitEvaluator : taskExitEvaluators )
+ {
+ boolean result = taskExitEvaluator.evaluate( task );
+
+ if ( !result )
+ {
+ // the task wasn't accepted; drop it.
+ task = null;
+
+ break;
+ }
+ }
+
+ if ( task != null )
+ {
+ return task;
+ }
+ }
+ }
+
+ public Task poll( int timeout, TimeUnit timeUnit )
+ throws InterruptedException
+ {
+ logger.debug( "pool" );
+ return queue.poll( timeout, timeUnit );
+ }
+
+ public boolean remove( Task task )
+ throws ClassCastException, NullPointerException
+ {
+ return queue.remove( task );
+ }
+
+ public boolean removeAll( List tasks )
+ throws ClassCastException, NullPointerException
+ {
+ return queue.removeAll( tasks );
+ }
+
+ // ----------------------------------------------------------------------
+ // Queue Inspection
+ // ----------------------------------------------------------------------
+
+ public List<Task> getQueueSnapshot()
+ throws TaskQueueException
+ {
+ return Collections.unmodifiableList( new ArrayList( queue ) );
+ }
+
+ // ----------------------------------------------------------------------
+ // Queue Management
+ // ----------------------------------------------------------------------
+
+ private void enqueue( Task task )
+ {
+ boolean success = queue.add( task );
+ logger.debug( "enqueue success {}", success );
+ }
+
+ private Task dequeue()
+ {
+ logger.debug( "dequeue" );
+ return queue.poll();
+ }
+
+ public List<TaskEntryEvaluator> getTaskEntryEvaluators()
+ {
+ return taskEntryEvaluators;
+ }
+
+ public void setTaskEntryEvaluators( List<TaskEntryEvaluator> taskEntryEvaluators )
+ {
+ this.taskEntryEvaluators = taskEntryEvaluators;
+ }
+
+ public List<TaskExitEvaluator> getTaskExitEvaluators()
+ {
+ return taskExitEvaluators;
+ }
+
+ public void setTaskExitEvaluators( List<TaskExitEvaluator> taskExitEvaluators )
+ {
+ this.taskExitEvaluators = taskExitEvaluators;
+ }
+
+ public List<TaskViabilityEvaluator> getTaskViabilityEvaluators()
+ {
+ return taskViabilityEvaluators;
+ }
+
+ public void setTaskViabilityEvaluators( List<TaskViabilityEvaluator> taskViabilityEvaluators )
+ {
+ this.taskViabilityEvaluators = taskViabilityEvaluators;
+ }
+}
diff --git a/src/main/java/org/codehaus/plexus/taskqueue/Task.java b/src/main/java/org/codehaus/plexus/taskqueue/Task.java
new file mode 100644
index 0000000..3dd3fdc
--- /dev/null
+++ b/src/main/java/org/codehaus/plexus/taskqueue/Task.java
@@ -0,0 +1,38 @@
+package org.codehaus.plexus.taskqueue;
+
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2004, The Codehaus
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/**
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a>
+ * @version $Id$
+ */
+public interface Task
+{
+ /**
+ * @return the maximum time in milliseconds this task may run before it's cancelled.
+ */
+ long getMaxExecutionTime();
+}
diff --git a/src/main/java/org/codehaus/plexus/taskqueue/TaskEntryEvaluator.java b/src/main/java/org/codehaus/plexus/taskqueue/TaskEntryEvaluator.java
new file mode 100644
index 0000000..b732e10
--- /dev/null
+++ b/src/main/java/org/codehaus/plexus/taskqueue/TaskEntryEvaluator.java
@@ -0,0 +1,38 @@
+package org.codehaus.plexus.taskqueue;
+
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2004, The Codehaus
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/**
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a>
+ * @version $Id$
+ */
+public interface TaskEntryEvaluator
+{
+ String ROLE = TaskEntryEvaluator.class.getName();
+
+ boolean evaluate( Task task )
+ throws TaskQueueException;
+}
diff --git a/src/main/java/org/codehaus/plexus/taskqueue/TaskExitEvaluator.java b/src/main/java/org/codehaus/plexus/taskqueue/TaskExitEvaluator.java
new file mode 100644
index 0000000..95dd907
--- /dev/null
+++ b/src/main/java/org/codehaus/plexus/taskqueue/TaskExitEvaluator.java
@@ -0,0 +1,38 @@
+package org.codehaus.plexus.taskqueue;
+
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2004, The Codehaus
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/**
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a>
+ * @version $Id$
+ */
+public interface TaskExitEvaluator
+{
+ String ROLE = TaskExitEvaluator.class.getName();
+
+ boolean evaluate( Task task )
+ throws TaskQueueException;
+}
diff --git a/src/main/java/org/codehaus/plexus/taskqueue/TaskQueue.java b/src/main/java/org/codehaus/plexus/taskqueue/TaskQueue.java
new file mode 100644
index 0000000..832528c
--- /dev/null
+++ b/src/main/java/org/codehaus/plexus/taskqueue/TaskQueue.java
@@ -0,0 +1,82 @@
+package org.codehaus.plexus.taskqueue;
+
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2004, The Codehaus
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+
+/**
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a>
+ * @version $Id$
+ */
+public interface TaskQueue
+{
+ String ROLE = TaskQueue.class.getName();
+
+ // ----------------------------------------------------------------------
+ // Queue operations
+ // ----------------------------------------------------------------------
+
+ /**
+ * @param task
+ * The task to add to the queue.
+ * @return Returns true if the task was accepted into the queue.
+ */
+ boolean put( Task task )
+ throws TaskQueueException;
+
+ Task take()
+ throws TaskQueueException;
+
+ boolean remove( Task task )
+ throws ClassCastException, NullPointerException;
+
+ boolean removeAll( List tasks )
+ throws ClassCastException, NullPointerException;
+
+ // ----------------------------------------------------------------------
+ // Queue Inspection
+ // ----------------------------------------------------------------------
+
+ List getQueueSnapshot()
+ throws TaskQueueException;
+
+ /**
+ * Retrieves and removes the head of the queue, waiting at most timeout timeUnit when no element is available.
+ *
+ * @param timeout
+ * time to wait, in timeUnit units
+ * @param timeUnit
+ * how to interpret the timeout parameter.
+ * @return the head of the queue, or null if the timeout elapsed
+ * @throws InterruptedException
+ * when this thread is interrupted while waiting
+ */
+ Task poll( int timeout, TimeUnit timeUnit )
+ throws InterruptedException;
+}
diff --git a/src/main/java/org/codehaus/plexus/taskqueue/TaskQueueException.java b/src/main/java/org/codehaus/plexus/taskqueue/TaskQueueException.java
new file mode 100644
index 0000000..c448906
--- /dev/null
+++ b/src/main/java/org/codehaus/plexus/taskqueue/TaskQueueException.java
@@ -0,0 +1,43 @@
+package org.codehaus.plexus.taskqueue;
+
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2004, The Codehaus
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a>
+ * @version $Id$
+ */
+public class TaskQueueException
+ extends Exception
+{
+ public TaskQueueException( String message )
+ {
+ super( message );
+ }
+
+ public TaskQueueException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+}
diff --git a/src/main/java/org/codehaus/plexus/taskqueue/TaskViabilityEvaluator.java b/src/main/java/org/codehaus/plexus/taskqueue/TaskViabilityEvaluator.java
new file mode 100644
index 0000000..2ee2fc2
--- /dev/null
+++ b/src/main/java/org/codehaus/plexus/taskqueue/TaskViabilityEvaluator.java
@@ -0,0 +1,45 @@
+package org.codehaus.plexus.taskqueue;
+
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2004, The Codehaus
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import java.util.Collection;
+
+/**
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a>
+ * @version $Id$
+ */
+public interface TaskViabilityEvaluator
+{
+ String ROLE = TaskViabilityEvaluator.class.getName();
+
+ /**
+ * @param tasks The tasks to evaluate
+ * @return Returns a list of tasks to remove from the queue.
+ * @throws TaskQueueException
+ */
+ Collection<Task> evaluate( Collection tasks )
+ throws TaskQueueException;
+}
diff --git a/src/main/java/org/codehaus/plexus/taskqueue/execution/TaskExecutionException.java b/src/main/java/org/codehaus/plexus/taskqueue/execution/TaskExecutionException.java
new file mode 100644
index 0000000..aac0f81
--- /dev/null
+++ b/src/main/java/org/codehaus/plexus/taskqueue/execution/TaskExecutionException.java
@@ -0,0 +1,43 @@
+package org.codehaus.plexus.taskqueue.execution;
+
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2004, The Codehaus
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a>
+ * @version $Id$
+ */
+public class TaskExecutionException
+ extends Exception
+{
+ public TaskExecutionException( String message )
+ {
+ super( message );
+ }
+
+ public TaskExecutionException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+}
diff --git a/src/main/java/org/codehaus/plexus/taskqueue/execution/TaskExecutor.java b/src/main/java/org/codehaus/plexus/taskqueue/execution/TaskExecutor.java
new file mode 100644
index 0000000..15bea9d
--- /dev/null
+++ b/src/main/java/org/codehaus/plexus/taskqueue/execution/TaskExecutor.java
@@ -0,0 +1,37 @@
+package org.codehaus.plexus.taskqueue.execution;
+
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2004, The Codehaus
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import org.codehaus.plexus.taskqueue.Task;
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a>
+ * @version $Id$
+ */
+public interface TaskExecutor
+{
+ void executeTask( Task task )
+ throws TaskExecutionException;
+}
diff --git a/src/main/java/org/codehaus/plexus/taskqueue/execution/TaskQueueExecutor.java b/src/main/java/org/codehaus/plexus/taskqueue/execution/TaskQueueExecutor.java
new file mode 100644
index 0000000..e097bc1
--- /dev/null
+++ b/src/main/java/org/codehaus/plexus/taskqueue/execution/TaskQueueExecutor.java
@@ -0,0 +1,52 @@
+package org.codehaus.plexus.taskqueue.execution;
+
+import org.codehaus.plexus.taskqueue.Task;
+
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2004, The Codehaus
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a>
+ * @version $Id$
+ */
+public interface TaskQueueExecutor
+{
+ String ROLE = TaskQueueExecutor.class.getName();
+
+ /**
+ * Returns the currently executing task.
+ *
+ * @return the currently executing task.
+ */
+ Task getCurrentTask();
+
+ /**
+ * Cancels execution of this task, if it's currently running.
+ * Does NOT remove it from the associated queue!
+ *
+ * @param task The task to cancel
+ * @return true if the task was cancelled, false if the task was not executing.
+ */
+ boolean cancelTask( Task task );
+}
diff --git a/src/main/java/org/codehaus/plexus/taskqueue/execution/ThreadedTaskQueueExecutor.java b/src/main/java/org/codehaus/plexus/taskqueue/execution/ThreadedTaskQueueExecutor.java
new file mode 100644
index 0000000..c827e18
--- /dev/null
+++ b/src/main/java/org/codehaus/plexus/taskqueue/execution/ThreadedTaskQueueExecutor.java
@@ -0,0 +1,378 @@
+package org.codehaus.plexus.taskqueue.execution;
+
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2004, The Codehaus
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import org.apache.commons.lang.StringUtils;
+import org.codehaus.plexus.taskqueue.Task;
+import org.codehaus.plexus.taskqueue.TaskQueue;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.inject.Inject;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a>
+ * @author <a href="mailto:kenney@codehaus.org">Kenney Westerhof</a>
+ * @version $Id$
+ */
+public class ThreadedTaskQueueExecutor
+ implements TaskQueueExecutor
+{
+
+ private Logger logger = LoggerFactory.getLogger( getClass() );
+
+ private static final int SHUTDOWN = 1;
+
+ private static final int CANCEL_TASK = 2;
+
+ /**
+ * requirement
+ */
+ private TaskQueue queue;
+
+ /**
+ * requirement
+ */
+ private TaskExecutor executor;
+
+ /**
+ * configuration
+ */
+ private String name;
+
+ // ----------------------------------------------------------------------
+ //
+ // ----------------------------------------------------------------------
+
+ private ExecutorRunnable executorRunnable;
+
+ private ExecutorService executorService;
+
+ private Task currentTask;
+
+ private class ExecutorRunnable
+ extends Thread
+ {
+ private volatile int command;
+
+ private boolean done;
+
+ public void run()
+ {
+ while ( command != SHUTDOWN )
+ {
+ final Task task;
+
+ currentTask = null;
+
+ try
+ {
+ task = queue.poll( 100, TimeUnit.MILLISECONDS );
+ }
+ catch ( InterruptedException e )
+ {
+ logger.info( "Executor thread interrupted, command: {}", ( command == SHUTDOWN
+ ? "Shutdown"
+ : command == CANCEL_TASK ? "Cancel task" : "Unknown" ) );
+ continue;
+ }
+
+ if ( task == null )
+ {
+ continue;
+ }
+
+ currentTask = task;
+
+ Future future = executorService.submit( new Runnable()
+ {
+ public void run()
+ {
+ try
+ {
+ executor.executeTask( task );
+ }
+ catch ( TaskExecutionException e )
+ {
+ logger.error( "Error executing task", e );
+ }
+ }
+ } );
+
+ try
+ {
+ waitForTask( task, future );
+ }
+ catch ( ExecutionException e )
+ {
+ logger.error( "Error executing task", e );
+ }
+ }
+
+ currentTask = null;
+
+ logger.info( "Executor thread '{}' exited.", name );
+
+ done = true;
+
+ synchronized ( this )
+ {
+ notifyAll();
+ }
+ }
+
+ private void waitForTask( Task task, Future future )
+ throws ExecutionException
+ {
+ boolean stop = false;
+
+ while ( !stop )
+ {
+ try
+ {
+ if ( task.getMaxExecutionTime() == 0 )
+ {
+ logger.debug( "Waiting indefinitely for task to complete" );
+ future.get();
+ return;
+ }
+ else
+ {
+ logger.debug( "Waiting at most {} ms for task completion", task.getMaxExecutionTime() );
+ future.get( task.getMaxExecutionTime(), TimeUnit.MILLISECONDS );
+ logger.debug( "Task completed within {} ms", task.getMaxExecutionTime() );
+ return;
+ }
+ }
+ catch ( InterruptedException e )
+ {
+ switch ( command )
+ {
+ case SHUTDOWN:
+ {
+ logger.info( "Shutdown command received. Cancelling task." );
+ cancel( future );
+ return;
+ }
+
+ case CANCEL_TASK:
+ {
+ command = 0;
+ logger.info( "Cancelling task" );
+ cancel( future );
+ return;
+ }
+
+ default:
+ // when can this thread be interrupted, and should we ignore it if shutdown = false?
+ logger.warn( "Interrupted while waiting for task to complete; ignoring", e );
+ break;
+ }
+ }
+ catch ( TimeoutException e )
+ {
+ logger.warn( "Task {} didn't complete within time, cancelling it.", task );
+ cancel( future );
+ return;
+ }
+ catch ( CancellationException e )
+ {
+ logger.warn( "The task was cancelled", e );
+ return;
+ }
+ }
+ }
+
+ private void cancel( Future future )
+ {
+ if ( !future.cancel( true ) )
+ {
+ if ( !future.isDone() && !future.isCancelled() )
+ {
+ logger.warn( "Unable to cancel task" );
+ }
+ else
+ {
+ logger.warn(
+ "Task not cancelled (Flags: done: " + future.isDone() + " cancelled: " + future.isCancelled()
+ + ")" );
+ }
+ }
+ else
+ {
+ logger.debug( "Task successfully cancelled" );
+ }
+ }
+
+ public synchronized void shutdown()
+ {
+ logger.debug( "Signalling executor thread to shutdown" );
+
+ command = SHUTDOWN;
+
+ interrupt();
+ }
+
+ public synchronized boolean cancelTask( Task task )
+ {
+ if ( !task.equals( currentTask ) )
+ {
+ logger.debug( "Not cancelling task - it is not running" );
+ return false;
+ }
+
+ if ( command != SHUTDOWN )
+ {
+ logger.debug( "Signalling executor thread to cancel task" );
+
+ command = CANCEL_TASK;
+
+ interrupt();
+ }
+ else
+ {
+ logger.debug( "Executor thread already stopping; task will be cancelled automatically" );
+ }
+
+ return true;
+ }
+
+ public boolean isDone()
+ {
+ return done;
+ }
+ }
+
+ // ----------------------------------------------------------------------
+ // Component lifecycle
+ // ----------------------------------------------------------------------
+
+ @PostConstruct
+ public void start()
+ {
+
+ if ( StringUtils.isBlank( name ) )
+ {
+ throw new IllegalArgumentException( "'name' must be set." );
+ }
+
+ logger.info( "Starting task executor, thread name '{}'.", name );
+
+ this.executorService = Executors.newSingleThreadExecutor();
+
+ executorRunnable = new ExecutorRunnable();
+
+ executorRunnable.setDaemon( true );
+
+ executorRunnable.start();
+ }
+
+ @PreDestroy
+ public void stop()
+ {
+ executorRunnable.shutdown();
+
+ int maxSleep = 10 * 1000; // 10 seconds
+
+ int interval = 1000;
+
+ long endTime = System.currentTimeMillis() + maxSleep;
+
+ while ( !executorRunnable.isDone() && executorRunnable.isAlive() )
+ {
+ if ( System.currentTimeMillis() > endTime )
+ {
+ logger.warn( "Timeout waiting for executor thread '" + name + "' to stop, aborting" );
+ break;
+ }
+
+ logger.info( "Waiting until task executor '" + name + "' is idling..." );
+
+ try
+ {
+ synchronized ( executorRunnable )
+ {
+ executorRunnable.wait( interval );
+ }
+ }
+ catch ( InterruptedException ex )
+ {
+ // ignore
+ }
+
+ // notify again, just in case.
+ executorRunnable.shutdown();
+ }
+ }
+
+ public Task getCurrentTask()
+ {
+ return currentTask;
+ }
+
+ public synchronized boolean cancelTask( Task task )
+ {
+ return executorRunnable.cancelTask( task );
+ }
+
+ public TaskQueue getQueue()
+ {
+ return queue;
+ }
+
+ public void setQueue( TaskQueue queue )
+ {
+ this.queue = queue;
+ }
+
+ public TaskExecutor getExecutor()
+ {
+ return executor;
+ }
+
+ public void setExecutor( TaskExecutor executor )
+ {
+ this.executor = executor;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public void setName( String name )
+ {
+ this.name = name;
+ }
+}
diff --git a/src/main/resources/META-INF/spring-context.xml b/src/main/resources/META-INF/spring-context.xml
new file mode 100755
index 0000000..08cf61b
--- /dev/null
+++ b/src/main/resources/META-INF/spring-context.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+
+<!--
+ ~ 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.
+ -->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+ http://www.springframework.org/schema/context
+ http://www.springframework.org/schema/context/spring-context-3.0.xsd"
+ default-lazy-init="true">
+
+ <context:annotation-config />
+ <context:component-scan
+ base-package="org.codehaus.plexus.taskqueue"/>
+
+</beans>
\ No newline at end of file
diff --git a/src/test/java/org/codehaus/plexus/taskqueue/ATaskEntryEvaluator.java b/src/test/java/org/codehaus/plexus/taskqueue/ATaskEntryEvaluator.java
new file mode 100644
index 0000000..3a90140
--- /dev/null
+++ b/src/test/java/org/codehaus/plexus/taskqueue/ATaskEntryEvaluator.java
@@ -0,0 +1,42 @@
+package org.codehaus.plexus.taskqueue;
+
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2004, The Codehaus
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import org.springframework.stereotype.Service;
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a>
+ * @version $Id$
+ */
+@Service("taskEntryEvaluator#a")
+public class ATaskEntryEvaluator
+ implements TaskEntryEvaluator
+{
+ public boolean evaluate( Task task )
+ throws TaskQueueException
+ {
+ return ( (BuildProjectTask) task).isPassAEntryEvaluator();
+ }
+}
diff --git a/src/test/java/org/codehaus/plexus/taskqueue/ATaskExitEvaluator.java b/src/test/java/org/codehaus/plexus/taskqueue/ATaskExitEvaluator.java
new file mode 100644
index 0000000..0effd93
--- /dev/null
+++ b/src/test/java/org/codehaus/plexus/taskqueue/ATaskExitEvaluator.java
@@ -0,0 +1,42 @@
+package org.codehaus.plexus.taskqueue;
+
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2004, The Codehaus
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import org.springframework.stereotype.Service;
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a>
+ * @version $Id$
+ */
+@Service("taskExitEvaluator#a")
+public class ATaskExitEvaluator
+ implements TaskExitEvaluator
+{
+ public boolean evaluate( Task task )
+ throws TaskQueueException
+ {
+ return ( (BuildProjectTask) task ).isPassAExitEvaluator();
+ }
+}
diff --git a/src/test/java/org/codehaus/plexus/taskqueue/BTaskEntryEvaluator.java b/src/test/java/org/codehaus/plexus/taskqueue/BTaskEntryEvaluator.java
new file mode 100644
index 0000000..591e176
--- /dev/null
+++ b/src/test/java/org/codehaus/plexus/taskqueue/BTaskEntryEvaluator.java
@@ -0,0 +1,42 @@
+package org.codehaus.plexus.taskqueue;
+
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2004, The Codehaus
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import org.springframework.stereotype.Service;
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a>
+ * @version $Id$
+ */
+@Service("taskEntryEvaluator#b")
+public class BTaskEntryEvaluator
+ implements TaskEntryEvaluator
+{
+ public boolean evaluate( Task task )
+ throws TaskQueueException
+ {
+ return ( (BuildProjectTask) task ).isPassBEntryEvaluator();
+ }
+}
diff --git a/src/test/java/org/codehaus/plexus/taskqueue/BTaskExitEvaluator.java b/src/test/java/org/codehaus/plexus/taskqueue/BTaskExitEvaluator.java
new file mode 100644
index 0000000..367bbb4
--- /dev/null
+++ b/src/test/java/org/codehaus/plexus/taskqueue/BTaskExitEvaluator.java
@@ -0,0 +1,42 @@
+package org.codehaus.plexus.taskqueue;
+
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2004, The Codehaus
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import org.springframework.stereotype.Service;
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a>
+ * @version $Id$
+ */
+@Service("taskExitEvaluator#b")
+public class BTaskExitEvaluator
+ implements TaskExitEvaluator
+{
+ public boolean evaluate( Task task )
+ throws TaskQueueException
+ {
+ return ( (BuildProjectTask) task ).isPassBExitEvaluator();
+ }
+}
diff --git a/src/test/java/org/codehaus/plexus/taskqueue/BuildProjectTask.java b/src/test/java/org/codehaus/plexus/taskqueue/BuildProjectTask.java
new file mode 100644
index 0000000..c2f1a82
--- /dev/null
+++ b/src/test/java/org/codehaus/plexus/taskqueue/BuildProjectTask.java
@@ -0,0 +1,160 @@
+package org.codehaus.plexus.taskqueue;
+
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2004, The Codehaus
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a>
+ * @version $Id$
+ */
+public class BuildProjectTask
+ implements Task
+{
+ private boolean passAEntryEvaluator;
+
+ private boolean passBEntryEvaluator;
+
+ private boolean passAExitEvaluator;
+
+ private boolean passBExitEvaluator;
+
+ private long timestamp;
+
+ private long maxExecutionTime;
+
+ private long executionTime;
+
+ private boolean cancelled;
+
+ private boolean done;
+
+ private boolean started;
+
+ private boolean ignoreInterrupts;
+
+ public BuildProjectTask( boolean passAEntryEvaluator, boolean passBEntryEvaluator, boolean passAExitEvaluator,
+ boolean passBExitEvaluator )
+ {
+ this.passAEntryEvaluator = passAEntryEvaluator;
+
+ this.passBEntryEvaluator = passBEntryEvaluator;
+
+ this.passAExitEvaluator = passAExitEvaluator;
+
+ this.passBExitEvaluator = passBExitEvaluator;
+ }
+
+ public BuildProjectTask( long timestamp )
+ {
+ this( true, true, true, true );
+
+ this.timestamp = timestamp;
+ }
+
+ public boolean isPassAEntryEvaluator()
+ {
+ return passAEntryEvaluator;
+ }
+
+ public boolean isPassBEntryEvaluator()
+ {
+ return passBEntryEvaluator;
+ }
+
+ public boolean isPassAExitEvaluator()
+ {
+ return passAExitEvaluator;
+ }
+
+ public boolean isPassBExitEvaluator()
+ {
+ return passBExitEvaluator;
+ }
+
+ public long getTimestamp()
+ {
+ return timestamp;
+ }
+
+ public long getMaxExecutionTime()
+ {
+ return maxExecutionTime;
+ }
+
+ public void setMaxExecutionTime( long timeout )
+ {
+ maxExecutionTime = timeout;
+ }
+
+ public void setExecutionTime( long l )
+ {
+ this.executionTime = l;
+ }
+
+ public long getExecutionTime()
+ {
+ return executionTime;
+ }
+
+ public boolean isCancelled()
+ {
+ return cancelled;
+ }
+
+ public void cancel()
+ {
+ cancelled = true;
+ }
+
+ public void done()
+ {
+ this.done = true;
+ }
+
+ public boolean isDone()
+ {
+ return done;
+ }
+
+ public boolean isStarted()
+ {
+ return started;
+ }
+
+ public void start()
+ {
+ this.started = true;
+ }
+
+ public void setIgnoreInterrupts( boolean ignore )
+ {
+ this.ignoreInterrupts = ignore;
+ }
+
+ public boolean ignoreInterrupts()
+ {
+ return ignoreInterrupts;
+ }
+
+}
diff --git a/src/test/java/org/codehaus/plexus/taskqueue/BuildProjectTaskViabilityEvaluator.java b/src/test/java/org/codehaus/plexus/taskqueue/BuildProjectTaskViabilityEvaluator.java
new file mode 100644
index 0000000..222dab4
--- /dev/null
+++ b/src/test/java/org/codehaus/plexus/taskqueue/BuildProjectTaskViabilityEvaluator.java
@@ -0,0 +1,68 @@
+package org.codehaus.plexus.taskqueue;
+
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2004, The Codehaus
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a>
+ * @version $Id$
+ */
+@Service( "taskViabilityEvaluator#build-project" )
+public class BuildProjectTaskViabilityEvaluator
+ implements TaskViabilityEvaluator
+{
+ public Collection evaluate( Collection tasks )
+ throws TaskQueueException
+ {
+ BuildProjectTask okTask = null;
+
+ List toBeRemoved = new ArrayList( tasks.size() );
+
+ for ( Iterator it = tasks.iterator(); it.hasNext(); )
+ {
+ BuildProjectTask buildProjectTask = (BuildProjectTask) it.next();
+
+ if ( okTask == null )
+ {
+ okTask = buildProjectTask;
+
+ continue;
+ }
+
+ if ( buildProjectTask.getTimestamp() - okTask.getTimestamp() < 100 )
+ {
+ toBeRemoved.add( buildProjectTask );
+ }
+ }
+
+ return toBeRemoved;
+ }
+}
diff --git a/src/test/java/org/codehaus/plexus/taskqueue/TaskQueueTest.java b/src/test/java/org/codehaus/plexus/taskqueue/TaskQueueTest.java
new file mode 100644
index 0000000..7465ffe
--- /dev/null
+++ b/src/test/java/org/codehaus/plexus/taskqueue/TaskQueueTest.java
@@ -0,0 +1,191 @@
+package org.codehaus.plexus.taskqueue;
+
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2004, The Codehaus
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import junit.framework.TestCase;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.scheduling.TaskScheduler;
+import org.springframework.scheduling.backportconcurrent.ThreadPoolTaskExecutor;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a>
+ * @version $Id$
+ */
+@RunWith( SpringJUnit4ClassRunner.class )
+@ContextConfiguration( locations = { "classpath*:/META-INF/spring-context.xml", "classpath*:/spring-context.xml" } )
+public class TaskQueueTest
+ extends TestCase
+{
+ @Inject
+ @Named( value = "taskQueue#taskQueueTest" )
+ private TaskQueue taskQueue;
+
+
+ // NOTE: If we were using a blocking queue, the sleep/continue in the ThreadedTaskQueueExecutor wouldn't
+ // be necessary; the queue would block until an element was available.
+ @Test
+ public void testEmptyQueue()
+ throws Exception
+ {
+ assertNull( taskQueue.take() );
+ }
+
+ @Test
+ public void testTaskEntryAndExitEvaluators()
+ throws Exception
+ {
+ assertTaskIsAccepted( new BuildProjectTask( true, true, true, true ) );
+
+ assertTaskIsRejected( new BuildProjectTask( false, true, true, true ) );
+
+ assertTaskIsRejected( new BuildProjectTask( true, false, true, true ) );
+
+ assertTaskIsRejected( new BuildProjectTask( true, true, false, true ) );
+
+ assertTaskIsRejected( new BuildProjectTask( true, true, true, false ) );
+ }
+
+ @Test
+ public void testTaskViabilityEvaluators()
+ throws Exception
+ {
+ // The first and last task should be accepted
+
+ Task task1 = new BuildProjectTask( 0 );
+
+ Task task2 = new BuildProjectTask( 10 );
+
+ Task task3 = new BuildProjectTask( 20 );
+
+ Task task4 = new BuildProjectTask( 30 );
+
+ Task task5 = new BuildProjectTask( 40 );
+
+ Task task6 = new BuildProjectTask( 100 );
+
+ assertTrue( taskQueue.put( task1 ) );
+
+ assertTrue( taskQueue.put( task2 ) );
+
+ assertTrue( taskQueue.put( task3 ) );
+
+ assertTrue( taskQueue.put( task4 ) );
+
+ assertTrue( taskQueue.put( task5 ) );
+
+ assertTrue( taskQueue.put( task6 ) );
+
+ Task actualTask1 = taskQueue.take();
+
+ assertNotNull( actualTask1 );
+
+ assertEquals( task1, actualTask1 );
+
+ Task actualTask6 = taskQueue.take();
+
+ assertNotNull( actualTask6 );
+
+ assertEquals( task6, actualTask6 );
+
+ assertNull( taskQueue.take() );
+ }
+
+ @Test
+ public void testRemoveTask()
+ throws Exception
+ {
+ Task task = new BuildProjectTask( 0 );
+
+ taskQueue.put( task );
+
+ taskQueue.remove( task );
+
+ assertNull( taskQueue.take() );
+ }
+
+ @Test
+ public void testRemoveAll()
+ throws Exception
+ {
+
+ BlockingQueue<String> foo = new LinkedBlockingQueue<String>();
+ foo.offer("1");
+ foo.offer("2");
+
+ Task firstTask = new BuildProjectTask( 110 );
+
+ taskQueue.put( firstTask );
+
+ Task secondTask = new BuildProjectTask( 11120 );
+
+ taskQueue.put( secondTask );
+
+ assertEquals( 2, taskQueue.getQueueSnapshot().size() );
+
+ List tasks = new ArrayList();
+
+ tasks.add( firstTask );
+
+ tasks.add( secondTask );
+
+ taskQueue.removeAll( tasks );
+
+ assertTrue( taskQueue.getQueueSnapshot().isEmpty() );
+ }
+
+ // ----------------------------------------------------------------------
+ //
+ // ----------------------------------------------------------------------
+
+ private void assertTaskIsAccepted( Task expectedTask )
+ throws Exception
+ {
+ taskQueue.put( expectedTask );
+
+ Task actualTask = taskQueue.take();
+
+ assertEquals( expectedTask, actualTask );
+ }
+
+ private void assertTaskIsRejected( Task expectedTask )
+ throws Exception
+ {
+ taskQueue.put( expectedTask );
+
+ Task actualTask = taskQueue.take();
+
+ assertNull( actualTask );
+ }
+}
diff --git a/src/test/java/org/codehaus/plexus/taskqueue/execution/BuildProjectTaskExecutor.java b/src/test/java/org/codehaus/plexus/taskqueue/execution/BuildProjectTaskExecutor.java
new file mode 100644
index 0000000..cd05683
--- /dev/null
+++ b/src/test/java/org/codehaus/plexus/taskqueue/execution/BuildProjectTaskExecutor.java
@@ -0,0 +1,81 @@
+package org.codehaus.plexus.taskqueue.execution;
+
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+
+import org.codehaus.plexus.taskqueue.BuildProjectTask;
+import org.codehaus.plexus.taskqueue.Task;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+/**
+ *
+ * @author <a href="mailto:kenney@apache.org">Kenney Westerhof</a>
+ *
+ */
+@Service("taskExecutor#build-project")
+public class BuildProjectTaskExecutor
+ implements TaskExecutor
+{
+
+ private Logger logger = LoggerFactory.getLogger( getClass() );
+
+ public void executeTask( Task task0 )
+ throws TaskExecutionException
+ {
+ BuildProjectTask task = (BuildProjectTask) task0;
+
+ task.start();
+
+ logger.info( "Task: " + task + " cancelled: " + task.isCancelled() + "; done: " + task.isDone() );
+
+ long time = System.currentTimeMillis();
+
+ long endTime = task.getExecutionTime() + time;
+
+ for ( long timeToSleep = endTime - time; timeToSleep > 0; timeToSleep = endTime - System.currentTimeMillis() )
+ {
+ try
+ {
+ logger.info( "Sleeping " + timeToSleep + "ms (interrupts ignored: " + task.ignoreInterrupts() + ")" );
+ Thread.sleep( timeToSleep );
+
+ task.done();
+
+ logger.info( "Task completed normally: " + task + " cancelled: " + task.isCancelled() + "; done: "
+ + task.isDone() );
+ }
+ catch ( InterruptedException e )
+ {
+ if ( !task.ignoreInterrupts() )
+ {
+ task.cancel();
+
+ logger.info(
+ "Task cancelled: " + task + " cancelled: " + task.isCancelled() + "; done: " + task.isDone() );
+
+ throw new TaskExecutionException( "Never interrupt sleeping threads! :)", e );
+ }
+ else
+ {
+ logger.info( "Ignoring interrupt" );
+ }
+ }
+ }
+
+ }
+}
diff --git a/src/test/java/org/codehaus/plexus/taskqueue/execution/TaskQueueExecutorTest.java b/src/test/java/org/codehaus/plexus/taskqueue/execution/TaskQueueExecutorTest.java
new file mode 100644
index 0000000..ae1ed0c
--- /dev/null
+++ b/src/test/java/org/codehaus/plexus/taskqueue/execution/TaskQueueExecutorTest.java
@@ -0,0 +1,112 @@
+package org.codehaus.plexus.taskqueue.execution;
+
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2004, The Codehaus
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import junit.framework.TestCase;
+import org.codehaus.plexus.taskqueue.BuildProjectTask;
+import org.codehaus.plexus.taskqueue.TaskQueue;
+import org.codehaus.plexus.taskqueue.TaskQueueException;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+/**
+ * @author <a href="mailto:kenney@apache.org">Kenney Westerhof</a>
+ */
+@RunWith( SpringJUnit4ClassRunner.class )
+@ContextConfiguration( locations = { "classpath*:/META-INF/spring-context.xml", "classpath*:/spring-context.xml" } )
+public class TaskQueueExecutorTest
+ extends TestCase
+{
+ @Inject
+ @Named( value = "taskQueue#default" )
+ private TaskQueue taskQueue;
+
+ // inject this to start the executor see @PostConstruct in {@link ThreadedTaskQueueExecutor
+ @Inject
+ @Named( value = "queueExecutor#default" )
+ private TaskQueueExecutor taskQueueExecutor;
+
+
+ @Test
+ public void testTimeoutWithInterrupts()
+ throws TaskQueueException, InterruptedException
+ {
+ BuildProjectTask task = putTask( 2 * 1000, false );
+
+ waitForExpectedTaskEnd( task );
+
+ assertTrue( task.isCancelled() );
+ assertFalse( task.isDone() );
+ }
+
+ @Test
+ public void testTimeoutWithoutInterrupts()
+ throws TaskQueueException, InterruptedException
+ {
+ BuildProjectTask task = putTask( 2 * 1000, true );
+
+ waitForExpectedTaskEnd( task );
+
+ // the thread is killed so the task is neither done nor cancelled
+ assertFalse( task.isCancelled() );
+ assertFalse( task.isDone() );
+ }
+
+ private BuildProjectTask putTask( int executionTime, boolean ignoreInterrupts )
+ throws TaskQueueException
+ {
+ BuildProjectTask task = new BuildProjectTask( 100 );
+ task.setMaxExecutionTime( executionTime );
+ task.setExecutionTime( 10 * executionTime );
+ task.setIgnoreInterrupts( ignoreInterrupts );
+
+ taskQueue.put( task );
+ return task;
+ }
+
+ private static void waitForExpectedTaskEnd( BuildProjectTask task )
+ throws InterruptedException
+ {
+ // thread scheduling may take some time, so we want to wait until the task
+ // is actually running before starting to count the timeout.
+ for ( int i = 0; i < 500; i++ )
+ {
+ if ( task.isStarted() )
+ {
+ break;
+ }
+ Thread.sleep( 10 );
+ }
+
+ assertTrue( "Task not started in 5 seconds - heavy load?", task.isStarted() );
+
+ Thread.sleep( task.getMaxExecutionTime() );
+ }
+}
diff --git a/src/test/resources/spring-context.xml b/src/test/resources/spring-context.xml
new file mode 100644
index 0000000..ad66c03
--- /dev/null
+++ b/src/test/resources/spring-context.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0"?>
+
+<!--
+ ~ 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.
+ -->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+ http://www.springframework.org/schema/context
+ http://www.springframework.org/schema/context/spring-context-3.0.xsd"
+ default-lazy-init="true">
+
+ <bean name="queueExecutor#default" class="org.codehaus.plexus.taskqueue.execution.ThreadedTaskQueueExecutor">
+ <property name="queue" ref="taskQueue#default"/>
+ <property name="executor" ref="taskExecutor#build-project"/>
+ <property name="name" value="default"/>
+ </bean>
+
+ <bean name="queueExecutor#taskQueueTest" class="org.codehaus.plexus.taskqueue.execution.ThreadedTaskQueueExecutor">
+ <property name="queue" ref="taskQueue#taskQueueTest"/>
+ <property name="executor" ref="taskExecutor#build-project"/>
+ <property name="name" value="taskQueueTest"/>
+ </bean>
+
+ <bean abstract="true" name="abstractQueue" class="org.codehaus.plexus.taskqueue.DefaultTaskQueue">
+ <property name="taskEntryEvaluators">
+ <list>
+ <ref bean="taskEntryEvaluator#a"/>
+ <ref bean="taskEntryEvaluator#b"/>
+ </list>
+ </property>
+ <property name="taskExitEvaluators">
+ <list>
+ <ref bean="taskExitEvaluator#a"/>
+ <ref bean="taskExitEvaluator#b"/>
+ </list>
+ </property>
+ <property name="taskViabilityEvaluators">
+ <list>
+ <ref bean="taskViabilityEvaluator#build-project"/>
+ </list>
+ </property>
+ </bean>
+
+ <bean name="taskQueue#default" parent="abstractQueue"/>
+
+ <bean name="taskQueue#taskQueueTest" parent="abstractQueue"/>
+
+</beans>
\ No newline at end of file