You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@continuum.apache.org by oc...@apache.org on 2009/01/13 12:05:10 UTC

svn commit: r734099 [2/3] - in /continuum/trunk: ./ continuum-api/src/main/java/org/apache/continuum/buildmanager/ continuum-api/src/main/java/org/apache/continuum/buildqueue/ continuum-api/src/main/java/org/apache/continuum/configuration/ continuum-ap...

Modified: continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/builddefinition/DefaultBuildDefinitionService.java
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/builddefinition/DefaultBuildDefinitionService.java?rev=734099&r1=734098&r2=734099&view=diff
==============================================================================
--- continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/builddefinition/DefaultBuildDefinitionService.java (original)
+++ continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/builddefinition/DefaultBuildDefinitionService.java Tue Jan 13 03:00:41 2009
@@ -18,6 +18,7 @@
  */
 package org.apache.maven.continuum.builddefinition;
 
+import org.apache.continuum.buildqueue.BuildQueueServiceException;
 import org.apache.continuum.configuration.ContinuumConfigurationException;
 import org.apache.continuum.dao.BuildDefinitionDao;
 import org.apache.continuum.dao.BuildDefinitionTemplateDao;
@@ -430,6 +431,10 @@
         {
             throw new BuildDefinitionServiceException( e.getMessage(), e );
         }
+        catch ( BuildQueueServiceException e )
+        {
+            throw new BuildDefinitionServiceException( e.getMessage(), e );
+        }
     }
 
     // ------------------------------------------------------

Modified: continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/core/action/AbstractContinuumAction.java
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/core/action/AbstractContinuumAction.java?rev=734099&r1=734098&r2=734099&view=diff
==============================================================================
--- continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/core/action/AbstractContinuumAction.java (original)
+++ continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/core/action/AbstractContinuumAction.java Tue Jan 13 03:00:41 2009
@@ -46,6 +46,10 @@
     public static final String KEY_PROJECT_ID = "project-id";
 
     public static final String KEY_PROJECT = "project";
+    
+    public static final String KEY_PROJECTS = "projects";
+    
+    public static final String KEY_PROJECTS_BUILD_DEFINITIONS_MAP = "projects-build-definitions";
 
     public static final String KEY_BUILD_DEFINITION_TEMPLATE = "build-definition-template";
 
@@ -220,6 +224,16 @@
     {
         return getInteger( context, KEY_OLD_BUILD_ID ); 
     }
+    
+    public static List<Project> getListOfProjects( Map context )
+    {
+        return (List<Project>) getObject( context, KEY_PROJECTS );
+    }
+    
+    public static Map<Integer, BuildDefinition> getProjectsBuildDefinitionsMap( Map context )
+    {
+        return (Map<Integer, BuildDefinition>) getObject( context, KEY_PROJECTS_BUILD_DEFINITIONS_MAP );
+    }
 
     // ----------------------------------------------------------------------
     //

Modified: continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/core/action/AddProjectToCheckOutQueueAction.java
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/core/action/AddProjectToCheckOutQueueAction.java?rev=734099&r1=734098&r2=734099&view=diff
==============================================================================
--- continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/core/action/AddProjectToCheckOutQueueAction.java (original)
+++ continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/core/action/AddProjectToCheckOutQueueAction.java Tue Jan 13 03:00:41 2009
@@ -19,10 +19,10 @@
  * under the License.
  */
 
+import org.apache.continuum.buildmanager.BuildsManager;
 import org.apache.continuum.dao.ProjectDao;
-import org.apache.continuum.taskqueue.manager.TaskQueueManager;
+import org.apache.maven.continuum.model.project.BuildDefinition;
 import org.apache.maven.continuum.model.project.Project;
-import org.apache.maven.continuum.scm.queue.CheckOutTask;
 import org.apache.maven.continuum.utils.WorkingDirectoryService;
 
 import java.util.Map;
@@ -45,26 +45,26 @@
      * @plexus.requirement
      */
     private ProjectDao projectDao;
-
+    
     /**
-     * @plexus.requirement
+     * @plexus.requirement role-hint="parallel"
      */
-    private TaskQueueManager taskQueueManager;
+    private BuildsManager parallelBuildsManager;
     
     @SuppressWarnings("unchecked")
     public void execute( Map context )
         throws Exception
     {
-
         Project project = (Project) getObject( context, KEY_PROJECT, null );
         if ( project == null )
         {
             project = projectDao.getProject( getProjectId( context ) );
         }
 
-        CheckOutTask checkOutTask = new CheckOutTask( project.getId(), workingDirectoryService
-            .getWorkingDirectory( project ), project.getName(), project.getScmUsername(), project.getScmPassword() );
-
-        taskQueueManager.getCheckoutQueue().put( checkOutTask );
+        BuildDefinition defaultBuildDefinition = ( BuildDefinition ) getBuildDefinition( context );
+        parallelBuildsManager.checkoutProject( project.getId(), project.getName(),
+                                               workingDirectoryService.getWorkingDirectory( project ),
+                                               project.getScmUsername(), project.getScmPassword(),
+                                               defaultBuildDefinition );
     }
 }

Modified: continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/core/action/CreateBuildProjectTaskAction.java
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/core/action/CreateBuildProjectTaskAction.java?rev=734099&r1=734098&r2=734099&view=diff
==============================================================================
--- continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/core/action/CreateBuildProjectTaskAction.java (original)
+++ continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/core/action/CreateBuildProjectTaskAction.java Tue Jan 13 03:00:41 2009
@@ -19,21 +19,19 @@
  * under the License.
  */
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 
-import org.apache.continuum.dao.BuildDefinitionDao;
+import org.apache.continuum.buildmanager.BuildsManager;
 import org.apache.continuum.dao.ProjectDao;
-import org.apache.continuum.taskqueue.manager.TaskQueueManager;
-import org.apache.maven.continuum.ContinuumException;
-import org.apache.maven.continuum.buildqueue.BuildProjectTask;
 import org.apache.maven.continuum.execution.ContinuumBuildExecutor;
 import org.apache.maven.continuum.execution.manager.BuildExecutorManager;
 import org.apache.maven.continuum.model.project.BuildDefinition;
+import org.apache.maven.continuum.model.project.BuildQueue;
 import org.apache.maven.continuum.model.project.Project;
 import org.apache.maven.continuum.project.ContinuumProjectState;
 import org.apache.maven.continuum.store.ContinuumStoreException;
-import org.codehaus.plexus.taskqueue.TaskQueueException;
-import org.codehaus.plexus.util.StringUtils;
 
 /**
  * @author <a href="mailto:ctan@apache.org">Maria Catherine Tan</a>
@@ -46,103 +44,88 @@
     /**
      * @plexus.requirement
      */
-    private TaskQueueManager taskQueueManager;
-
-    /**
-     * @plexus.requirement
-     */
     private BuildExecutorManager executorManager;
 
     /**
      * @plexus.requirement
      */
     private ProjectDao projectDao;
-
+    
     /**
-     * @plexus.requirement
+     * @plexus.requirement role-hint="parallel"
      */
-    private BuildDefinitionDao buildDefinitionDao;
+    private BuildsManager parallelBuildsManager;
     
     public synchronized void execute( Map context )
         throws Exception
     {
-        Project project = AbstractContinuumAction.getProject( context );
-        int buildDefinitionId = AbstractContinuumAction.getBuildDefinitionId( context );
-        int trigger = AbstractContinuumAction.getTrigger( context );
+        List<Project> projects = AbstractContinuumAction.getListOfProjects( context );
+        Map<Integer, BuildDefinition> projectsBuildDefinitionsMap =
+            AbstractContinuumAction.getProjectsBuildDefinitionsMap( context );
         
-        if ( taskQueueManager.isInBuildingQueue( project.getId(), buildDefinitionId ) )
-        {
-            return;
-        }
-
-        if ( taskQueueManager.isInCheckoutQueue( project.getId() ) )
-        {
-            taskQueueManager.removeProjectFromCheckoutQueue( project.getId() );
-        }
+        List<Project> projectsToBeBuilt = new ArrayList<Project>();
+        int trigger = AbstractContinuumAction.getTrigger( context );
         
-        try
-        {
-            if ( project.getState() != ContinuumProjectState.NEW &&
-                project.getState() != ContinuumProjectState.CHECKEDOUT &&
-                project.getState() != ContinuumProjectState.OK && project.getState() != ContinuumProjectState.FAILED &&
-                project.getState() != ContinuumProjectState.ERROR )
+        // update state of each project first
+        for( Project project : projects )
+        {   
+            BuildDefinition buildDefinition = projectsBuildDefinitionsMap.get( project.getId() );
+            
+            if ( parallelBuildsManager.isInAnyBuildQueue( project.getId(), buildDefinition.getId() ) )
             {
-                ContinuumBuildExecutor executor = executorManager.getBuildExecutor( project.getExecutorId() );
+                return;
+            }
 
-                if ( executor.isBuilding( project ) || project.getState() == ContinuumProjectState.UPDATING )
+            if ( parallelBuildsManager.isInAnyCheckoutQueue( project.getId() ) )
+            {
+                parallelBuildsManager.removeProjectFromCheckoutQueue( project.getId() );
+            }
+            
+            try
+            {
+                if ( project.getState() != ContinuumProjectState.NEW &&
+                    project.getState() != ContinuumProjectState.CHECKEDOUT &&
+                    project.getState() != ContinuumProjectState.OK && project.getState() != ContinuumProjectState.FAILED &&
+                    project.getState() != ContinuumProjectState.ERROR )
                 {
-                    // project is building
-                    getLogger().info( "Project '" + project.getName() + "' already being built." );
+                    ContinuumBuildExecutor executor = executorManager.getBuildExecutor( project.getExecutorId() );
 
-                    return;
+                    if ( executor.isBuilding( project ) || project.getState() == ContinuumProjectState.UPDATING )
+                    {
+                        // project is building
+                        getLogger().info( "Project '" + project.getName() + "' already being built." );
+
+                        continue;
+                    }
+                    else
+                    {
+                        project.setOldState( project.getState() );
+
+                        project.setState( ContinuumProjectState.ERROR );
+
+                        projectDao.updateProject( project );
+
+                        project = projectDao.getProject( project.getId() );
+                    }
                 }
                 else
                 {
                     project.setOldState( project.getState() );
 
-                    project.setState( ContinuumProjectState.ERROR );
-
                     projectDao.updateProject( project );
 
                     project = projectDao.getProject( project.getId() );
                 }
-            }
-            else
-            {
-                project.setOldState( project.getState() );
-
-                projectDao.updateProject( project );
 
-                project = projectDao.getProject( project.getId() );
+                projectsToBeBuilt.add( project );                                
             }
-
-            BuildDefinition buildDefinition = buildDefinitionDao.getBuildDefinition( buildDefinitionId );
-            String buildDefinitionLabel = buildDefinition.getDescription();
-            if ( StringUtils.isEmpty( buildDefinitionLabel ) )
+            catch ( ContinuumStoreException e )
             {
-                buildDefinitionLabel = buildDefinition.getGoals();
+                getLogger().error( "Error while creating build object", e );
+                //throw new ContinuumException( "Error while creating build object.", e );
             }
-
-            getLogger().info( "Enqueuing '" + project.getName() + "' with build definition '" + buildDefinitionLabel +
-                "' - id=" + buildDefinitionId + ")." );
-
-            BuildProjectTask task = new BuildProjectTask( project.getId(), buildDefinitionId, trigger, project
-                .getName(), buildDefinitionLabel );
-
-            task.setMaxExecutionTime( buildDefinition.getSchedule()
-                .getMaxJobExecutionTime() * 1000 );
-
-            taskQueueManager.getBuildQueue().put( task );
-        }
-        catch ( ContinuumStoreException e )
-        {
-            getLogger().error( "Error while creating build object", e );
-            throw new ContinuumException( "Error while creating build object.", e );
-        }
-        catch ( TaskQueueException e )
-        {
-            getLogger().error( "Error while enqueuing object", e );
-            throw new ContinuumException( "Error while enqueuing object.", e );
         }
+        
+        parallelBuildsManager.buildProjects( projectsToBeBuilt, projectsBuildDefinitionsMap, trigger );      
     }
 }

