You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@continuum.apache.org by jv...@apache.org on 2005/07/18 06:40:13 UTC

svn commit: r219457 - in /maven/continuum/trunk/continuum-core: ./ src/main/java/org/apache/maven/continuum/ src/main/java/org/apache/maven/continuum/configuration/ src/main/java/org/apache/maven/continuum/scheduler/ src/main/java/org/apache/maven/cont...

Author: jvanzyl
Date: Sun Jul 17 21:39:44 2005
New Revision: 219457

URL: http://svn.apache.org/viewcvs?rev=219457&view=rev
Log:
o adding scheduler bits
o adding configuration service which will start to serve as a dynamic store
  of configuration information that can be used to create an initial web
  install process
  

Added:
    maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/configuration/
    maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/configuration/ConfigurationLoadingException.java
    maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/configuration/ConfigurationService.java
    maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/configuration/ConfigurationStoringException.java
    maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/configuration/DefaultConfigurationService.java
    maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scheduler/
    maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scheduler/ContinuumBuildJob.java
    maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scheduler/ContinuumScheduler.java
    maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scheduler/ContinuumSchedulerConstants.java
    maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scheduler/ContinuumSchedulerException.java
    maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scheduler/DefaultContinuumScheduler.java
    maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/trigger/quartz/
    maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/trigger/quartz/ContinuumBuildTrigger.java
    maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/trigger/quartz/QuartzAlarmClockTrigger.java
Removed:
    maven/continuum/trunk/continuum-core/src/test/java/org/apache/maven/continuum/project/ContinuumJPoxStoreTest.java
    maven/continuum/trunk/continuum-core/src/test/java/org/apache/maven/continuum/store/ModelloJPoxContinuumStoreTest.java
Modified:
    maven/continuum/trunk/continuum-core/pom.xml
    maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/DefaultContinuum.java
    maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/store/JdoContinuumStore.java
    maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/trigger/alarmclock/AlarmClockTrigger.java
    maven/continuum/trunk/continuum-core/src/main/resources/META-INF/plexus/components.xml
    maven/continuum/trunk/continuum-core/src/test/java/org/apache/maven/continuum/AbstractContinuumTest.java
    maven/continuum/trunk/continuum-core/src/test/java/org/apache/maven/continuum/store/AbstractContinuumStoreTest.java
    maven/continuum/trunk/continuum-core/src/test/java/org/apache/maven/continuum/store/JdoContinuumStoreTest.java

Modified: maven/continuum/trunk/continuum-core/pom.xml
URL: http://svn.apache.org/viewcvs/maven/continuum/trunk/continuum-core/pom.xml?rev=219457&r1=219456&r2=219457&view=diff
==============================================================================
--- maven/continuum/trunk/continuum-core/pom.xml (original)
+++ maven/continuum/trunk/continuum-core/pom.xml Sun Jul 17 21:39:44 2005
@@ -62,7 +62,11 @@
       <artifactId>plexus-command-line</artifactId>
       <version>1.0-alpha-1</version>
     </dependency>
-
+    <dependency>
+      <groupId>quartz</groupId>
+      <artifactId>quartz</artifactId>
+      <version>1.4.5</version>
+    </dependency>    
     <!--
      |
      | Maven Dependencies

Modified: maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/DefaultContinuum.java
URL: http://svn.apache.org/viewcvs/maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/DefaultContinuum.java?rev=219457&r1=219456&r2=219457&view=diff
==============================================================================
--- maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/DefaultContinuum.java (original)
+++ maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/DefaultContinuum.java Sun Jul 17 21:39:44 2005
@@ -32,14 +32,20 @@
 import org.apache.maven.continuum.project.MavenOneProject;
 import org.apache.maven.continuum.project.MavenTwoProject;
 import org.apache.maven.continuum.project.ShellProject;
+import org.apache.maven.continuum.project.ContinuumSchedule;
 import org.apache.maven.continuum.project.builder.ContinuumProjectBuildingResult;
 import org.apache.maven.continuum.project.builder.maven.MavenOneContinuumProjectBuilder;
 import org.apache.maven.continuum.project.builder.maven.MavenTwoContinuumProjectBuilder;
 import org.apache.maven.continuum.scm.ScmResult;
 import org.apache.maven.continuum.utils.ProjectSorter;
+import org.apache.maven.continuum.scheduler.ContinuumScheduler;
+import org.apache.maven.continuum.scheduler.ContinuumSchedulerConstants;
+import org.apache.maven.continuum.configuration.ConfigurationService;
 import org.codehaus.plexus.action.ActionManager;
 import org.codehaus.plexus.logging.AbstractLogEnabled;
 import org.codehaus.plexus.util.dag.CycleDetectedException;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
 
 import java.util.Collection;
 import java.util.HashMap;
@@ -55,18 +61,20 @@
  */
 public class DefaultContinuum
     extends AbstractLogEnabled
-    implements Continuum
+    implements Continuum, Initializable
 {
-    /**
-     * @plexus.requirement
-     */
+    /** @plexus.requirement */
     private ContinuumCore core;
 
-    /**
-     * @plexus.requirement
-     */
+    /** @plexus.requirement */
     private ActionManager actionManager;
 
+    /** @plexus.requirement */
+    private ContinuumScheduler scheduler;
+
+    /** @plexus.requirement */
+    private ConfigurationService configurationService;
+
     // ----------------------------------------------------------------------
     // Projects
     // ----------------------------------------------------------------------
@@ -148,6 +156,8 @@
         buildProjects( true );
     }
 