Modified: continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scm/queue/CheckOutTaskExecutor.java
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scm/queue/CheckOutTaskExecutor.java?rev=734099&r1=734098&r2=734099&view=diff
==============================================================================
--- continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scm/queue/CheckOutTaskExecutor.java (original)
+++ continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scm/queue/CheckOutTaskExecutor.java Tue Jan 13 03:00:41 2009
@@ -37,7 +37,7 @@
  * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
  * @version $Id$
  * @plexus.component role="org.codehaus.plexus.taskqueue.execution.TaskExecutor"
- * role-hint="check-out-project"
+ * role-hint="check-out-project" instantiation-strategy="per-lookup"
  */
 public class CheckOutTaskExecutor
     implements TaskExecutor
@@ -61,6 +61,8 @@
     public void executeTask( Task t )
         throws TaskExecutionException
     {
+        log.info( "Checkout task executor.." );
+        
         CheckOutTask task = (CheckOutTask) t;
 
         int projectId = task.getProjectId();

Modified: continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scm/queue/PrepareBuildProjectsTaskExecutor.java
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scm/queue/PrepareBuildProjectsTaskExecutor.java?rev=734099&r1=734098&r2=734099&view=diff
==============================================================================
--- continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scm/queue/PrepareBuildProjectsTaskExecutor.java (original)
+++ continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scm/queue/PrepareBuildProjectsTaskExecutor.java Tue Jan 13 03:00:41 2009
@@ -19,6 +19,7 @@
  * under the License.
  */
 
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -29,6 +30,7 @@
 import org.apache.continuum.dao.ProjectScmRootDao;
 import org.apache.continuum.model.project.ProjectScmRoot;
 import org.apache.maven.continuum.core.action.AbstractContinuumAction;
+import org.apache.maven.continuum.model.project.BuildDefinition;
 import org.apache.maven.continuum.model.project.Project;
 import org.apache.maven.continuum.model.project.ProjectGroup;
 import org.apache.maven.continuum.model.scm.ChangeSet;
@@ -464,54 +466,74 @@
             projectList = projectDao.getAllProjectsByName();
         }
 
+        List<Project> projectsToBeBuilt = new ArrayList<Project>();
+        Map<Integer, BuildDefinition> projectsBuildDefinitionsMap = new HashMap<Integer, BuildDefinition>();
+        
         for ( Project project : projectList )
         {
-            boolean shouldBuild = false;
+            //boolean shouldBuild = false;
             int buildDefinitionId = 0;
             
             if ( projectsAndBuildDefinitionsMap.get( project.getId() ) != null )
             {
-                buildDefinitionId = projectsAndBuildDefinitionsMap.get( project.getId() );
-                shouldBuild = true;
-            }
-            else if ( project.getState() == ContinuumProjectState.CHECKEDOUT || project.getState() == ContinuumProjectState.NEW ) //check if no build result yet for project
-            {
+                buildDefinitionId = projectsAndBuildDefinitionsMap.get( project.getId() );                
+                //shouldBuild = true;         
                 try
                 {
-                    //get default build definition for project
-                    buildDefinitionId = buildDefinitionDao.getDefaultBuildDefinition( project.getId() ).getId();
+                    BuildDefinition buildDefinition = buildDefinitionDao.getBuildDefinition( buildDefinitionId );
+                    projectsBuildDefinitionsMap.put( project.getId(), buildDefinition );
+                    projectsToBeBuilt.add( project );
                 }
-                catch ( ContinuumStoreException e )
+                catch( ContinuumStoreException e )
                 {
                     log.error( "Error while creating build object", e );
                     throw new TaskExecutionException( "Error while creating build object", e );
                 }
-                shouldBuild = true;
             }
-
-            if ( shouldBuild )
+            else if ( project.getState() == ContinuumProjectState.CHECKEDOUT || project.getState() == ContinuumProjectState.NEW ) //check if no build result yet for project
             {
                 try
                 {
-                    Map context = new HashMap();
-                    context.put( AbstractContinuumAction.KEY_PROJECT, project );
-                    context.put( AbstractContinuumAction.KEY_BUILD_DEFINITION_ID, buildDefinitionId );
-                    context.put( AbstractContinuumAction.KEY_TRIGGER, trigger );
-                    
-                    log.info( "Performing action create-build-project-task" );
-                    actionManager.lookup( "create-build-project-task" ).execute( context );
+                    //get default build definition for project
+                    //buildDefinitionId = buildDefinitionDao.getDefaultBuildDefinition( project.getId() ).getId();
+                    BuildDefinition buildDefinition = buildDefinitionDao.getDefaultBuildDefinition( project.getId() );
+                    projectsBuildDefinitionsMap.put( project.getId(), buildDefinition );
+                    projectsToBeBuilt.add( project );
                 }
-                catch ( ActionNotFoundException e )
+                catch ( ContinuumStoreException e )
                 {
-                   log.error( "Error looking up action 'build-project'" );
-                   throw new TaskExecutionException( "Error looking up action 'build-project'", e );
+                    log.error( "Error while creating build object", e );
+                    throw new TaskExecutionException( "Error while creating build object", e );
                 }
                 catch ( Exception e )
                 {
                     log.error( e.getMessage(), e );
                     throw new TaskExecutionException( "Error executing action 'build-project'", e );
                 }
+                //shouldBuild = true;
+                projectsToBeBuilt.add( project );
             }
         }
+        
+        try
+        {
+            Map context = new HashMap();
+            context.put( AbstractContinuumAction.KEY_PROJECTS, projectsToBeBuilt );
+            context.put( AbstractContinuumAction.KEY_PROJECTS_BUILD_DEFINITIONS_MAP, projectsBuildDefinitionsMap );
+            context.put( AbstractContinuumAction.KEY_TRIGGER, trigger );
+            
+            log.info( "Performing action create-build-project-task" );
+            actionManager.lookup( "create-build-project-task" ).execute( context );
+        }
+        catch ( ActionNotFoundException e )
+        {
+           log.error( "Error looking up action 'build-project'" );
+           throw new TaskExecutionException( "Error looking up action 'build-project'", e );
+        }
+        catch ( Exception e )
+        {
+            log.error( e.getMessage(), e );
+            throw new TaskExecutionException( "Error executing action 'build-project'", e );
+        }
     }
 }

Modified: continuum/trunk/continuum-core/src/main/resources/META-INF/plexus/components.xml
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-core/src/main/resources/META-INF/plexus/components.xml?rev=734099&r1=734098&r2=734099&view=diff
==============================================================================
--- continuum/trunk/continuum-core/src/main/resources/META-INF/plexus/components.xml (original)
+++ continuum/trunk/continuum-core/src/main/resources/META-INF/plexus/components.xml Tue Jan 13 03:00:41 2009
@@ -19,7 +19,7 @@
 
 <component-set>
   <components>
-
+    
     <!--
      |
      | Build Project Task Queue
@@ -30,6 +30,7 @@
       <role>org.codehaus.plexus.taskqueue.TaskQueue</role>
       <role-hint>build-project</role-hint>
       <implementation>org.codehaus.plexus.taskqueue.DefaultTaskQueue</implementation>
+      <instantiation-strategy>per-lookup</instantiation-strategy>
       <lifecycle-handler>plexus-configurable</lifecycle-handler>
       <configuration>
         <task-entry-evaluators>
@@ -45,6 +46,7 @@
     <component>
       <role>org.codehaus.plexus.taskqueue.TaskViabilityEvaluator</role>
       <role-hint>build-project</role-hint>
+      <instantiation-strategy>per-lookup</instantiation-strategy>
       <implementation>
         org.apache.maven.continuum.buildqueue.evaluator.BuildProjectTaskViabilityEvaluator</implementation>
       <configuration>
@@ -55,22 +57,25 @@
     <component>
       <role>org.codehaus.plexus.taskqueue.execution.TaskExecutor</role>
       <role-hint>build-project</role-hint>