+    // TODO: take a Properties here so that we can be extensible. For example we would like to be able
+    // to specify an update or clean checkout as well.
     public void buildProjects( boolean force )
         throws ContinuumException
     {
@@ -625,5 +635,81 @@
         {
             core.removeNotifier( n );
         }
+    }
+
+    // ----------------------------------------------------------------------
+    // Lifecylce Management
+    // ----------------------------------------------------------------------
+
+    public void initialize()
+        throws InitializationException
+    {
+        // ----------------------------------------------------------------------
+        // Make sure that the default schedule exists so that projects being
+        // added to Continuum will participate in a scheduled build by default
+        // ----------------------------------------------------------------------
+
+        if ( !defaultScheduleExists() )
+        {
+            createDefaultSchedule();
+        }
+    }
+
+    // ----------------------------------------------------------------------
+    // Build Scheduling
+    // ----------------------------------------------------------------------
+
+    public ContinuumSchedule getSchedule( String id )
+    {
+        return null;
+    }
+
+    public void addSchedule( ContinuumSchedule schedule )
+    {
+    }
+
+    public void updateSchedule( ContinuumSchedule schedule )
+    {
+    }
+
+    public void removeSchedule( ContinuumSchedule schedule )
+    {
+    }
+
+
+    public void addScheduleToProject( ContinuumProject project, ContinuumSchedule schedule )
+    {
+        project.addSchedule( schedule );
+    }
+
+    public void removeScheduleFromProject( ContinuumProject project, ContinuumSchedule schedule )
+    {
+        project.removeSchedule( schedule );
+    }
+
+    // ----------------------------------------------------------------------
+    // Internal Build Scheduling
+    // ----------------------------------------------------------------------
+
+    private boolean defaultScheduleExists()
+    {
+        // ----------------------------------------------------------------------
+        // Perform a lookup for the default schedule to see if it exists.
+        // ----------------------------------------------------------------------
+
+        return true;
+    }
+
+    private void createDefaultSchedule()
+    {
+        ContinuumSchedule schedule = new ContinuumSchedule();
+
+        schedule.setName( ContinuumSchedulerConstants.DEFAULT_SCHEDULE_NAME );
+
+        schedule.setDescription( ContinuumSchedulerConstants.DEFAULT_SCHEDULE_NAME );
+
+        schedule.setScmMode( ContinuumSchedulerConstants.DEFAULT_SCHEDULE_SCM_MODE );
+
+        schedule.setCronExpression( ContinuumSchedulerConstants.DEFAULT_CRON_EXPRESSION );
     }
 }

Added: maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/configuration/ConfigurationLoadingException.java
URL: http://svn.apache.org/viewcvs/maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/configuration/ConfigurationLoadingException.java?rev=219457&view=auto
==============================================================================
--- maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/configuration/ConfigurationLoadingException.java (added)
+++ maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/configuration/ConfigurationLoadingException.java Sun Jul 17 21:39:44 2005
@@ -0,0 +1,24 @@
+package org.apache.maven.continuum.configuration;
+
+/**
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
+ * @version $Id:$
+ */
+public class ConfigurationLoadingException
+    extends Exception
+{
+    public ConfigurationLoadingException( String message )
+    {
+        super( message );
+    }
+
+    public ConfigurationLoadingException( Throwable cause )
+    {
+        super( cause );
+    }
+
+    public ConfigurationLoadingException( String message, Throwable cause )
+    {
+        super( message, cause );
+    }
+}

Added: maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/configuration/ConfigurationService.java
URL: http://svn.apache.org/viewcvs/maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/configuration/ConfigurationService.java?rev=219457&view=auto
==============================================================================
--- maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/configuration/ConfigurationService.java (added)
+++ maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/configuration/ConfigurationService.java Sun Jul 17 21:39:44 2005
@@ -0,0 +1,20 @@
+package org.apache.maven.continuum.configuration;
+
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+import java.io.File;
+
+/**
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
+ * @version $Id:$
+ */
+public interface ConfigurationService
+{
+    String ROLE = ConfigurationService.class.getName();
+
+    void load()
+        throws ConfigurationLoadingException;
+
+    void store()
+        throws ConfigurationStoringException;
+}

Added: maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/configuration/ConfigurationStoringException.java
URL: http://svn.apache.org/viewcvs/maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/configuration/ConfigurationStoringException.java?rev=219457&view=auto
==============================================================================
--- maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/configuration/ConfigurationStoringException.java (added)
+++ maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/configuration/ConfigurationStoringException.java Sun Jul 17 21:39:44 2005
@@ -0,0 +1,24 @@
+package org.apache.maven.continuum.configuration;
+
+/**
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
+ * @version $Id:$
+ */
+public class ConfigurationStoringException
+    extends Exception
+{
+    public ConfigurationStoringException( String message )
+    {
+        super( message );
+    }
+
+    public ConfigurationStoringException( Throwable cause )
+    {
+        super( cause );
+    }
+
+    public ConfigurationStoringException( String message, Throwable cause )
+    {
+        super( message, cause );
+    }
+}

Added: maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/configuration/DefaultConfigurationService.java
URL: http://svn.apache.org/viewcvs/maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/configuration/DefaultConfigurationService.java?rev=219457&view=auto
==============================================================================
--- maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/configuration/DefaultConfigurationService.java (added)
+++ maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/configuration/DefaultConfigurationService.java Sun Jul 17 21:39:44 2005
@@ -0,0 +1,115 @@
+package org.apache.maven.continuum.configuration;
+
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
+import org.codehaus.plexus.util.xml.Xpp3DomWriter;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+import org.codehaus.plexus.util.FileUtils;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
+
+/**
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
+ * @version $Id:$
+ */
+public class DefaultConfigurationService
+    implements ConfigurationService
+{
+    private File source;
+
+    private Xpp3Dom configuration;
+
+    // ----------------------------------------------------------------------
+    // Continuum specifics we'll refactor out later
+    // ----------------------------------------------------------------------
+
+    private String url;
+
+    public String getUrl()
+    {
+        return url;
+    }
+
+    public void setUrl( String url )
+    {
+        this.url = url;
+    }
+
+    // ----------------------------------------------------------------------
+    // Process configuration to glean application specific values
+    // ----------------------------------------------------------------------
+
+    protected void processInboundConfiguration()
+    {
+        url = configuration.getChild( "url" ).getValue();
+    }
+
+    protected void processOutboundConfiguration()
+    {
+        configuration = new Xpp3Dom( "configuration" );
+
+        configuration.addChild( createDom( "url", url ) );
+    }
+
+    protected Xpp3Dom createDom( String elementName, String value )
+    {
+        Xpp3Dom dom = new Xpp3Dom( elementName );
+
+        dom.setValue( value );
+
+        return dom;
+    }
+
+    // ----------------------------------------------------------------------
+    // Load and Store
+    // ----------------------------------------------------------------------
+
+    public void load()
+        throws ConfigurationLoadingException
+    {
+        try
+        {
+            configuration = Xpp3DomBuilder.build( new FileReader( source ) );
+        }
+        catch ( FileNotFoundException e )
+        {
+            throw new ConfigurationLoadingException( "Specified location of configuration '" + source + "' doesn't exist." );
+        }
+        catch ( IOException e )
+        {
+            throw new ConfigurationLoadingException( "Error reading configuration '" + source + "'.", e );
+        }
+        catch ( XmlPullParserException e )
+        {
+            throw new ConfigurationLoadingException( "Error parsing configuration '" + source + "'.", e );
+        }
+
+        processInboundConfiguration();
+    }
+
+    public void store()
+        throws ConfigurationStoringException
+    {
+        processOutboundConfiguration();
+
+        try
+        {
+            File backup = new File( source.getName() + ".backup " );
+
+            FileUtils.rename( source, backup );
+
+            Writer writer = new FileWriter( source );
+
+            Xpp3DomWriter.write( writer, configuration );
+        }
+        catch ( IOException e )
+        {
+            throw new ConfigurationStoringException( "Error reading configuration '" + source + "'.", e );
+        }
+    }
+}

Added: maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scheduler/ContinuumBuildJob.java
URL: http://svn.apache.org/viewcvs/maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scheduler/ContinuumBuildJob.java?rev=219457&view=auto
==============================================================================
--- maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scheduler/ContinuumBuildJob.java (added)
+++ maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scheduler/ContinuumBuildJob.java Sun Jul 17 21:39:44 2005
@@ -0,0 +1,63 @@
+package org.apache.maven.continuum.scheduler;
+
+import org.quartz.Job;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobDetail;
+import org.apache.maven.continuum.project.ContinuumProject;
+import org.apache.maven.continuum.project.ContinuumSchedule;
+import org.apache.maven.continuum.ContinuumException;
+import org.apache.maven.continuum.Continuum;
+import org.codehaus.plexus.logging.Logger;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
+ * @version $Id:$
+ */
+public class ContinuumBuildJob
+    implements Job
+{
+    public void execute( JobExecutionContext context )
+    {
+        // ----------------------------------------------------------------------
+        // Get the job detail
+        // ----------------------------------------------------------------------
+
+        JobDetail jobDetail = context.getJobDetail();
+
+        // ----------------------------------------------------------------------
+        // Get data map out of the job detail
+        // ----------------------------------------------------------------------
+
+        Logger logger = (Logger) jobDetail.getJobDataMap().get( ContinuumSchedulerConstants.LOGGER );
+
+        Continuum continuum = (Continuum) jobDetail.getJobDataMap().get( ContinuumSchedulerConstants.CONTINUUM );
+
+        ContinuumSchedule schedule = (ContinuumSchedule) jobDetail.getJobDataMap().get( ContinuumSchedulerConstants.SCHEDULE );
+
+        // ----------------------------------------------------------------------
+        // Lookup all projects that belong to this schedule
+        // ----------------------------------------------------------------------
+
+        Set projects = schedule.getProjects();
+
+        for ( Iterator i = projects.iterator(); i.hasNext(); )
+        {
+            ContinuumProject project = (ContinuumProject) i.next();
+
+            try
+            {
+                continuum.buildProject( project.getId(), false );
+            }
+            catch ( ContinuumException ex )
+            {
+                logger.error( "Could not enqueue project: " + project.getId() + " ('" + project.getName() + "').", ex );
+
+                continue;
+            }
+        }
+    }
+}
\ No newline at end of file