+      <instantiation-strategy>per-lookup</instantiation-strategy>
       <implementation>org.apache.maven.continuum.buildcontroller.BuildProjectTaskExecutor</implementation>
       <requirements>
         <requirement>
           <role>org.apache.maven.continuum.buildcontroller.BuildController</role>
         </requirement>
+        <!-- 
         <requirement>
           <role>org.apache.continuum.taskqueue.manager.TaskQueueManager</role>
         </requirement>
+         -->
       </requirements>
     </component>
 
     <component>
       <role>org.codehaus.plexus.taskqueue.execution.TaskQueueExecutor</role>
       <role-hint>build-project</role-hint>
-      <implementation>org.codehaus.plexus.taskqueue.execution.ThreadedTaskQueueExecutor</implementation>
-      <instantiation-strategy>singleton</instantiation-strategy>
+      <instantiation-strategy>per-lookup</instantiation-strategy>
+      <implementation>org.apache.continuum.taskqueueexecutor.ParallelBuildsThreadedTaskQueueExecutor</implementation>      
       <requirements>
         <requirement>
           <role>org.codehaus.plexus.taskqueue.execution.TaskExecutor</role>
@@ -97,14 +102,15 @@
       <role-hint>check-out-project</role-hint>
       <implementation>org.codehaus.plexus.taskqueue.DefaultTaskQueue</implementation>
       <lifecycle-handler>plexus-configurable</lifecycle-handler>
+      <instantiation-strategy>per-lookup</instantiation-strategy>
     </component>
 
 
     <component>
       <role>org.codehaus.plexus.taskqueue.execution.TaskQueueExecutor</role>
       <role-hint>check-out-project</role-hint>
-      <implementation>org.codehaus.plexus.taskqueue.execution.ThreadedTaskQueueExecutor</implementation>
-      <instantiation-strategy>singleton</instantiation-strategy>
+      <implementation>org.apache.continuum.taskqueueexecutor.ParallelBuildsThreadedTaskQueueExecutor</implementation>
+      <instantiation-strategy>per-lookup</instantiation-strategy>
       <requirements>
         <requirement>
           <role>org.codehaus.plexus.taskqueue.execution.TaskExecutor</role>
@@ -132,6 +138,7 @@
       <role-hint>prepare-build-project</role-hint>
       <implementation>org.codehaus.plexus.taskqueue.DefaultTaskQueue</implementation>
       <lifecycle-handler>plexus-configurable</lifecycle-handler>
+      <instantiation-strategy>singleton</instantiation-strategy>
     </component>
     
     <component>

Modified: continuum/trunk/continuum-core/src/main/resources/META-INF/spring-context.xml
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-core/src/main/resources/META-INF/spring-context.xml?rev=734099&r1=734098&r2=734099&view=diff
==============================================================================
--- continuum/trunk/continuum-core/src/main/resources/META-INF/spring-context.xml (original)
+++ continuum/trunk/continuum-core/src/main/resources/META-INF/spring-context.xml Tue Jan 13 03:00:41 2009
@@ -33,4 +33,14 @@
     </property>
   </bean>
   
+  <bean name="buildsManager#parallel" 
+  		class="org.apache.continuum.buildmanager.ParallelBuildsManager" autowire="byName">
+     <property name="prepareBuildQueue" ref="taskQueue#prepare-build-project"/>
+  </bean>
+    
+  <bean name="overallBuildQueue" 
+  		class="org.apache.continuum.taskqueue.DefaultOverallBuildQueue" scope="prototype" autowire="byName">
+     <property name="buildTaskQueueExecutor" ref="taskQueueExecutor#build-project"/>
+     <property name="checkoutTaskQueueExecutor" ref="taskQueueExecutor#check-out-project"/>
+  </bean>
 </beans>

Added: continuum/trunk/continuum-core/src/test/java/org/apache/continuum/taskqueue/DefaultOverallBuildQueueTest.java
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-core/src/test/java/org/apache/continuum/taskqueue/DefaultOverallBuildQueueTest.java?rev=734099&view=auto
==============================================================================
--- continuum/trunk/continuum-core/src/test/java/org/apache/continuum/taskqueue/DefaultOverallBuildQueueTest.java (added)
+++ continuum/trunk/continuum-core/src/test/java/org/apache/continuum/taskqueue/DefaultOverallBuildQueueTest.java Tue Jan 13 03:00:41 2009
@@ -0,0 +1,347 @@
+package org.apache.continuum.taskqueue;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.continuum.dao.BuildDefinitionDao;
+import org.apache.continuum.taskqueueexecutor.ParallelBuildsThreadedTaskQueueExecutor;
+import org.apache.maven.continuum.buildqueue.BuildProjectTask;
+import org.apache.maven.continuum.model.project.BuildDefinition;
+import org.apache.maven.continuum.scm.queue.CheckOutTask;
+import org.codehaus.plexus.spring.PlexusInSpringTestCase;
+import org.codehaus.plexus.taskqueue.Task;
+import org.codehaus.plexus.taskqueue.TaskQueue;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.jmock.integration.junit3.JUnit3Mockery;
+import org.jmock.lib.legacy.ClassImposteriser;
+
+/**
+ * DefaultOverallBuildQueueTest
+ * 
+ * @author <a href="mailto:oching@apache.org">Maria Odea Ching</a>
+ *
+ */
+public class DefaultOverallBuildQueueTest
+    extends PlexusInSpringTestCase
+{
+    private DefaultOverallBuildQueue overallQueue;
+
+    private Mockery context;
+
+    private BuildDefinitionDao buildDefinitionDao;
+
+    private ParallelBuildsThreadedTaskQueueExecutor buildTaskQueueExecutor;
+
+    private ParallelBuildsThreadedTaskQueueExecutor checkoutTaskQueueExecutor;
+
+    @Override
+    protected void setUp()
+        throws Exception
+    {
+        super.setUp();
+
+        overallQueue = new DefaultOverallBuildQueue();
+
+        context = new JUnit3Mockery();
+
+        buildDefinitionDao = context.mock( BuildDefinitionDao.class );
+        context.setImposteriser( ClassImposteriser.INSTANCE );
+
+        buildTaskQueueExecutor = context.mock( ParallelBuildsThreadedTaskQueueExecutor.class, "build-queue-executor" );
+
+        checkoutTaskQueueExecutor =
+            context.mock( ParallelBuildsThreadedTaskQueueExecutor.class, "checkout-queue-executor" );
+
+        overallQueue.setBuildDefinitionDao( buildDefinitionDao );
+
+        overallQueue.setBuildTaskQueueExecutor( buildTaskQueueExecutor );
+
+        overallQueue.setCheckoutTaskQueueExecutor( checkoutTaskQueueExecutor );
+    }
+
+    // checkout queue
+
+    public void testAddToCheckoutQueue()
+        throws Exception
+    {
+        final Task checkoutTask =
+            new CheckOutTask( 1, new File( getBasedir(), "/target/test-working-dir/1" ), "continuum-project-test-1",
+                              "dummy", "dummypass" );
+        final TaskQueue checkoutQueue = context.mock( TaskQueue.class, "checkout-queue" );
+
+        context.checking( new Expectations()
+        {
+            {
+                one( checkoutTaskQueueExecutor ).getQueue();
+                will( returnValue( checkoutQueue ) );
+
+                one( checkoutQueue ).put( checkoutTask );
+            }
+        } );
+
+        overallQueue.addToCheckoutQueue( checkoutTask );
+        context.assertIsSatisfied();
+    }
+
+    public void testGetProjectsInCheckoutQueue()
+        throws Exception
+    {
+        final TaskQueue checkoutQueue = context.mock( TaskQueue.class, "checkout-queue" );
+        final List<Task> tasks = new ArrayList<Task>();
+        tasks.add( new CheckOutTask( 1, new File( getBasedir(), "/target/test-working-dir/1" ),
+                                     "continuum-project-test-1", "dummy", "dummypass" ) );
+
+        context.checking( new Expectations()
+        {
+            {
+                one( checkoutTaskQueueExecutor ).getQueue();
+                will( returnValue( checkoutQueue ) );
+
+                one( checkoutQueue ).getQueueSnapshot();
+                will( returnValue( tasks ) );
+            }
+        } );
+
+        List<CheckOutTask> returnedTasks = overallQueue.getProjectsInCheckoutQueue();
+        context.assertIsSatisfied();
+
+        assertNotNull( returnedTasks );
+        assertEquals( 1, returnedTasks.size() );
+    }
+
+    public void testIsInCheckoutQueue()
+        throws Exception
+    {
+        final TaskQueue checkoutQueue = context.mock( TaskQueue.class, "checkout-queue" );
+        final List<Task> tasks = new ArrayList<Task>();
+        tasks.add( new CheckOutTask( 1, new File( getBasedir(), "/target/test-working-dir/1" ),
+                                     "continuum-project-test-1", "dummy", "dummypass" ) );
+
+        context.checking( new Expectations()
+        {
+            {
+                one( checkoutTaskQueueExecutor ).getQueue();
+                will( returnValue( checkoutQueue ) );
+
+                one( checkoutQueue ).getQueueSnapshot();
+                will( returnValue( tasks ) );
+            }
+        } );
+
+        assertTrue( overallQueue.isInCheckoutQueue( 1 ) );
+        context.assertIsSatisfied();
+    }
+
+    public void testRemoveProjectFromCheckoutQueue()
+        throws Exception
+    {
+        final Task checkoutTask =
+            new CheckOutTask( 1, new File( getBasedir(), "/target/test-working-dir/1" ), "continuum-project-test-1",
+                              "dummy", "dummypass" );
+        final TaskQueue checkoutQueue = context.mock( TaskQueue.class, "checkout-queue" );
+        final List<Task> tasks = new ArrayList<Task>();
+        tasks.add( checkoutTask );
+
+        context.checking( new Expectations()
+        {
+            {
+                one( checkoutTaskQueueExecutor ).getQueue();
+                will( returnValue( checkoutQueue ) );
+
+                one( checkoutQueue ).getQueueSnapshot();
+                will( returnValue( tasks ) );
+
+                one( checkoutTaskQueueExecutor ).getQueue();
+                will( returnValue( checkoutQueue ) );
+
+                one( checkoutQueue ).remove( checkoutTask );
+            }
+        } );
+
+        overallQueue.removeProjectFromCheckoutQueue( 1 );
+        context.assertIsSatisfied();
+    }
+
+    // build queue
+
+    public void testAddToBuildQueue()
+        throws Exception
+    {
+        final Task buildTask = new BuildProjectTask( 2, 1, 1, "continuum-project-test-2", "BUILD_DEF" );
+        final TaskQueue buildQueue = context.mock( TaskQueue.class, "build-queue" );
+
+        context.checking( new Expectations()
+        {
+            {
+                one( buildTaskQueueExecutor ).getQueue();
+                will( returnValue( buildQueue ) );
+
+                one( buildQueue ).put( buildTask );
+            }
+        } );
+
+        overallQueue.addToBuildQueue( buildTask );
+        context.assertIsSatisfied();
+    }
+
+    public void testGetProjectsFromBuildQueue()
+        throws Exception
+    {
+        final TaskQueue buildQueue = context.mock( TaskQueue.class, "build-queue" );
+        final List<Task> tasks = new ArrayList<Task>();
+        tasks.add( new BuildProjectTask( 2, 1, 1, "continuum-project-test-2", "BUILD_DEF" ) );
+
+        context.checking( new Expectations()
+        {
+            {
+                one( buildTaskQueueExecutor ).getQueue();
+                will( returnValue( buildQueue ) );
+
+                one( buildQueue ).getQueueSnapshot();
+                will( returnValue( tasks ) );
+            }
+        } );
+
+        List<Task> returnedTasks = overallQueue.getProjectsInBuildQueue();
+        context.assertIsSatisfied();
+
+        assertNotNull( returnedTasks );
+        assertEquals( 1, returnedTasks.size() );
+    }
+
+    public void testIsInBuildQueue()
+        throws Exception
+    {
+        final TaskQueue buildQueue = context.mock( TaskQueue.class, "build-queue" );
+        final List<Task> tasks = new ArrayList<Task>();
+        tasks.add( new BuildProjectTask( 2, 1, 1, "continuum-project-test-2", "BUILD_DEF" ) );
+
+        context.checking( new Expectations()
+        {
+            {
+                one( buildTaskQueueExecutor ).getQueue();
+                will( returnValue( buildQueue ) );
+
+                one( buildQueue ).getQueueSnapshot();
+                will( returnValue( tasks ) );
+            }
+        } );
+
+        assertTrue( overallQueue.isInBuildQueue( 2 ) );
+        context.assertIsSatisfied();
+    }
+
+    public void testCancelBuildTask()
+        throws Exception
+    {
+        final Task buildTask = new BuildProjectTask( 2, 1, 1, "continuum-project-test-2", "BUILD_DEF" );
+
+        context.checking( new Expectations()
+        {
+            {
+                one( buildTaskQueueExecutor ).getCurrentTask();
+                will( returnValue( buildTask ) );
+
+                one( buildTaskQueueExecutor ).cancelTask( buildTask );
+            }
+        } );
+
+        overallQueue.cancelBuildTask( 2 );
+        context.assertIsSatisfied();
+    }
+
+    public void testCancelCurrentBuild()
+        throws Exception
+    {
+        final Task buildTask = new BuildProjectTask( 2, 1, 1, "continuum-project-test-2", "BUILD_DEF" );
+
+        context.checking( new Expectations()
+        {
+            {
+                one( buildTaskQueueExecutor ).getCurrentTask();
+                will( returnValue( buildTask ) );
+
+                one( buildTaskQueueExecutor ).cancelTask( buildTask );
+            }
+        } );
+
+        overallQueue.cancelCurrentBuild();
+        context.assertIsSatisfied();
+    }
+
+    public void testRemoveProjectFromBuildQueueWithGivenBuildDefinition()
+        throws Exception
+    {
+        final BuildDefinition buildDef = new BuildDefinition();
+        buildDef.setId( 1 );
+        buildDef.setDescription( "Test build definition" );
+
+        final TaskQueue buildQueue = context.mock( TaskQueue.class, "build-queue" );
+
+        context.checking( new Expectations()
+        {
+            {
+                one( buildDefinitionDao ).getBuildDefinition( 1 );
+                will( returnValue( buildDef ) );
+
+                one( buildTaskQueueExecutor ).getQueue();
+                will( returnValue( buildQueue ) );
+
+                one( buildQueue ).remove( with( any( Task.class ) ) );
+            }
+        } );
+
+        overallQueue.removeProjectFromBuildQueue( 1, 1, 1, "continuum-project-test-1" );
+        context.assertIsSatisfied();
+    }
+
+    public void testRemoveProjectFromBuildQueue()
+        throws Exception
+    {
+        final Task buildTask = new BuildProjectTask( 1, 1, 1, "continuum-project-test-2", "BUILD_DEF" );
+
+        final TaskQueue buildQueue = context.mock( TaskQueue.class, "build-queue" );
+        final List<Task> tasks = new ArrayList<Task>();
+        tasks.add( buildTask );
+
+        context.checking( new Expectations()
+        {
+            {
+                one( buildTaskQueueExecutor ).getQueue();
+                will( returnValue( buildQueue ) );
+
+                one( buildQueue ).getQueueSnapshot();
+                will( returnValue( tasks ) );
+
+                one( buildTaskQueueExecutor ).getQueue();
+                will( returnValue( buildQueue ) );
+
+                one( buildQueue ).remove( buildTask );
+            }
+        } );
+
+        overallQueue.removeProjectFromBuildQueue( 1 );
+        context.assertIsSatisfied();
+    }
+}