Added: maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scheduler/ContinuumScheduler.java
URL: http://svn.apache.org/viewcvs/maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scheduler/ContinuumScheduler.java?rev=219457&view=auto
==============================================================================
--- maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scheduler/ContinuumScheduler.java (added)
+++ maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scheduler/ContinuumScheduler.java Sun Jul 17 21:39:44 2005
@@ -0,0 +1,19 @@
+package org.apache.maven.continuum.scheduler;
+
+import org.quartz.JobDetail;
+import org.quartz.Trigger;
+import org.quartz.SchedulerException;
+import org.quartz.JobListener;
+import org.quartz.TriggerListener;
+
+public interface ContinuumScheduler
+{
+    public static String ROLE = ContinuumScheduler.class.getName();
+
+    void scheduleJob( JobDetail jobDetail, Trigger trigger )
+        throws ContinuumSchedulerException;
+
+    void addGlobalJobListener( JobListener listener );
+
+    void addGlobalTriggerListener( TriggerListener listener );  
+}

Added: maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scheduler/ContinuumSchedulerConstants.java
URL: http://svn.apache.org/viewcvs/maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scheduler/ContinuumSchedulerConstants.java?rev=219457&view=auto
==============================================================================
--- maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scheduler/ContinuumSchedulerConstants.java (added)
+++ maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scheduler/ContinuumSchedulerConstants.java Sun Jul 17 21:39:44 2005
@@ -0,0 +1,40 @@
+package org.apache.maven.continuum.scheduler;
+
+/**
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
+ * @version $Id:$
+ */
+public class ContinuumSchedulerConstants
+{
+    /** Checkout before performing a build */
+    public static final int SCM_MODE_CHECKOUT = 0;
+
+    /** Update before performing a build */
+    public static final int SCM_MODE_UPDATE = 1;
+
+    // ----------------------------------------------------------------------
+    // Default Schedule
+    // ----------------------------------------------------------------------
+
+    /** Default schedule name */
+    public static final String DEFAULT_SCHEDULE_NAME = "Default";
+
+    /** Default schedule description */
+    public static final String DEFAULT_SCHEDULE_DESC = "Default Continuum Schedule";
+
+    /** Default scm mode which is to update */
+    public static final int DEFAULT_SCHEDULE_SCM_MODE = SCM_MODE_UPDATE;
+
+    /** Every hour on the hour */
+    public static final String DEFAULT_CRON_EXPRESSION = "0 0 * * * ?";
+
+    // ----------------------------------------------------------------------
+    // Keys for JobDataMap
+    // ----------------------------------------------------------------------
+
+    public static final String LOGGER = "logger";
+
+    public static final String CONTINUUM = "continuum";
+
+    public static final String SCHEDULE = "schedule";
+}

Added: maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scheduler/ContinuumSchedulerException.java
URL: http://svn.apache.org/viewcvs/maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scheduler/ContinuumSchedulerException.java?rev=219457&view=auto
==============================================================================
--- maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scheduler/ContinuumSchedulerException.java (added)
+++ maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scheduler/ContinuumSchedulerException.java Sun Jul 17 21:39:44 2005
@@ -0,0 +1,24 @@
+package org.apache.maven.continuum.scheduler;
+
+/**
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
+ * @version $Id:$
+ */
+public class ContinuumSchedulerException
+    extends Exception
+{
+    public ContinuumSchedulerException( String message )
+    {
+        super( message );
+    }
+
+    public ContinuumSchedulerException( Throwable cause )
+    {
+        super( cause );
+    }
+
+    public ContinuumSchedulerException( String message, Throwable cause )
+    {
+        super( message, cause );
+    }
+}