Modified: continuum/trunk/continuum-core/src/test/java/org/apache/maven/continuum/DefaultContinuumTest.java
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-core/src/test/java/org/apache/maven/continuum/DefaultContinuumTest.java?rev=734099&r1=734098&r2=734099&view=diff
==============================================================================
--- continuum/trunk/continuum-core/src/test/java/org/apache/maven/continuum/DefaultContinuumTest.java (original)
+++ continuum/trunk/continuum-core/src/test/java/org/apache/maven/continuum/DefaultContinuumTest.java Tue Jan 13 03:00:41 2009
@@ -20,12 +20,15 @@
  */
 
 import java.io.File;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.continuum.buildmanager.BuildsManager;
+import org.apache.continuum.dao.ProjectDao;
 import org.apache.continuum.model.release.ContinuumReleaseResult;
 import org.apache.continuum.model.repository.LocalRepository;
 import org.apache.continuum.repository.RepositoryService;
@@ -39,8 +42,9 @@
 import org.apache.maven.continuum.model.project.ProjectNotifier;
 import org.apache.maven.continuum.project.builder.ContinuumProjectBuildingResult;
 import org.apache.maven.continuum.utils.ContinuumUrlValidator;
-import org.codehaus.plexus.taskqueue.TaskQueue;
-import org.codehaus.plexus.taskqueue.execution.TaskQueueExecutor;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.jmock.integration.junit3.JUnit3Mockery;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -53,24 +57,31 @@
 {
     protected Logger log = LoggerFactory.getLogger( getClass() );
     
-    public void testContinuumConfiguration()
+    private Mockery context;
+    
+    private TaskQueueManager taskQueueManager;
+    
+    private ProjectDao projectDao;
+    
+    @Override
+    protected void setUp()
         throws Exception
     {
-        lookup( Continuum.ROLE );
+        super.setUp();
+        
+        context = new JUnit3Mockery();
+        
+        taskQueueManager = context.mock( TaskQueueManager.class );
+        
+        projectDao = context.mock( ProjectDao.class );
     }
-
-    public void testLookups()
+    
+    public void testContinuumConfiguration()
         throws Exception
     {
-        lookup( TaskQueue.ROLE, "build-project" );
-
-        lookup( TaskQueue.ROLE, "check-out-project" );
-
-        lookup( TaskQueueExecutor.ROLE, "build-project" );
-
-        lookup( TaskQueueExecutor.ROLE, "check-out-project" );
+        lookup( Continuum.ROLE );
     }
-
+    
     public void testAddMavenTwoProjectSet()
         throws Exception
     {
@@ -275,7 +286,24 @@
         projectGroup = (ProjectGroup) projectGroupList.iterator().next();
 
         assertNotNull( projectGroup );
-
+        
+        BuildsManager buildsManager = continuum.getBuildsManager();
+        
+        List<Project> projects = projectGroup.getProjects();
+        int[] projectIds = new int[ projects.size() ];
+        
+        int idx = 0;
+        for( Project project : projects )
+        {
+            projectIds[ idx ] = project.getId();
+            idx++;
+        }
+        
+        while( buildsManager.isAnyProjectCurrentlyBeingCheckedOut( projectIds ) )
+        {
+            continue;
+        }
+        
         continuum.removeProjectGroup( projectGroup.getId() );
 
         projectGroupList = continuum.getAllProjectGroupsWithProjects();
@@ -353,9 +381,9 @@
         throws Exception
     {
         Continuum continuum = (Continuum) lookup( Continuum.ROLE );
-
-        TaskQueueManager taskQueueManager = (TaskQueueManager) lookup( TaskQueueManager.ROLE );
-
+        
+        BuildsManager parallelBuildsManager = continuum.getBuildsManager();
+        
         String url = getTestFile( "src/test-projects/project1/pom.xml" ).toURL().toExternalForm();
 
         ContinuumProjectBuildingResult result = continuum.addMavenTwoProject( url );
@@ -369,12 +397,11 @@
         assertEquals( Project.class, projects.get( 0 ).getClass() );
 
         Project project = (Project) projects.get( 0 );
-
-        assertTrue( "project missing from the checkout queue",
-                    taskQueueManager.removeProjectFromCheckoutQueue( project.getId() ) );
-
+        
+        parallelBuildsManager.removeProjectFromCheckoutQueue( project.getId() );
+        
         assertFalse( "project still exist on the checkout queue",
-                     taskQueueManager.removeProjectFromCheckoutQueue( project.getId() ) );
+                     parallelBuildsManager.isInAnyCheckoutQueue( project.getId() ) );
     }
 
     public void testAddAntProjectWithdefaultBuildDef()
@@ -478,11 +505,94 @@
         
     }
     