Added: maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scheduler/DefaultContinuumScheduler.java
URL: http://svn.apache.org/viewcvs/maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scheduler/DefaultContinuumScheduler.java?rev=219457&view=auto
==============================================================================
--- maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scheduler/DefaultContinuumScheduler.java (added)
+++ maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/scheduler/DefaultContinuumScheduler.java Sun Jul 17 21:39:44 2005
@@ -0,0 +1,213 @@
+package org.apache.maven.continuum.scheduler;
+
+import org.codehaus.plexus.logging.AbstractLogEnabled;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Startable;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.StartingException;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.StoppingException;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
+import org.codehaus.plexus.context.ContextException;
+import org.codehaus.plexus.context.Context;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.PlexusConstants;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+import org.quartz.JobDetail;
+import org.quartz.SchedulerException;
+import org.quartz.SchedulerFactory;
+import org.quartz.Trigger;
+import org.quartz.JobListener;
+import org.quartz.TriggerListener;
+import org.quartz.JobDataMap;
+import org.quartz.CronTrigger;
+import org.quartz.Scheduler;
+import org.quartz.impl.StdScheduler;
+import org.quartz.impl.StdSchedulerFactory;
+import org.apache.maven.continuum.project.ContinuumSchedule;
+import org.apache.maven.continuum.Continuum;
+
+import java.util.Properties;
+import java.util.Date;
+import java.text.ParseException;
+
+public class DefaultContinuumScheduler
+    extends AbstractLogEnabled
+    implements ContinuumScheduler, Contextualizable, Initializable, Startable
+{
+    private Properties properties;
+
+    private StdScheduler scheduler;
+
+    private Continuum continuum;
+
+    // ----------------------------------------------------------------------
+    //
+    // ----------------------------------------------------------------------
+
+    public void scheduleJob( ContinuumSchedule schedule )
+        throws ContinuumSchedulerException
+    {
+        scheduleJob( createJobDetail( schedule ), createTrigger( schedule ) );
+    }
+
+    /**
+     * Create job detail for a build job. The detail contains a map of objects that can be utilized
+     * by the executing job.
+     *
+     * @param schedule
+     * @return
+     */
+    protected JobDetail createJobDetail( ContinuumSchedule schedule )
+    {
+        JobDetail jobDetail = new JobDetail( schedule.getName(), Scheduler.DEFAULT_GROUP, ContinuumBuildJob.class );
+
+        jobDetail.setJobDataMap( createJobDataMap( schedule ) );
+
+        return jobDetail;
+    }
+
+    /**
+     * Create Job data map for a build job. The map of objects created can be utilized by
+     * the executing job.
+     *
+     * @param schedule
+     * @return
+     */
+    protected JobDataMap createJobDataMap( ContinuumSchedule schedule )
+    {
+        JobDataMap dataMap = new JobDataMap();
+
+        dataMap.put( ContinuumSchedulerConstants.CONTINUUM, continuum );
+
+        dataMap.put( ContinuumSchedulerConstants.LOGGER, getLogger() );
+
+        dataMap.put( ContinuumSchedulerConstants.SCHEDULE, schedule );
+
+        return dataMap;
+    }
+
+    /**
+     * Create the trigger for the build job.
+     *
+     * @param schedule
+     * @return
+     * @throws ContinuumSchedulerException
+     */
+    protected Trigger createTrigger( ContinuumSchedule schedule )
+        throws ContinuumSchedulerException
+    {
+        CronTrigger trigger = new CronTrigger();
+
+        trigger.setName( schedule.getName() );
+
+        trigger.setGroup( Scheduler.DEFAULT_GROUP );
+
+        Date startTime = new Date( System.currentTimeMillis() + ( schedule.getDelay() * 1000 ) );
+
+        trigger.setStartTime( startTime );
+
+        trigger.setNextFireTime( startTime );
+
+        try
+        {
+            trigger.setCronExpression( schedule.getCronExpression() );
+        }
+        catch ( ParseException e )
+        {
+            throw new ContinuumSchedulerException( "Error parsing cron expression.", e );
+        }
+
+        return trigger;
+    }
+
+    public void scheduleJob( JobDetail jobDetail, Trigger trigger )
+        throws ContinuumSchedulerException
+    {
+        try
+        {
+            scheduler.scheduleJob( jobDetail, trigger );
+        }
+        catch ( SchedulerException e )
+        {
+            throw new ContinuumSchedulerException( "Error scheduling job.", e );
+        }
+    }
+
+    // ----------------------------------------------------------------------
+    //
+    // ----------------------------------------------------------------------
+
+    public void addGlobalJobListener( JobListener listener )
+    {
+        scheduler.addGlobalJobListener( listener );
+    }
+
+    public void addGlobalTriggerListener( TriggerListener listener )
+    {
+        scheduler.addGlobalTriggerListener( listener );
+    }
+
+    // ----------------------------------------------------------------------
+    // Lifecycle
+    // ----------------------------------------------------------------------
+
+    private PlexusContainer container;
+
+    public void contextualize( Context context )
+        throws ContextException
+    {
+        container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
+    }
+
+    protected Continuum getContinuum()
+    {
+        if ( continuum == null )
+        {
+            try
+            {
+                continuum = (Continuum) container.lookup( Continuum.ROLE );
+            }
+            catch ( ComponentLookupException e )
+            {
+                // Should never happen.
+                getLogger().error( "Cannot lookup Continuum component.", e );
+            }
+        }
+
+        return continuum;
+    }
+
+    public void initialize()
+        throws InitializationException
+    {
+        try
+        {
+            SchedulerFactory factory = new StdSchedulerFactory( properties );
+
+            scheduler = (StdScheduler) factory.getScheduler();
+        }
+        catch ( SchedulerException e )
+        {
+            throw new InitializationException( "Cannot create scheduler.", e );
+        }
+    }
+
+    public void start()
+        throws StartingException
+    {
+        try
+        {
+            scheduler.start();
+        }
+        catch ( SchedulerException e )
+        {
+            throw new StartingException( "Cannot start scheduler.", e );
+        }
+    }
+
+    public void stop()
+        throws StoppingException
+    {
+        scheduler.shutdown();
+    }
+}

Modified: maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/store/JdoContinuumStore.java
URL: http://svn.apache.org/viewcvs/maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/store/JdoContinuumStore.java?rev=219457&r1=219456&r2=219457&view=diff
==============================================================================
--- maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/store/JdoContinuumStore.java (original)
+++ maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/store/JdoContinuumStore.java Sun Jul 17 21:39:44 2005
@@ -1,20 +1,7 @@
-package org.apache.maven.continuum.store;
-
 /*
- * 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.
+ * Copyright (c) 2005 Your Corporation. All Rights Reserved.
  */