+    public void testBuildProjectWhileProjectIsInReleaseStage()
+        throws Exception
+    {
+        DefaultContinuum continuum = ( DefaultContinuum ) getContinuum();
+        
+        continuum.setTaskQueueManager( taskQueueManager );
+        
+        continuum.setProjectDao( projectDao );
+        
+        final Project project = new Project();
+        project.setId( 1 );
+        project.setName( "Continuum Core" );
+        project.setGroupId( "org.apache.continuum" );
+        project.setArtifactId( "continuum-core" );
+        
+        context.checking( new Expectations()
+        {
+            {                
+                one( projectDao ).getProject( 1 );
+                will( returnValue( project ) );
+                
+                one( taskQueueManager ).isProjectInReleaseStage( "org.apache.continuum:continuum-core" );
+                will( returnValue( true ) );
+            }
+        });
+        
+        try
+        {
+            continuum.buildProject( 1 );
+            fail( "An exception should have been thrown." );
+        }
+        catch ( ContinuumException e )
+        {
+            assertEquals( "Project (id=1) is currently in release stage.", e.getMessage() );
+        }
+    }
+        
+    public void testBuildProjectGroupWhileAtLeastOneProjectIsInReleaseStage()
+        throws Exception
+    {
+        DefaultContinuum continuum = ( DefaultContinuum ) getContinuum();
+        
+        continuum.setTaskQueueManager( taskQueueManager );
+        
+        continuum.setProjectDao( projectDao );
+        
+        final List<Project> projects = new ArrayList<Project>();
+        
+        Project project = new Project();
+        project.setId( 1 );
+        project.setName( "Continuum Core" );
+        project.setGroupId( "org.apache.continuum" );
+        project.setArtifactId( "continuum-core" );
+        projects.add( project );
+        
+        project = new Project();
+        project.setId( 2 );
+        project.setName( "Continuum API" );
+        project.setGroupId( "org.apache.continuum" );
+        project.setArtifactId( "continuum-api" );
+        projects.add( project );
+        
+        context.checking( new Expectations()  
+        {
+            {
+                one( projectDao ).getProjectsInGroup( 1 );
+                will( returnValue( projects ) );
+                
+                one( taskQueueManager ).isProjectInReleaseStage( "org.apache.continuum:continuum-core" );
+                will( returnValue( true ) );
+            }
+        });
+        
+        try
+        {
+            continuum.buildProjectGroup( 1 );
+            fail( "An exception should have been thrown." );
+        }
+        catch ( ContinuumException e )
+        {
+            assertEquals( "Cannot build project group. Project (id=1) in group is currently in release stage.",
+                          e.getMessage() );
+        }
+    }
+    
     private Continuum getContinuum()
         throws Exception
     {
         return (Continuum) lookup( Continuum.ROLE );
     }
-
-
 }

Modified: continuum/trunk/continuum-docs/src/site/apt/administrator_guides/index.apt
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-docs/src/site/apt/administrator_guides/index.apt?rev=734099&r1=734098&r2=734099&view=diff
==============================================================================
--- continuum/trunk/continuum-docs/src/site/apt/administrator_guides/index.apt (original)
+++ continuum/trunk/continuum-docs/src/site/apt/administrator_guides/index.apt Tue Jan 13 03:00:41 2009
@@ -26,6 +26,8 @@
 
  * {{{purgeConfiguration.html}Managing Purge Configuration}}
 
+ * {{{parallelBuilds.html}Managing Parallel Build Queue}}
+
  * {{{external-db.html}External Databases}}
 
  * {{{monitoring.html}Monitoring Continuum}}

Modified: continuum/trunk/continuum-docs/src/site/site.xml
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-docs/src/site/site.xml?rev=734099&r1=734098&r2=734099&view=diff
==============================================================================
--- continuum/trunk/continuum-docs/src/site/site.xml (original)
+++ continuum/trunk/continuum-docs/src/site/site.xml Tue Jan 13 03:00:41 2009
@@ -79,6 +79,7 @@
         <item name="Managing General Configuration" href="administrator_guides/configuration.html"/> <!-- (configuration and appearance) -->
         <item name="Managing Local Repositories" href="administrator_guides/localRepository.html"/>
         <item name="Managing Purge Configuration" href="administrator_guides/purgeConfiguration.html"/>
+        <item name="Managing Parallel Build Queue" href="administrator_guides/parallelBuilds.html"/>
         <item name="External databases" href="administrator_guides/external-db.html"/>
         <item name="Monitoring Continuum" href="administrator_guides/monitoring.html"/>
         <item name="Appearance Configuration" href="administrator_guides/appearance.html"/>

Modified: continuum/trunk/continuum-model/pom.xml
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-model/pom.xml?rev=734099&r1=734098&r2=734099&view=diff
==============================================================================
--- continuum/trunk/continuum-model/pom.xml (original)
+++ continuum/trunk/continuum-model/pom.xml Tue Jan 13 03:00:41 2009
@@ -63,7 +63,7 @@
           </execution>
         </executions>
         <configuration>
-          <version>1.1.3</version>
+          <version>1.1.4</version>
           <packageWithVersion>false</packageWithVersion>
           <model>src/main/mdo/continuum.xml</model>
         </configuration>

Modified: continuum/trunk/continuum-model/src/main/mdo/continuum.xml
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-model/src/main/mdo/continuum.xml?rev=734099&r1=734098&r2=734099&view=diff
==============================================================================
--- continuum/trunk/continuum-model/src/main/mdo/continuum.xml (original)
+++ continuum/trunk/continuum-model/src/main/mdo/continuum.xml Tue Jan 13 03:00:41 2009
@@ -1030,6 +1030,27 @@
       </fields>
     </class>
     <class>