+package org.apache.maven.continuum.store;
 
 import java.util.Collection;
 import java.util.Iterator;
@@ -503,6 +490,8 @@
 
     private ContinuumProject getContinuumProject( PersistenceManager pm, String projectId )
     {
+        pm.getFetchPlan().addGroup( "project-detail" );
+
         Object id = pm.newObjectIdInstance( ContinuumProject.class, projectId );
 
         ContinuumProject project = (ContinuumProject) pm.getObjectById( id );

Modified: maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/trigger/alarmclock/AlarmClockTrigger.java
URL: http://svn.apache.org/viewcvs/maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/trigger/alarmclock/AlarmClockTrigger.java?rev=219457&r1=219456&r2=219457&view=diff
==============================================================================
--- maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/trigger/alarmclock/AlarmClockTrigger.java (original)
+++ maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/trigger/alarmclock/AlarmClockTrigger.java Sun Jul 17 21:39:44 2005
@@ -68,6 +68,7 @@
     public void start()
     {
         getLogger().info( "Build interval: " + interval + "s" );
+
         getLogger().info( "Will schedule the first build in: " + delay + "s" );
 
         timer.schedule( new BuildTask(), delay * 1000, interval * 1000 );

Added: maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/trigger/quartz/ContinuumBuildTrigger.java
URL: http://svn.apache.org/viewcvs/maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/trigger/quartz/ContinuumBuildTrigger.java?rev=219457&view=auto
==============================================================================
--- maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/trigger/quartz/ContinuumBuildTrigger.java (added)
+++ maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/trigger/quartz/ContinuumBuildTrigger.java Sun Jul 17 21:39:44 2005
@@ -0,0 +1,16 @@
+package org.apache.maven.continuum.trigger.quartz;
+
+import org.quartz.SimpleTrigger;
+
+/**
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
+ * @version $Id:$
+ */
+public class ContinuumBuildTrigger
+    extends SimpleTrigger
+{
+    public void setRepeatCount( int repeatCount )
+    {
+        super.setRepeatCount( SimpleTrigger.REPEAT_INDEFINITELY );
+    }
+}

Added: maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/trigger/quartz/QuartzAlarmClockTrigger.java
URL: http://svn.apache.org/viewcvs/maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/trigger/quartz/QuartzAlarmClockTrigger.java?rev=219457&view=auto
==============================================================================
--- maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/trigger/quartz/QuartzAlarmClockTrigger.java (added)
+++ maven/continuum/trunk/continuum-core/src/main/java/org/apache/maven/continuum/trigger/quartz/QuartzAlarmClockTrigger.java Sun Jul 17 21:39:44 2005
@@ -0,0 +1,125 @@
+package org.apache.maven.continuum.trigger.quartz;
+
+import org.apache.maven.continuum.scheduler.ContinuumScheduler;
+import org.apache.maven.continuum.scheduler.ContinuumBuildJob;
+import org.apache.maven.continuum.trigger.AbstractContinuumTrigger;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Startable;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.StartingException;
+import org.quartz.JobDataMap;
+import org.quartz.JobDetail;
+import org.quartz.SchedulerException;
+import org.quartz.CronTrigger;
+
+import java.util.Date;
+import java.text.ParseException;
+
+/**
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ * @version $Id: AlarmClockTrigger.java 209941 2005-07-09 13:14:31Z trygvis $
+ */
+public class QuartzAlarmClockTrigger
+    extends AbstractContinuumTrigger
+    implements Initializable, Startable
+{
+    /**
+     * @plexus.configuration
+     */
+    private int interval;
+
+    /**
+     * @plexus.configuration
+     */
+    private int delay;
+
+    /** @plexus.requirement */
+    private ContinuumScheduler scheduler;
+
+    // ----------------------------------------------------------------------
+    // Plexus Component Implementation
+    // ----------------------------------------------------------------------
+
+    public void initialize()
+        throws InitializationException
+    {
+        if ( interval <= 0 )
+        {
+            throw new InitializationException( "Invalid value for 'interval': the interval must be bigger that 0." );
+        }
+
+        if ( delay <= 0 )
+        {
+            throw new InitializationException( "Invalid value for 'delay': the delay must be bigger that 0." );
+        }
+    }
+
+    public void start()
+        throws StartingException
+    {
+        getLogger().info( "Build interval: " + interval + "s" );
+
+        getLogger().info( "Will schedule the first build in: " + delay + "s" );
+
+        JobDataMap dataMap = new JobDataMap();
+
+        dataMap.put( "continuum", getContinuum() );
+
+        dataMap.put( "logger", getLogger() );
+
+        JobDetail jobDetail = new JobDetail( "job", "group", ContinuumBuildJob.class );
+
+        jobDetail.setJobDataMap( dataMap );
+
+        //ContinuumBuildTrigger trigger = new ContinuumBuildTrigger();
+
+        CronTrigger trigger = new CronTrigger();
+
+        trigger.setName( "buildTrigger" );
+
+        trigger.setGroup( "continuum" );
+
+        System.out.println( "new Date() = " + new Date() );
+
+        System.out.println( "System.currentTimeMillis() = " + System.currentTimeMillis() );
+
+        System.out.println( "delay = " + delay * 1000 );
+
+        Date startTime = new Date(System.currentTimeMillis() + ( delay * 1000 ) );
+
+        System.out.println( "startTime = " + startTime );
+
+        trigger.setStartTime( startTime );
+
+        trigger.setNextFireTime( startTime );
+
+        try
+        {
+            trigger.setCronExpression( "0 * * * * ?" );
+        }
+        catch ( ParseException e )
+        {
+            throw new StartingException( "Error parsing cron expression.", e );
+        }
+
+        //trigger.setRepeatInterval( interval * 1000 );
+
+        //trigger.setRepeatCount( ContinuumBuildTrigger.REPEAT_INDEFINITELY );
+
+        try
+        {
+            scheduler.scheduleJob( jobDetail, trigger );
+
+            getLogger().info( trigger.getNextFireTime() + "" );
+        }
+        catch ( Exception e )
+        {
+            throw new StartingException( "Cannot schedule build job.", e );
+        }
+    }
+
+    public void stop()
+    {
+    }
+}

Modified: maven/continuum/trunk/continuum-core/src/main/resources/META-INF/plexus/components.xml
URL: http://svn.apache.org/viewcvs/maven/continuum/trunk/continuum-core/src/main/resources/META-INF/plexus/components.xml?rev=219457&r1=219456&r2=219457&view=diff
==============================================================================
--- maven/continuum/trunk/continuum-core/src/main/resources/META-INF/plexus/components.xml (original)
+++ maven/continuum/trunk/continuum-core/src/main/resources/META-INF/plexus/components.xml Sun Jul 17 21:39:44 2005
@@ -34,6 +34,14 @@
     </component>
 
     <component>
+      <role>org.apache.maven.continuum.configuration.ConfigurationService</role>
+      <implementation>org.apache.maven.continuum.configuration.DefaultConfigurationService</implementation>
+      <configuration>
+        <source>${plexus.home}/conf/configuration.xml</source>
+      </configuration>
+    </component>
+
+    <component>
       <role>org.apache.maven.continuum.Continuum</role>
       <implementation>org.apache.maven.continuum.DefaultContinuum</implementation>
       <requirements>
@@ -43,11 +51,12 @@
         <requirement>
           <role>org.codehaus.plexus.action.ActionManager</role>
         </requirement>
-        <!--
         <requirement>
-          <role>org.codehaus.plexus.workflow.WorkflowEngine</role>
+          <role>org.apache.maven.continuum.scheduler.ContinuumScheduler</role>
+        </requirement>
+        <requirement>
+          <role>org.apache.maven.continuum.configuration.ConfigurationService</role>
         </requirement>
-        -->
       </requirements>
     </component>
 
@@ -645,5 +654,45 @@
         </requirement>
       </requirements>
     </component>
+    <!--
+     |
+     | Scheduler
+     |
+     -->
+
+    <component>
+      <role>org.apache.maven.continuum.scheduler.ContinuumScheduler</role>
+      <implementation>org.apache.maven.continuum.scheduler.DefaultContinuumScheduler</implementation>
+      <configuration>
+        <properties>
+          <property>
+            <name>org.quartz.scheduler.instanceName</name>
+            <value>scheduler1</value>
+          </property>
+          <property>
+            <name></name>
+            <value></value>
+          </property>
+          <property>
+            <name>org.quartz.threadPool.class</name>
+            <value>org.quartz.simpl.SimpleThreadPool</value>
+          </property>
+          <property>
+            <name>org.quartz.threadPool.threadCount</name>
+            <value>15</value>
+          </property>
+          <property>
+            <name>org.quartz.threadPool.threadPriority</name>
+            <value>4</value>
+          </property>
+          <property>
+            <name>org.quartz.jobStore.class</name>
+            <value>org.quartz.simpl.RAMJobStore</value>
+          </property>
+        </properties>
+      </configuration>
+    </component>
+
+
   </components>
 </component-set>

Modified: maven/continuum/trunk/continuum-core/src/test/java/org/apache/maven/continuum/AbstractContinuumTest.java
URL: http://svn.apache.org/viewcvs/maven/continuum/trunk/continuum-core/src/test/java/org/apache/maven/continuum/AbstractContinuumTest.java?rev=219457&r1=219456&r2=219457&view=diff
==============================================================================
--- maven/continuum/trunk/continuum-core/src/test/java/org/apache/maven/continuum/AbstractContinuumTest.java (original)
+++ maven/continuum/trunk/continuum-core/src/test/java/org/apache/maven/continuum/AbstractContinuumTest.java Sun Jul 17 21:39:44 2005
@@ -155,6 +155,11 @@
 
     protected static List createMailNotifierList( String emailAddress )
     {
+        if ( emailAddress == null )
+        {
+            return null;
+        }
+
         ContinuumNotifier notifier = new ContinuumNotifier();
 
         notifier.setType( "mail" );
@@ -365,21 +370,24 @@
 
         assertEquals( "project.scmUrl", scmUrl, actual.getScmUrl() );
 
-        assertNotNull( "project.notifiers", actual.getNotifiers() );
+        if ( notifiers != null )
+        {
+            assertNotNull( "project.notifiers", actual.getNotifiers() );
 
-        assertEquals( "project.notifiers.size", notifiers.size(), actual.getNotifiers().size() );
+            assertEquals( "project.notifiers.size", notifiers.size(), actual.getNotifiers().size() );
 
-        for ( int i = 0; i < notifiers.size(); i++ )
-        {
-            ContinuumNotifier notifier = (ContinuumNotifier) notifiers.get( i );
+            for ( int i = 0; i < notifiers.size(); i++ )
+            {
+                ContinuumNotifier notifier = (ContinuumNotifier) notifiers.get( i );
 
-            ContinuumNotifier actualNotifier = (ContinuumNotifier) actual.getNotifiers().get( i );
+                ContinuumNotifier actualNotifier = (ContinuumNotifier) actual.getNotifiers().get( i );
 
-            assertEquals( "project.notifiers.notifier.type", notifier.getType(), actualNotifier.getType() );
+                assertEquals( "project.notifiers.notifier.type", notifier.getType(), actualNotifier.getType() );
 
-            assertEquals( "project.notifiers.notifier.configuration.address",
-                          notifier.getConfiguration().get( "address" ),
-                          actualNotifier.getConfiguration().get( "address" ) );
+                assertEquals( "project.notifiers.notifier.configuration.address",
+                              notifier.getConfiguration().get( "address" ),
+                              actualNotifier.getConfiguration().get( "address" ) );
+            }
         }
 
         assertEquals( "project.version", version, actual.getVersion() );
@@ -390,4 +398,4 @@
 
         assertEquals( "project.workingDirectory", workingDirectory, actual.getWorkingDirectory() );
     }
- }
+}

Modified: maven/continuum/trunk/continuum-core/src/test/java/org/apache/maven/continuum/store/AbstractContinuumStoreTest.java
URL: http://svn.apache.org/viewcvs/maven/continuum/trunk/continuum-core/src/test/java/org/apache/maven/continuum/store/AbstractContinuumStoreTest.java?rev=219457&r1=219456&r2=219457&view=diff
==============================================================================
--- maven/continuum/trunk/continuum-core/src/test/java/org/apache/maven/continuum/store/AbstractContinuumStoreTest.java (original)
+++ maven/continuum/trunk/continuum-core/src/test/java/org/apache/maven/continuum/store/AbstractContinuumStoreTest.java Sun Jul 17 21:39:44 2005
@@ -1,20 +1,7 @@
-package org.apache.maven.continuum.store;
-
 /*
- * 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.
+ * Copyright (c) 2005 Your Corporation. All Rights Reserved.
  */
+package org.apache.maven.continuum.store;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -315,7 +302,7 @@
         assertProjectEquals( id1,
                              name1,
                              scmUrl1,
-                             nagEmailAddress1,
+                             (String)null,
                              version1,
                              commandLineArguments1,
                              MavenTwoBuildExecutor.ID,
@@ -327,7 +314,7 @@
         assertProjectEquals( id2,
                              name2,
                              scmUrl2,
-                             nagEmailAddress2,
+                             (String)null,
                              version2,
                              commandLineArguments2,
                              MavenTwoBuildExecutor.ID,

Modified: maven/continuum/trunk/continuum-core/src/test/java/org/apache/maven/continuum/store/JdoContinuumStoreTest.java
URL: http://svn.apache.org/viewcvs/maven/continuum/trunk/continuum-core/src/test/java/org/apache/maven/continuum/store/JdoContinuumStoreTest.java?rev=219457&r1=219456&r2=219457&view=diff
==============================================================================
--- maven/continuum/trunk/continuum-core/src/test/java/org/apache/maven/continuum/store/JdoContinuumStoreTest.java (original)
+++ maven/continuum/trunk/continuum-core/src/test/java/org/apache/maven/continuum/store/JdoContinuumStoreTest.java Sun Jul 17 21:39:44 2005
@@ -1,20 +1,16 @@
-package org.apache.maven.continuum.store;
-
 /*
- * 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.
+ * Copyright (c) 2005 Your Corporation. All Rights Reserved.
  */
+package org.apache.maven.continuum.store;
+
+import org.apache.maven.continuum.project.ContinuumNotifier;
+import org.apache.maven.continuum.project.ContinuumProject;
+import org.apache.maven.continuum.project.MavenTwoProject;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
@@ -26,5 +22,33 @@
     public JdoContinuumStoreTest()
     {
         super( "jdo", JdoContinuumStore.class );
+    }
+
+    public void testNotifiersAreBeingDetached()
+        throws Exception
+    {
+        List notifiers = new ArrayList();
+
+        ContinuumNotifier notifier = new ContinuumNotifier();
+
+        notifier.setType( "foo" );
+
+        Map configuration = new HashMap();
+
+        configuration.put( "moo", "foo" );
+
+        notifier.setConfiguration( configuration );
+
+        notifiers.add( notifier );
+
+        ContinuumProject project = new MavenTwoProject();
+
+        project.setNotifiers( notifiers );
+
+        String id = getStore().addProject( project );
+
+        project = getStore().getProject( id );
+
+        assertNotNull( project.getNotifiers() );
     }
 }