+      <name>BuildQueue</name>
+      <version>1.1.4+</version>    
+      <description><![CDATA[
+       Build queue.
+      ]]></description>
+      <fields>
+        <field>
+          <name>id</name>
+          <version>1.1.4+</version>
+          <identifier>true</identifier>
+          <type>int</type>
+        </field>
+        <field>
+          <name>name</name>
+          <version>1.1.4+</version>
+          <type>String</type>
+          <required>true</required>
+        </field>        
+      </fields>
+    </class>    
+    <class>
       <name>Schedule</name>
       <version>1.0.9+</version>
       <description><![CDATA[
@@ -1088,6 +1109,14 @@
           <version>1.0.9+</version>
           <type>String</type>
         </field>
+        <field jpox.fetch-groups="schedule-build-queues">
+          <name>buildQueues</name>
+          <version>1.1.4+</version>
+          <association xml.reference="true" stash.part="true" jpox.dependent="false">
+            <type>BuildQueue</type>
+            <multiplicity>*</multiplicity>
+          </association>
+        </field>
       </fields>
     </class>
 
@@ -1244,6 +1273,12 @@
           <type>String</type>
           <defaultValue>release-output-directory</defaultValue>
         </field>
+        <field>
+          <name>numberOfBuildsInParallel</name>
+          <version>1.1.4+</version>
+          <type>int</type>
+          <defaultValue>1</defaultValue>
+        </field>
       </fields>
     </class>
 
@@ -1593,7 +1628,6 @@
           <required>true</required>
         </field>
       </fields>
-    </class>
-    
+    </class>    
   </classes>
 </model>

Modified: continuum/trunk/continuum-test/src/main/java/org/apache/maven/continuum/configuration/ConfigurationServiceMock.java
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-test/src/main/java/org/apache/maven/continuum/configuration/ConfigurationServiceMock.java?rev=734099&r1=734098&r2=734099&view=diff
==============================================================================
--- continuum/trunk/continuum-test/src/main/java/org/apache/maven/continuum/configuration/ConfigurationServiceMock.java (original)
+++ continuum/trunk/continuum-test/src/main/java/org/apache/maven/continuum/configuration/ConfigurationServiceMock.java Tue Jan 13 03:00:41 2009
@@ -19,6 +19,8 @@
  * under the License.
  */
 
+import org.apache.continuum.buildqueue.BuildQueueServiceException;
+import org.apache.maven.continuum.model.project.BuildQueue;
 import org.apache.maven.continuum.model.project.Schedule;
 import org.apache.maven.continuum.store.ContinuumStoreException;
 
@@ -188,6 +190,12 @@
     {
     }
 
+    public BuildQueue getDefaultBuildQueue()
+        throws BuildQueueServiceException
+    {
+        return null;
+    }
+    
     public Schedule getDefaultSchedule()
         throws ContinuumStoreException
     {
@@ -240,4 +248,13 @@
         return null;
     }
 
+    public int getNumberOfBuildsInParallel()
+    {
+        return 1;
+    }
+    
+    public void setNumberOfBuildsInParallel( int num )
+    {
+        
+    }
 }

Modified: continuum/trunk/continuum-webapp/pom.xml
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-webapp/pom.xml?rev=734099&r1=734098&r2=734099&view=diff
==============================================================================
--- continuum/trunk/continuum-webapp/pom.xml (original)
+++ continuum/trunk/continuum-webapp/pom.xml Tue Jan 13 03:00:41 2009
@@ -319,6 +319,10 @@
   </build>
   <dependencies>
     <dependency>
+      <groupId>org.apache.continuum</groupId>
+      <artifactId>continuum-store</artifactId>
+    </dependency>
+    <dependency>
       <groupId>org.codehaus.plexus.registry</groupId>
       <artifactId>plexus-registry-api</artifactId>
     </dependency>

Modified: continuum/trunk/continuum-webapp/src/main/java/org/apache/continuum/web/startup/ContinuumStartup.java
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-webapp/src/main/java/org/apache/continuum/web/startup/ContinuumStartup.java?rev=734099&r1=734098&r2=734099&view=diff
==============================================================================
--- continuum/trunk/continuum-webapp/src/main/java/org/apache/continuum/web/startup/ContinuumStartup.java (original)
+++ continuum/trunk/continuum-webapp/src/main/java/org/apache/continuum/web/startup/ContinuumStartup.java Tue Jan 13 03:00:41 2009
@@ -1,3 +1,5 @@
+package org.apache.continuum.web.startup;
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -16,13 +18,12 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.continuum.web.startup;
 
 import javax.servlet.ServletContextEvent;
 import javax.servlet.ServletContextListener;
 
+import org.apache.continuum.buildmanager.BuildsManager;
 import org.apache.maven.continuum.Continuum;
-import org.apache.maven.continuum.ContinuumException;
 import org.codehaus.plexus.spring.PlexusToSpringUtils;
 import org.codehaus.plexus.taskqueue.execution.TaskQueueExecutor;
 import org.slf4j.Logger;
@@ -60,12 +61,8 @@
 
         // to simulate Plexus load on start with Spring
         Continuum continuum = (Continuum) wac.getBean( PlexusToSpringUtils.buildSpringId( Continuum.class ) );
-
-        TaskQueueExecutor buildProject = (TaskQueueExecutor) wac.getBean( PlexusToSpringUtils
-            .buildSpringId( TaskQueueExecutor.class, "build-project" ) );
-
-        TaskQueueExecutor checkOutProject = (TaskQueueExecutor) wac.getBean( PlexusToSpringUtils
-            .buildSpringId( TaskQueueExecutor.class, "check-out-project" ) );
+        
+        BuildsManager buildsManager = (BuildsManager) wac.getBean( PlexusToSpringUtils.buildSpringId( BuildsManager.class, "parallel" ) );
 
         TaskQueueExecutor prepareRelease = (TaskQueueExecutor) wac.getBean( PlexusToSpringUtils
             .buildSpringId( TaskQueueExecutor.class, "prepare-release" ) );

Modified: continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/AbstractBuildAction.java
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/AbstractBuildAction.java?rev=734099&r1=734098&r2=734099&view=diff
==============================================================================
--- continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/AbstractBuildAction.java (original)
+++ continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/AbstractBuildAction.java Tue Jan 13 03:00:41 2009
@@ -18,10 +18,14 @@
  */
 package org.apache.maven.continuum.web.action;
 
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.continuum.buildmanager.BuildManagerException;
 import org.apache.maven.continuum.buildqueue.BuildProjectTask;
 import org.apache.maven.continuum.model.project.BuildResult;
 import org.apache.maven.continuum.project.ContinuumProjectState;
-import org.codehaus.plexus.taskqueue.execution.TaskQueueExecutor;
+import org.codehaus.plexus.taskqueue.Task;
 
 /**
  * @author <a href="mailto:olamy@apache.org">olamy</a>
@@ -30,31 +34,24 @@
  */
 public abstract class AbstractBuildAction
     extends ContinuumConfirmAction
-{
-    
+{    
     private int projectId;
     
     private boolean canDelete = true;
     
-    /**
-     * @plexus.requirement role-hint='build-project'
-     */
-    private TaskQueueExecutor taskQueueExecutor; 
-    
-    
-    
-    protected TaskQueueExecutor getTaskQueueExecutor()
-    {
-        return this.taskQueueExecutor;
-    }
-    
     protected boolean canRemoveBuildResult(BuildResult buildResult)
+        throws BuildManagerException
     {
-        BuildProjectTask buildProjectTask = (BuildProjectTask) getTaskQueueExecutor().getCurrentTask();
-        if ( buildProjectTask != null && buildResult != null )
+        Map<String, Task> currentBuilds = getContinuum().getBuildsManager().getCurrentBuilds();
+        Set<String> keySet = currentBuilds.keySet();
+        for( String key : keySet )
         {
-            return !( buildResult.getState() == ContinuumProjectState.BUILDING && ( buildProjectTask
-                .getBuildDefinitionId() == buildResult.getBuildDefinition().getId() && buildProjectTask.getProjectId() == this.getProjectId() ) );
+            BuildProjectTask buildProjectTask = (BuildProjectTask) currentBuilds.get( key );
+            if ( buildProjectTask != null && buildResult != null )
+            {
+                return !( buildResult.getState() == ContinuumProjectState.BUILDING && ( buildProjectTask
+                    .getBuildDefinitionId() == buildResult.getBuildDefinition().getId() && buildProjectTask.getProjectId() == this.getProjectId() ) );
+            }
         }
         return true;
     }

Modified: continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/BuildResultAction.java
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/BuildResultAction.java?rev=734099&r1=734098&r2=734099&view=diff
==============================================================================
--- continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/BuildResultAction.java (original)
+++ continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/BuildResultAction.java Tue Jan 13 03:00:41 2009
@@ -21,6 +21,7 @@
 
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.continuum.buildmanager.BuildManagerException;
 import org.apache.maven.continuum.ContinuumException;
 import org.apache.maven.continuum.configuration.ConfigurationException;
 import org.apache.maven.continuum.model.project.BuildResult;
@@ -62,7 +63,7 @@
     private String projectGroupName = "";
 
     public String execute()
-        throws ContinuumException, ConfigurationException, IOException
+        throws ContinuumException, ConfigurationException, IOException, BuildManagerException
     {
         try
         {

Modified: continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/BuildResultsListAction.java
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/BuildResultsListAction.java?rev=734099&r1=734098&r2=734099&view=diff
==============================================================================
--- continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/BuildResultsListAction.java (original)
+++ continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/BuildResultsListAction.java Tue Jan 13 03:00:41 2009
@@ -23,6 +23,7 @@
 import java.util.Collection;
 import java.util.List;
 
+import org.apache.continuum.buildmanager.BuildManagerException;
 import org.apache.maven.continuum.ContinuumException;
 import org.apache.maven.continuum.model.project.Project;
 import org.apache.maven.continuum.web.exception.AuthorizationRequiredException;
@@ -112,13 +113,21 @@
                 {
                     int buildId = Integer.parseInt( id );
 
-                    if ( canRemoveBuildResult( getContinuum().getBuildResult( buildId ) ) )
+                    try
                     {
-                        buildResultsRemovable.add( Integer.toString( buildId ) );
+                        if ( canRemoveBuildResult( getContinuum().getBuildResult( buildId ) ) )
+                        {
+                            buildResultsRemovable.add( Integer.toString( buildId ) );
+                        }
+                        else
+                        {
+                            this.addActionMessage( getResourceBundle().getString( "buildResult.cannot.delete" ) );
+                        }
                     }
-                    else
+                    catch ( BuildManagerException e )
                     {
-                        this.addActionMessage( getResourceBundle().getString( "buildResult.cannot.delete" ) );
+                        getLogger().error( e.getMessage() );
+                        throw new ContinuumException( e.getMessage(), e ); 
                     }
                 }
             }
@@ -186,7 +195,5 @@
     public void setProjectGroupId( int projectGroupId )
     {
         this.projectGroupId = projectGroupId;
-    }
-
-    
+    }    
 }

Modified: continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/CancelBuildAction.java
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/CancelBuildAction.java?rev=734099&r1=734098&r2=734099&view=diff
==============================================================================
--- continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/CancelBuildAction.java (original)
+++ continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/CancelBuildAction.java Tue Jan 13 03:00:41 2009
@@ -22,14 +22,18 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import org.apache.commons.lang.ArrayUtils;
+import org.apache.continuum.buildmanager.BuildManagerException;
+import org.apache.continuum.buildmanager.BuildsManager;
 import org.apache.continuum.model.project.ProjectScmRoot;
-import org.apache.continuum.taskqueue.manager.TaskQueueManager;
-import org.apache.continuum.taskqueue.manager.TaskQueueManagerException;
 import org.apache.maven.continuum.ContinuumException;
+import org.apache.maven.continuum.buildqueue.BuildProjectTask;
 import org.apache.maven.continuum.model.project.Project;
 import org.apache.maven.continuum.web.exception.AuthorizationRequiredException;
+import org.codehaus.plexus.taskqueue.Task;
 import org.codehaus.plexus.util.StringUtils;
 
 /**
@@ -38,151 +42,177 @@
  * @plexus.component role="com.opensymphony.xwork2.Action" role-hint="cancelBuild"
  */
 public class CancelBuildAction
-    extends ContinuumActionSupport
+	extends ContinuumActionSupport
 {
-
-    private int projectId;
-
-    private int projectGroupId;
-
-    private List<String> selectedProjects;
-
-    private String projectGroupName = "";
-
-    public String execute()
-        throws ContinuumException
-    {
-        try
-        {
-            checkBuildProjectInGroupAuthorization( getProjectGroupName() );
-
-            TaskQueueManager taskQueueManager = getContinuum().getTaskQueueManager();
-
-            taskQueueManager.cancelBuildTask( projectId );
-        }
-        catch ( AuthorizationRequiredException e )
-        {
-            return REQUIRES_AUTHORIZATION;
-        }
-        catch ( TaskQueueManagerException e )
-        {
-            throw new ContinuumException( "Error while canceling build", e );
-        }
-
-        return SUCCESS;
-    }
-
-    public String cancelBuilds()
-        throws ContinuumException
-    {
-        if ( getSelectedProjects() == null || getSelectedProjects().isEmpty() )
-        {
-            return SUCCESS;
-        }
-        int[] projectsId = new int[getSelectedProjects().size()];
-        for ( String selectedProjectId : getSelectedProjects() )
-        {
-            int projectId = Integer.parseInt( selectedProjectId );
-            projectsId = ArrayUtils.add( projectsId, projectId );
-        }
-
-        TaskQueueManager taskQueueManager = getContinuum().getTaskQueueManager();
-        try
-        {
-            taskQueueManager.removeProjectsFromBuildingQueue( projectsId );
-            
-            // now we must check if the current build is one of this
-        	int index = ArrayUtils.indexOf( projectsId, taskQueueManager.getCurrentProjectIdBuilding() );
-        	if ( index > 0 )
-        	{
-            	taskQueueManager.cancelBuildTask( projectsId[index] );
-        	}
-        }
-        catch ( TaskQueueManagerException e )
-        {
-            throw new ContinuumException( "Unable to remove projects from building queue", e );
-        }
-
-        return SUCCESS;
-    }
-
-    public String cancelGroupBuild()
-        throws ContinuumException
-    {
-        try
-        {
-            checkBuildProjectInGroupAuthorization( getContinuum().getProjectGroup( projectGroupId).getName() );
-        }
-        catch ( AuthorizationRequiredException e )
-        {
-            return REQUIRES_AUTHORIZATION;
-        }
-
-        TaskQueueManager taskQueueManager = getContinuum().getTaskQueueManager();
-
-        List<ProjectScmRoot> scmRoots = getContinuum().getProjectScmRootByProjectGroup( projectGroupId );
-        
-        if ( scmRoots != null )
-        {
-            for ( ProjectScmRoot scmRoot : scmRoots )
-            {
-                try
-                {
-                    taskQueueManager.removeFromPrepareBuildQueue( projectGroupId, scmRoot.getScmRootAddress() );
-                }
-                catch ( TaskQueueManagerException e )
-                {
-                    throw new ContinuumException( "Unable to cancel group build", e );
-                }
-            }
-        }
-        Collection<Project> projects = getContinuum().getProjectsInGroup( projectGroupId );
-
-        List<String> projectIds = new ArrayList<String>();
-        
-        for ( Project project : projects )
-        {
-            projectIds.add( Integer.toString( project.getId() ) );
-        }
-
-        setSelectedProjects( projectIds );
-
-        return cancelBuilds();
-    }
-
-    public void setProjectId( int projectId )
-    {
-        this.projectId = projectId;
-    }
-
-    public String getProjectGroupName()
-        throws ContinuumException
-    {
-        if ( StringUtils.isEmpty( projectGroupName ) )
-        {
-            projectGroupName = getContinuum().getProjectGroupByProjectId( projectId ).getName();
-        }
-
-        return projectGroupName;
-    }
-
-    public List<String> getSelectedProjects()
-    {
-        return selectedProjects;
-    }
-
-    public void setSelectedProjects( List<String> selectedProjects )
-    {
-        this.selectedProjects = selectedProjects;
-    }
-
-    public int getProjectGroupId()
-    {
-        return projectGroupId;
-    }
-
-    public void setProjectGroupId( int projectGroupId )
-    {
-        this.projectGroupId = projectGroupId;
-    }
+	private int projectId;
+	
+	private int projectGroupId;
+	
+	private List<String> selectedProjects;
+	
+	private String projectGroupName = "";
+	
+	public String execute()
+	    throws ContinuumException
+	{
+	    try
+	    {
+	        checkBuildProjectInGroupAuthorization( getProjectGroupName() );
+	
+	        BuildsManager buildsManager = getContinuum().getBuildsManager();
+	        
+	        buildsManager.cancelBuild( projectId );
+	    }
+	    catch ( AuthorizationRequiredException e )
+	    {
+	        return REQUIRES_AUTHORIZATION;
+	    }
+	    catch ( BuildManagerException e )
+	    {
+	        throw new ContinuumException( "Error while canceling build", e );
+	    }
+	
+	    return SUCCESS;
+	}
+	
+	public String cancelBuilds()
+	    throws ContinuumException
+	{
+	    if ( getSelectedProjects() == null || getSelectedProjects().isEmpty() )
+	    {
+	        return SUCCESS;
+	    }
+	    int[] projectsId = new int[getSelectedProjects().size()];
+	    for ( String selectedProjectId : getSelectedProjects() )
+	    {
+	        int projectId = Integer.parseInt( selectedProjectId );
+	        projectsId = ArrayUtils.add( projectsId, projectId );
+	    }
+	
+	    BuildsManager parallelBuildsManager = getContinuum().getBuildsManager();
+	    parallelBuildsManager.removeProjectsFromBuildQueue( projectsId );           
+	    
+	    try
+	    {
+	        // now we must check if the current build is one of this
+	        int index = ArrayUtils.indexOf( projectsId, getCurrentProjectIdBuilding() );
+	        if ( index > 0 )
+	        {
+	            getContinuum().getBuildsManager().cancelBuild( projectsId[index] );
+	        }
+	        
+	    }
+	    catch ( BuildManagerException e )
+	    {
+	        getLogger().error( e.getMessage() );
+	        throw new ContinuumException( e.getMessage(), e );
+	    }
+	
+	    return SUCCESS;
+	}
+	
+	public String cancelGroupBuild()
+	    throws ContinuumException
+	{
+	    try
+	    {
+	        checkBuildProjectInGroupAuthorization( getContinuum().getProjectGroup( projectGroupId).getName() );
+	    }
+	    catch ( AuthorizationRequiredException e )
+	    {
+	        return REQUIRES_AUTHORIZATION;
+	    }
+	
+	    BuildsManager buildsManager = getContinuum().getBuildsManager();
+	
+	    List<ProjectScmRoot> scmRoots = getContinuum().getProjectScmRootByProjectGroup( projectGroupId );
+	    
+	    if ( scmRoots != null )
+	    {
+	        for ( ProjectScmRoot scmRoot : scmRoots )
+	        {
+	            try
+	            {
+	                buildsManager.removeProjectGroupFromPrepareBuildQueue( projectGroupId, scmRoot.getScmRootAddress() );
+	                //taskQueueManager.removeFromPrepareBuildQueue( projectGroupId, scmRoot.getScmRootAddress() );
+	            }
+	            catch ( BuildManagerException e )
+	            {
+	                throw new ContinuumException( "Unable to cancel group build", e );
+	            }
+	        }
+	    }
+	    Collection<Project> projects = getContinuum().getProjectsInGroup( projectGroupId );
+	
+	    List<String> projectIds = new ArrayList<String>();
+	    
+	    for ( Project project : projects )
+	    {
+	        projectIds.add( Integer.toString( project.getId() ) );
+	    }
+	
+	    setSelectedProjects( projectIds );
+	
+	    return cancelBuilds();
+	}
+	
+	public void setProjectId( int projectId )
+	{
+	    this.projectId = projectId;
+	}
+	
+	public String getProjectGroupName()
+	    throws ContinuumException
+	{
+	    if ( StringUtils.isEmpty( projectGroupName ) )
+	    {
+	        projectGroupName = getContinuum().getProjectGroupByProjectId( projectId ).getName();
+	    }
+	
+	    return projectGroupName;
+	}
+	
+	public List<String> getSelectedProjects()
+	{
+	    return selectedProjects;
+	}
+	
+	public void setSelectedProjects( List<String> selectedProjects )
+	{
+	    this.selectedProjects = selectedProjects;
+	}
+	
+	public int getProjectGroupId()
+	{
+	    return projectGroupId;
+	}
+	
+	public void setProjectGroupId( int projectGroupId )
+	{
+	    this.projectGroupId = projectGroupId;
+	}
+	
+	/**
+	 * @return -1 if not project currently building
+	 * @throws ContinuumException
+	 */
+	protected int getCurrentProjectIdBuilding()
+	    throws ContinuumException, BuildManagerException
+	{
+	    Map<String, Task> currentBuilds = getContinuum().getBuildsManager().getCurrentBuilds();
+	    Set<String> keySet = currentBuilds.keySet();
+	    
+	    for( String key : keySet )
+	    {
+	        Task task = currentBuilds.get( key );
+	        if ( task != null )
+	        {
+	            if ( task instanceof BuildProjectTask )
+	            {
+	                return ( (BuildProjectTask) task ).getProjectId();
+	            }
+	        }
+	    }        
+	    return -1;
+	}
 }

Modified: continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/ProjectGroupAction.java
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/ProjectGroupAction.java?rev=734099&r1=734098&r2=734099&view=diff
==============================================================================
--- continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/ProjectGroupAction.java (original)
+++ continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/ProjectGroupAction.java Tue Jan 13 03:00:41 2009
@@ -19,10 +19,10 @@
  * under the License.
  */
 
+import org.apache.continuum.buildmanager.BuildManagerException;
+import org.apache.continuum.buildmanager.BuildsManager;
 import org.apache.continuum.model.project.ProjectScmRoot;
 import org.apache.continuum.model.repository.LocalRepository;
-import org.apache.continuum.taskqueue.manager.TaskQueueManager;
-import org.apache.continuum.taskqueue.manager.TaskQueueManagerException;
 import org.apache.maven.continuum.ContinuumException;
 import org.apache.maven.continuum.model.project.BuildDefinition;
 import org.apache.maven.continuum.model.project.BuildResult;
@@ -80,11 +80,11 @@
      * @plexus.requirement role-hint="default"
      */
     private RoleManager roleManager;
-
+    
     /**
-     * @plexus.requirement
+     * @plexus.requirement role-hint="parallel"
      */
-    private TaskQueueManager taskQueueManager;
+    private BuildsManager parallelBuildsManager;
 
     private int projectGroupId;
 
@@ -346,13 +346,13 @@
             {
                 Project p = (Project) proj.next();
                 try
-                {
-                    if ( taskQueueManager.isInCheckoutQueue( p.getId() ) )
+                {   
+                    if ( parallelBuildsManager.isInAnyCheckoutQueue( p.getId() ) )
                     {
                         projectInCOQueue = true;
                     }
                 }
-                catch ( TaskQueueManagerException e )
+                catch ( BuildManagerException e )
                 {
                     throw new ContinuumException( e.getMessage(), e );
                 }

Modified: continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/ScheduleAction.java
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/ScheduleAction.java?rev=734099&r1=734098&r2=734099&view=diff
==============================================================================
--- continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/ScheduleAction.java (original)
+++ continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/ScheduleAction.java Tue Jan 13 03:00:41 2009
@@ -19,12 +19,17 @@
  * under the License.
  */
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
 import org.apache.maven.continuum.ContinuumException;
+import org.apache.maven.continuum.model.project.BuildQueue;
 import org.apache.maven.continuum.model.project.Schedule;
 import org.apache.maven.continuum.web.exception.AuthenticationRequiredException;
 import org.apache.maven.continuum.web.exception.AuthorizationRequiredException;
 
-import java.util.Collection;
+import com.opensymphony.xwork2.Preparable;
 
 /**
  * @author Nik Gonzalez
@@ -33,6 +38,7 @@
  */
 public class ScheduleAction
     extends ContinuumConfirmAction
+    implements Preparable
 {
     private int id;
 
@@ -65,6 +71,50 @@
     private String dayOfWeek = "?";
 
     private String year;
+    
+    private List<String> availableBuildQueues;
+    
+    private List<String> selectedBuildQueues = new ArrayList<String>();
+
+    public void prepare()
+        throws Exception
+    {
+        super.prepare();
+        
+        populateBuildQueues();
+    }
+
+    private void populateBuildQueues()
+        throws ContinuumException
+    {
+        List<BuildQueue> buildQueues = null;
+        if( schedule != null )
+        {
+            buildQueues = schedule.getBuildQueues();
+            for( BuildQueue buildQueue : buildQueues )
+            {
+                selectedBuildQueues.add( buildQueue.getName() );
+            }
+
+        }
+            
+        availableBuildQueues = new ArrayList<String>();
+        
+        buildQueues = getContinuum().getAllBuildQueues();
+        for( BuildQueue buildQueue : buildQueues )
+        {
+            availableBuildQueues.add( buildQueue.getName() );
+        }
+        
+        // remove selected build queues from available build queues
+        for( String buildQueue : selectedBuildQueues )
+        {
+            if( availableBuildQueues.contains( buildQueue ) )
+            {
+                availableBuildQueues.remove( buildQueue );
+            }
+        }
+    }
 
     public String summary()
         throws ContinuumException
@@ -82,8 +132,9 @@
         {
             addActionError( e.getMessage() );
             return REQUIRES_AUTHENTICATION;
-        }
 
+        }
+        
         schedules = getContinuum().getSchedules();
 
         return SUCCESS;
@@ -92,6 +143,7 @@
     public String input()
         throws ContinuumException
     {
+
         try
         {
             checkManageSchedulesAuthorization();
@@ -128,6 +180,8 @@
             name = schedule.getName();
             delay = schedule.getDelay();
             maxJobExecutionTime = schedule.getMaxJobExecutionTime();
+
+            populateBuildQueues();
         }
         else
         {
@@ -141,6 +195,7 @@
     public String save()
         throws ContinuumException
     {
+
         try
         {
             checkManageSchedulesAuthorization();
@@ -166,18 +221,35 @@
         {
             if ( id == 0 )
             {
-                getContinuum().addSchedule( setFields( new Schedule() ) );
+                try
+                {
+                    getContinuum().addSchedule( setFields( new Schedule() ) );
+                }
+                catch ( ContinuumException e )
+                {
+                    addActionError( "schedule.buildqueues.add.error" );
+                    return ERROR;
+                }
                 return SUCCESS;
             }
             else
             {
-                getContinuum().updateSchedule( setFields( getContinuum().getSchedule( id ) ) );
+                try
+                {
+                    getContinuum().updateSchedule( setFields( getContinuum().getSchedule( id ) ) );
+                }
+                catch ( ContinuumException e )
+                {
+                    addActionError( "schedule.buildqueues.add.error" );
+                    return ERROR;
+                }
                 return SUCCESS;
             }
         }
     }
 
     private Schedule setFields( Schedule schedule )
+        throws ContinuumException
     {
         schedule.setActive( active );
         schedule.setCronExpression( getCronExpression() );
@@ -186,6 +258,15 @@
         schedule.setName( name );
         schedule.setMaxJobExecutionTime( maxJobExecutionTime );
 
+     // remove old build queues
+        schedule.setBuildQueues( null );
+
+        for( String name : selectedBuildQueues )
+        {
+            BuildQueue buildQueue = getContinuum().getBuildQueueByName( name );
+            schedule.addBuildQueue( buildQueue );
+        }
+        
         return schedule;
     }
 
@@ -239,7 +320,6 @@
             catch ( ContinuumException e )
             {
                 addActionError( getText( "schedule.remove.error" ) );
-
                 return ERROR;
             }
         }
@@ -412,7 +492,26 @@
 
     private String getCronExpression()
     {
-        return ( second + " " + minute + " " + hour + " " + dayOfMonth + " " + month + " " + dayOfWeek + " " +
-            year ).trim();
+        return ( second + " " + minute + " " + hour + " " + dayOfMonth + " " + month + " " + dayOfWeek + " " + year ).trim();
+    }
+
+    public List<String> getAvailableBuildQueues()
+    {
+        return availableBuildQueues;
+    }
+
+    public void setAvailableBuildQueues( List<String> availableBuildQueues )
+    {
+        this.availableBuildQueues = availableBuildQueues;
+    }
+
+    public List<String> getSelectedBuildQueues()
+    {
+        return selectedBuildQueues;
+    }
+
+    public void setSelectedBuildQueues( List<String> selectedBuildQueues )
+    {
+        this.selectedBuildQueues = selectedBuildQueues;
     }
 }

Modified: continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/SummaryAction.java
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/SummaryAction.java?rev=734099&r1=734098&r2=734099&view=diff
==============================================================================
--- continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/SummaryAction.java (original)
+++ continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/SummaryAction.java Tue Jan 13 03:00:41 2009
@@ -19,8 +19,8 @@
  * under the License.
  */
 
-import org.apache.continuum.taskqueue.manager.TaskQueueManager;
-import org.apache.continuum.taskqueue.manager.TaskQueueManagerException;
+import org.apache.continuum.buildmanager.BuildManagerException;
+import org.apache.continuum.buildmanager.BuildsManager;
 import org.apache.maven.continuum.ContinuumException;
 import org.apache.maven.continuum.model.project.BuildResult;
 import org.apache.maven.continuum.model.project.Project;
@@ -56,10 +56,10 @@
     private GroupSummary groupSummary = new GroupSummary();
 
     /**
-     * @plexus.requirement
+     * @plexus.requirement role-hint="parallel"
      */
-    private TaskQueueManager taskQueueManager;
-
+    private BuildsManager parallelBuildsManager;
+    
     public String execute()
         throws ContinuumException
     {
@@ -110,12 +110,12 @@
             model.setProjectType( project.getExecutorId() );
 
             try
-            {
-                if ( taskQueueManager.isInBuildingQueue( project.getId() ) )
+            {                
+                if ( parallelBuildsManager.isInAnyBuildQueue( project.getId() ) )
                 {
                     model.setInBuildingQueue( true );
-                }
-                else if ( taskQueueManager.isInCheckoutQueue( project.getId() ) )
+                }             
+                else if ( parallelBuildsManager.isInAnyCheckoutQueue( project.getId() ) )
                 {
                     model.setInCheckoutQueue( true );
                 }
@@ -125,7 +125,7 @@
                     model.setInCheckoutQueue( false );
                 }
             }
-            catch ( TaskQueueManagerException e )
+            catch ( BuildManagerException e )
             {
                 throw new ContinuumException( e.getMessage(), e );
             }

Modified: continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/admin/ConfigurationAction.java
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/admin/ConfigurationAction.java?rev=734099&r1=734098&r2=734099&view=diff
==============================================================================
--- continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/admin/ConfigurationAction.java (original)
+++ continuum/trunk/continuum-webapp/src/main/java/org/apache/maven/continuum/web/action/admin/ConfigurationAction.java Tue Jan 13 03:00:41 2009
@@ -57,8 +57,10 @@
     
     private String releaseOutputDirectory;
 
+    private int numberOfAllowedBuildsinParallel = 1;
+    
     private boolean requireReleaseOutput;
-
+    
     public void prepare()
     {
         ConfigurationService configuration = getContinuum().getConfiguration();
@@ -97,6 +99,13 @@
             releaseOutputDirectory = releaseOutputDirectoryFile.getAbsolutePath();
         }
         
+        numberOfAllowedBuildsinParallel = configuration.getNumberOfBuildsInParallel();
+        
+        if( numberOfAllowedBuildsinParallel == 0 )
+        {
+            numberOfAllowedBuildsinParallel = 1;
+        }
+               
         String requireRelease = ServletActionContext.getRequest().getParameter( "requireReleaseOutput" );
         setRequireReleaseOutput( new Boolean( requireRelease ) );
     }
@@ -107,6 +116,11 @@
         {
             addActionError( getText( "configuration.releaseOutputDirectory.required" ) );
         }
+                
+        if( numberOfAllowedBuildsinParallel <= 0 )
+        {
+            addActionError( "configuration.numberOfBuildsInParallel.invalid" );
+        }
         
         return INPUT;
     }
@@ -114,12 +128,20 @@
     public String save()
         throws ConfigurationStoringException, ContinuumStoreException, ContinuumConfigurationException
     {
+        if( numberOfAllowedBuildsinParallel <= 0 )
+        {
+            addActionError( "Number of Allowed Builds in Parallel must be greater than zero." );
+            return ERROR;
+        }
+        
         ConfigurationService configuration = getContinuum().getConfiguration();
 
         configuration.setWorkingDirectory( new File( workingDirectory ) );
 
         configuration.setBuildOutputDirectory( new File( buildOutputDirectory ) );
-
+        
+        configuration.setNumberOfBuildsInParallel( numberOfAllowedBuildsinParallel );	
+        
         if ( StringUtils.isNotEmpty( deploymentRepositoryDirectory ) )
         {
             configuration.setDeploymentRepositoryDirectory( new File( deploymentRepositoryDirectory ) );
@@ -128,7 +150,7 @@
         {
             configuration.setDeploymentRepositoryDirectory( null );
         }
-
+        
         configuration.setUrl( baseUrl );
 
         configuration.setInitialized( true );
@@ -221,4 +243,14 @@
     {
         this.requireReleaseOutput = requireReleaseOutput;
     }
+    
+	public int getNumberOfAllowedBuildsinParallel() 
+	{
+	    return numberOfAllowedBuildsinParallel;
+	}
+
+	public void setNumberOfAllowedBuildsinParallel( int numberOfAllowedBuildsinParallel ) 
+	{
+	    this.numberOfAllowedBuildsinParallel = numberOfAllowedBuildsinParallel;
+	}
 }