You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@maven.apache.org by jv...@apache.org on 2005/04/11 04:22:17 UTC

svn commit: r160813 [4/10] - in maven/continuum: ./ continuum-core/ continuum-core/src/ continuum-core/src/main/ continuum-core/src/main/java/ continuum-core/src/main/java/org/ continuum-core/src/main/java/org/apache/ continuum-core/src/main/java/org/apache/maven/ continuum-core/src/main/java/org/apache/maven/continuum/ continuum-core/src/main/java/org/apache/maven/continuum/buildcontroller/ continuum-core/src/main/java/org/apache/maven/continuum/builder/ continuum-core/src/main/java/org/apache/maven/continuum/builder/ant/ continuum-core/src/main/java/org/apache/maven/continuum/builder/manager/ continuum-core/src/main/java/org/apache/maven/continuum/builder/maven/ continuum-core/src/main/java/org/apache/maven/continuum/builder/maven/m1/ continuum-core/src/main/java/org/apache/maven/continuum/builder/maven/m2/ continuum-core/src/main/java/org/apache/maven/continuum/builder/shell/ continuum-core/src/main/java/org/apache/maven/continuum/buildqueue/ continuum-core/src/main/java/org/apache/maven/continuum/buildqueue/evaluator/ continuum-core/src/main/java/org/apache/maven/continuum/network/ continuum-core/src/main/java/org/apache/maven/continuum/notification/ continuum-core/src/main/java/org/apache/maven/continuum/notification/console/ continuum-core/src/main/java/org/apache/maven/continuum/notification/mail/ continuum-core/src/main/java/org/apache/maven/continuum/project/ continuum-core/src/main/java/org/apache/maven/continuum/registration/ continuum-core/src/main/java/org/apache/maven/continuum/registration/socket/ continuum-core/src/main/java/org/apache/maven/continuum/scm/ continuum-core/src/main/java/org/apache/maven/continuum/socket/ continuum-core/src/main/java/org/apache/maven/continuum/store/ continuum-core/src/main/java/org/apache/maven/continuum/trigger/ continuum-core/src/main/java/org/apache/maven/continuum/trigger/alarmclock/ continuum-core/src/main/java/org/apache/maven/continuum/trigger/socket/ continuum-core/src/main/java/org/apache/maven/continuum/utils/ continuum-core/src/main/resources/ continuum-core/src/main/resources/META-INF/ continuum-core/src/main/resources/META-INF/plexus/ continuum-core/src/main/resources/org/ continuum-core/src/main/resources/org/apache/ continuum-core/src/main/resources/org/apache/maven/ continuum-core/src/main/resources/org/apache/maven/continuum/ continuum-core/src/main/resources/org/apache/maven/continuum/notification/ continuum-core/src/main/resources/org/apache/maven/continuum/notification/mail/ continuum-core/src/main/resources/org/apache/maven/continuum/notification/mail/templates/ continuum-core/src/main/resources/org/apache/maven/continuum/notification/mail/templates/ant/ continuum-core/src/main/resources/org/apache/maven/continuum/notification/mail/templates/maven-1/ continuum-core/src/main/resources/org/apache/maven/continuum/notification/mail/templates/maven2/ continuum-core/src/main/resources/org/apache/maven/continuum/notification/mail/templates/shell/ continuum-core/src/test-file-storage/ continuum-core/src/test-file-storage/inamo/ continuum-core/src/test-file-storage/plexus/ continuum-core/src/test-input/ continuum-core/src/test-input/src/ continuum-core/src/test-input/src/main/ continuum-core/src/test-input/src/main/java/ continuum-core/src/test-projects/ continuum-core/src/test-projects/project1/ continuum-core/src/test-projects/project1/src/ continuum-core/src/test-projects/project1/src/main/ continuum-core/src/test-projects/project1/src/main/java/ continuum-core/src/test-projects/project1/src/main/java/org/ continuum-core/src/test-projects/project1/src/main/java/org/codehaus/ continuum-core/src/test-projects/project1/src/main/java/org/codehaus/continuum/ continuum-core/src/test-projects/project1/src/main/java/org/codehaus/continuum/project1/ continuum-core/src/test-projects/project2/ continuum-core/src/test-projects/project2/src/ continuum-core/src/test-projects/project2/src/main/ continuum-core/src/test-projects/project2/src/main/java/ continuum-core/src/test-projects/project2/src/main/java/org/ continuum-core/src/test-projects/project2/src/main/java/org/codehaus/ continuum-core/src/test-projects/project2/src/main/java/org/codehaus/continuum/ continuum-core/src/test-projects/project2/src/main/java/org/codehaus/continuum/project2/ continuum-core/src/test/ continuum-core/src/test/java/ continuum-core/src/test/java/org/ continuum-core/src/test/java/org/apache/ continuum-core/src/test/java/org/apache/maven/ continuum-core/src/test/java/org/apache/maven/continuum/ continuum-core/src/test/java/org/apache/maven/continuum/builder/ continuum-core/src/test/java/org/apache/maven/continuum/builder/maven/ continuum-core/src/test/java/org/apache/maven/continuum/builder/maven/m1/ continuum-core/src/test/java/org/apache/maven/continuum/builder/maven/m2/ continuum-core/src/test/java/org/apache/maven/continuum/buildqueue/ continuum-core/src/test/java/org/apache/maven/continuum/network/ continuum-core/src/test/java/org/apache/maven/continuum/notification/ continuum-core/src/test/java/org/apache/maven/continuum/notification/mail/ continuum-core/src/test/java/org/apache/maven/continuum/scm/ continuum-core/src/test/java/org/apache/maven/continuum/store/ continuum-core/src/test/repository/ continuum-core/src/test/repository/console-notifier/ continuum-core/src/test/resources/ continuum-core/src/test/resources/org/ continuum-core/src/test/resources/org/apache/ continuum-core/src/test/resources/org/apache/maven/ continuum-core/src/test/resources/org/apache/maven/continuum/ continuum-core/src/test/resources/org/apache/maven/continuum/buildqueue/ continuum-core/src/test/resources/org/apache/maven/continuum/network/ continuum-core/src/test/resources/org/apache/maven/continuum/notification/ continuum-core/src/test/resources/org/apache/maven/continuum/notification/mail/ continuum-core/src/test/resources/org/apache/maven/continuum/store/ continuum-core/src/test/resources/projects/ continuum-model/ continuum-model/src/ continuum-model/src/main/ continuum-model/src/main/resources/ continuum-plexus-application/ continuum-plexus-application/src/ continuum-plexus-application/src/assembly/ continuum-plexus-application/src/conf/ continuum-plexus-application/src/test/ continuum-plexus-application/src/test/conf/ continuum-runtime/ continuum-runtime/src/ continuum-runtime/src/conf/ continuum-site/ continuum-site/src/ continuum-site/src/site/ continuum-site/src/site/apt/ continuum-site/src/site/apt/developer-info/ continuum-site/src/site/apt/releases/ continuum-site/src/site/apt/releases/1-0-alpha-1/ continuum-site/src/site/xdoc/ continuum-web/ continuum-web/src/ continuum-web/src/main/ continuum-web/src/main/java/ continuum-web/src/main/java/org/ continuum-web/src/main/java/org/codehaus/ continuum-web/src/main/java/org/codehaus/continuum/ continuum-web/src/main/java/org/codehaus/continuum/web/ continuum-web/src/main/java/org/codehaus/continuum/web/action/ continuum-web/src/main/java/org/codehaus/continuum/web/context/ continuum-web/src/main/java/org/codehaus/continuum/web/pipeline/ continuum-web/src/main/java/org/codehaus/continuum/web/pipeline/valve/ continuum-web/src/main/java/org/codehaus/continuum/web/tool/ continuum-web/src/main/java/org/codehaus/continuum/web/validation/ continuum-web/src/main/resources/ continuum-web/src/main/resources/META-INF/ continuum-web/src/main/resources/META-INF/plexus/ continuum-web/src/main/resources/WEB-INF/ continuum-web/src/main/resources/css/ continuum-web/src/main/resources/forms/ continuum-web/src/main/resources/images/ continuum-web/src/main/resources/localization/ continuum-web/src/main/resources/scripts/ continuum-web/src/main/resources/templates/ continuum-web/src/main/resources/templates/layouts/ continuum-web/src/main/resources/templates/navigations/ continuum-web/src/main/resources/templates/screens/ continuum-xmlrpc/ continuum-xmlrpc/src/ continuum-xmlrpc/src/main/ continuum-xmlrpc/src/main/java/ continuum-xmlrpc/src/main/java/org/ continuum-xmlrpc/src/main/java/org/apache/ continuum-xmlrpc/src/main/java/org/apache/maven/ continuum-xmlrpc/src/main/java/org/apache/maven/continuum/ continuum-xmlrpc/src/main/java/org/apache/maven/continuum/xmlrpc/ continuum-xmlrpc/src/main/resources/ continuum-xmlrpc/src/main/resources/META-INF/ continuum-xmlrpc/src/main/resources/META-INF/plexus/ continuum-xmlrpc/src/test/ continuum-xmlrpc/src/test/java/ continuum-xmlrpc/src/test/java/org/ continuum-xmlrpc/src/test/java/org/apache/ continuum-xmlrpc/src/test/java/org/apache/maven/ continuum-xmlrpc/src/test/java/org/apache/maven/continuum/ continuum-xmlrpc/src/test/java/org/apache/maven/continuum/xmlrpc/

Added: maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/builder/shell/DefaultShellCommandHelper.java
URL: http://svn.apache.org/viewcvs/maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/builder/shell/DefaultShellCommandHelper.java?view=auto&rev=160813
==============================================================================
--- maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/builder/shell/DefaultShellCommandHelper.java (added)
+++ maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/builder/shell/DefaultShellCommandHelper.java Sun Apr 10 19:21:34 2005
@@ -0,0 +1,80 @@
+package org.apache.maven.continuum.builder.shell;
+
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.File;
+
+import org.codehaus.plexus.logging.AbstractLogEnabled;
+import org.codehaus.plexus.util.cli.CommandLineUtils;
+import org.codehaus.plexus.util.cli.Commandline;
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ * @version $Id: DefaultShellCommandHelper.java,v 1.1.1.1 2005/03/29 20:42:00 trygvis Exp $
+ */
+public class DefaultShellCommandHelper
+    extends AbstractLogEnabled
+    implements ShellCommandHelper
+{
+    // ----------------------------------------------------------------------
+    // ShellCommandHelper Implementation
+    // ----------------------------------------------------------------------
+
+    public ExecutionResult executeShellCommand( File workingDirectory, String shellCommand, String[] arguments )
+        throws Exception
+    {
+        Commandline cl = createCommandline( workingDirectory, shellCommand, arguments );
+
+        CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
+
+        CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer();
+
+        int exitCode;
+
+        getLogger().info( "Executing: " + cl );
+
+        exitCode = CommandLineUtils.executeCommandLine( cl, stdout, stderr );
+
+        String out = stdout.getOutput();
+
+        String err = stderr.getOutput();
+
+        ExecutionResult result = new ExecutionResult( out, err, exitCode );
+
+        return result;
+    }
+
+    // ----------------------------------------------------------------------
+    //
+    // ----------------------------------------------------------------------
+
+    private Commandline createCommandline( File workingDirectory, String shellCommand, String[] arguments )
+    {
+        Commandline cl = new Commandline();
+
+        cl.setExecutable( shellCommand );
+
+        cl.setWorkingDirectory( workingDirectory.getAbsolutePath() );
+
+        for ( int i = 0; i < arguments.length; i++ )
+        {
+            cl.createArgument().setValue( arguments[ i ] );
+        }
+
+        return cl;
+    }
+}

Added: maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/builder/shell/ExecutionResult.java
URL: http://svn.apache.org/viewcvs/maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/builder/shell/ExecutionResult.java?view=auto&rev=160813
==============================================================================
--- maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/builder/shell/ExecutionResult.java (added)
+++ maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/builder/shell/ExecutionResult.java Sun Apr 10 19:21:34 2005
@@ -0,0 +1,54 @@
+package org.apache.maven.continuum.builder.shell;
+
+/*
+ * 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.
+ */
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ * @version $Id: ExecutionResult.java,v 1.1.1.1 2005/03/29 20:42:00 trygvis Exp $
+ */
+public class ExecutionResult
+{
+    private String standardOutput;
+
+    private String standardError;
+
+    private int exitCode;
+
+    public ExecutionResult( String standardOutput, String standardError, int exitCode )
+    {
+        this.standardOutput = standardOutput;
+
+        this.standardError = standardError;
+
+        this.exitCode = exitCode;
+    }
+
+    public String getStandardOutput()
+    {
+        return standardOutput;
+    }
+
+    public String getStandardError()
+    {
+        return standardError;
+    }
+
+    public int getExitCode()
+    {
+        return exitCode;
+    }
+}

Added: maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/builder/shell/ShellBuilder.java
URL: http://svn.apache.org/viewcvs/maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/builder/shell/ShellBuilder.java?view=auto&rev=160813
==============================================================================
--- maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/builder/shell/ShellBuilder.java (added)
+++ maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/builder/shell/ShellBuilder.java Sun Apr 10 19:21:34 2005
@@ -0,0 +1,147 @@
+package org.apache.maven.continuum.builder.shell;
+
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.File;
+import java.net.URL;
+
+import org.apache.maven.continuum.ContinuumException;
+import org.apache.maven.continuum.builder.AbstractContinuumBuilder;
+import org.apache.maven.continuum.project.ContinuumBuildResult;
+import org.apache.maven.continuum.project.ContinuumProject;
+
+import org.codehaus.plexus.util.cli.Commandline;
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ * @version $Id: ShellBuilder.java,v 1.2 2005/04/07 23:27:40 trygvis Exp $
+ */
+public class ShellBuilder
+    extends AbstractContinuumBuilder
+{
+    public static final String CONFIGURATION_EXECUTABLE = "executable";
+
+    public final static String CONFIGURATION_ARGUMENTS = "arguments";
+
+    /** @requirement */
+    private ShellCommandHelper shellCommandHelper;
+
+    // ----------------------------------------------------------------------
+    //
+    // ----------------------------------------------------------------------
+
+    protected boolean prependWorkingDirectoryIfMissing()
+    {
+        return true;
+    }
+
+    protected String getExecutable( ContinuumProject project )
+        throws ContinuumException
+    {
+        return getConfigurationString( project.getConfiguration(), CONFIGURATION_EXECUTABLE );
+    }
+
+    protected String[] getArguments( ContinuumProject project )
+        throws ContinuumException
+    {
+        return getConfigurationStringArray( project.getConfiguration(), CONFIGURATION_ARGUMENTS, " ", new String[ 0 ] );
+    }
+
+    // ----------------------------------------------------------------------
+    // ContinuumBuilder implementation
+    // ----------------------------------------------------------------------
+
+    public synchronized ContinuumBuildResult build( ContinuumProject project )
+        throws ContinuumException
+    {
+        File workingDirectory = new File( project.getWorkingDirectory() );
+
+        ExecutionResult executionResult;
+
+        String executable = getExecutable( project );
+
+        String[] arguments = getArguments( project );
+
+        if ( !executable.startsWith( "/" ) &&
+             !executable.startsWith( "\\" ) &&
+             prependWorkingDirectoryIfMissing() )
+        {
+            executable = workingDirectory + File.separator + executable;
+        }
+
+        try
+        {
+            executionResult = shellCommandHelper.executeShellCommand( workingDirectory,
+                                                                      executable,
+                                                                      arguments );
+        }
+        catch ( Exception e )
+        {
+            throw new ContinuumException( "Error while executing shell command.", e );
+        }
+
+        boolean success = executionResult.getExitCode() == 0;
+
+        ShellBuildResult result = new ShellBuildResult();
+
+        result.setSuccess( success );
+
+        result.setStandardOutput( executionResult.getStandardOutput() );
+
+        result.setStandardError( executionResult.getStandardError() );
+
+        result.setExitCode( executionResult.getExitCode() );
+
+        return result;
+    }
+
+    public ContinuumProject createProjectFromMetadata( URL metadata )
+        throws ContinuumException
+    {
+        throw new ContinuumException( "The Ant builder cannot create metadata from a URL." );
+    }
+
+    public void updateProjectFromCheckOut( File workingDirectory, ContinuumProject project )
+        throws ContinuumException
+    {
+        // Not much to do.
+    }
+
+    // ----------------------------------------------------------------------
+    //
+    // ----------------------------------------------------------------------
+
+    protected Commandline createCommandline( ContinuumProject project, String executable, String[] arguments )
+    {
+        Commandline cl = new Commandline();
+
+        cl.setExecutable( executable );
+
+        cl.setWorkingDirectory( new File( project.getWorkingDirectory() ).getAbsolutePath() );
+
+        for ( int i = 1; i < arguments.length; i++ )
+        {
+            cl.createArgument().setValue( arguments[i] );
+        }
+
+        getLogger().warn( "Executing external command '" + executable + "'." );
+
+        getLogger().warn( "Executing external command. Working directory: " + cl.getWorkingDirectory().getAbsolutePath() );
+
+        return cl;
+    }
+}

Added: maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/builder/shell/ShellCommandHelper.java
URL: http://svn.apache.org/viewcvs/maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/builder/shell/ShellCommandHelper.java?view=auto&rev=160813
==============================================================================
--- maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/builder/shell/ShellCommandHelper.java (added)
+++ maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/builder/shell/ShellCommandHelper.java Sun Apr 10 19:21:34 2005
@@ -0,0 +1,31 @@
+package org.apache.maven.continuum.builder.shell;
+
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.File;
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ * @version $Id: ShellCommandHelper.java,v 1.1.1.1 2005/03/29 20:42:00 trygvis Exp $
+ */
+public interface ShellCommandHelper
+{
+    String ROLE = ShellCommandHelper.class.getName();
+
+    ExecutionResult executeShellCommand( File workingDirectory, String shellCommand, String[] arguments )
+        throws Exception;
+}

Added: maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/buildqueue/AbstractBuildQueue.java
URL: http://svn.apache.org/viewcvs/maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/buildqueue/AbstractBuildQueue.java?view=auto&rev=160813
==============================================================================
--- maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/buildqueue/AbstractBuildQueue.java (added)
+++ maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/buildqueue/AbstractBuildQueue.java Sun Apr 10 19:21:34 2005
@@ -0,0 +1,29 @@
+package org.apache.maven.continuum.buildqueue;
+
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.codehaus.plexus.logging.AbstractLogEnabled;
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ * @version $Id: AbstractBuildQueue.java,v 1.1.1.1 2005/03/29 20:42:01 trygvis Exp $
+ */
+public abstract class AbstractBuildQueue
+    extends AbstractLogEnabled
+    implements BuildQueue
+{
+}

Added: maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/buildqueue/BuildProjectTask.java
URL: http://svn.apache.org/viewcvs/maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/buildqueue/BuildProjectTask.java?view=auto&rev=160813
==============================================================================
--- maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/buildqueue/BuildProjectTask.java (added)
+++ maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/buildqueue/BuildProjectTask.java Sun Apr 10 19:21:34 2005
@@ -0,0 +1,57 @@
+package org.apache.maven.continuum.buildqueue;
+
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.codehaus.plexus.taskqueue.Task;
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ * @version $Id: BuildProjectTask.java,v 1.1.1.1 2005/03/29 20:42:01 trygvis Exp $
+ */
+public class BuildProjectTask
+    implements Task
+{
+    private String projectId;
+
+    private String buildId;
+
+    private long timestamp;
+
+    public BuildProjectTask( String projectId, String buildId, long timestamp )
+    {
+        this.projectId = projectId;
+
+        this.buildId = buildId;
+
+        this.timestamp = timestamp;
+    }
+
+    public String getProjectId()
+    {
+        return projectId;
+    }
+
+    public String getBuildId()
+    {
+        return buildId;
+    }
+
+    public long getTimestamp()
+    {
+        return timestamp;
+    }
+}

Added: maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/buildqueue/BuildQueue.java
URL: http://svn.apache.org/viewcvs/maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/buildqueue/BuildQueue.java?view=auto&rev=160813
==============================================================================
--- maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/buildqueue/BuildQueue.java (added)
+++ maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/buildqueue/BuildQueue.java Sun Apr 10 19:21:34 2005
@@ -0,0 +1,47 @@
+package org.apache.maven.continuum.buildqueue;
+
+/*
+ * 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.
+ */
+
+/**
+ * A queue of build job ids.
+ *
+ * <it>A <code>BuildQueue</code> implementation MUST be thread safe.</it>
+ *
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ * @version $Id: BuildQueue.java,v 1.1.1.1 2005/03/29 20:42:01 trygvis Exp $
+ */
+public interface BuildQueue
+{
+    String ROLE = BuildQueue.class.getName();
+
+    /**
+     * Returns a bulid id from the queue.
+     * <p/>
+     * Returns <code>null</code> if the queue is empty.
+     *
+     * @return Returns a build id from the queue or <code>null</code> if the queue is empty.
+     */
+    String dequeue()
+        throws BuildQueueException;
+
+    /**
+     * @param projectId The id of the build to enqueue.
+     * @param buildId
+     */
+    void enqueue( String projectId, String buildId )
+        throws BuildQueueException;
+}

Added: maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/buildqueue/BuildQueueException.java
URL: http://svn.apache.org/viewcvs/maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/buildqueue/BuildQueueException.java?view=auto&rev=160813
==============================================================================
--- maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/buildqueue/BuildQueueException.java (added)
+++ maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/buildqueue/BuildQueueException.java Sun Apr 10 19:21:34 2005
@@ -0,0 +1,35 @@
+package org.apache.maven.continuum.buildqueue;
+
+/*
+ * 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.
+ */
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ * @version $Id: BuildQueueException.java,v 1.1.1.1 2005/03/29 20:42:01 trygvis Exp $
+ */
+public class BuildQueueException
+    extends Exception
+{
+    public BuildQueueException( String message )
+    {
+        super( message );
+    }
+
+    public BuildQueueException( String message, Throwable cause )
+    {
+        super( message, cause );
+    }
+}

Added: maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/buildqueue/DefaultBuildQueue.java
URL: http://svn.apache.org/viewcvs/maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/buildqueue/DefaultBuildQueue.java?view=auto&rev=160813
==============================================================================
--- maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/buildqueue/DefaultBuildQueue.java (added)
+++ maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/buildqueue/DefaultBuildQueue.java Sun Apr 10 19:21:34 2005
@@ -0,0 +1,71 @@
+package org.apache.maven.continuum.buildqueue;
+
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.codehaus.plexus.taskqueue.TaskQueue;
+import org.codehaus.plexus.taskqueue.TaskQueueException;
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ * @version $Id: DefaultBuildQueue.java,v 1.1.1.1 2005/03/29 20:42:01 trygvis Exp $
+ */
+public class DefaultBuildQueue
+    extends AbstractBuildQueue
+    implements BuildQueue
+{
+    /** @requirement */
+    private TaskQueue taskQueue;
+
+    // ----------------------------------------------------------------------
+    // BuildQueue Implementation
+    // ----------------------------------------------------------------------
+
+    public String dequeue()
+        throws BuildQueueException
+    {
+        try
+        {
+            BuildProjectTask task = (BuildProjectTask) taskQueue.take();
+
+            if ( task == null )
+            {
+                return null;
+            }
+
+            return task.getBuildId();
+        }
+        catch ( TaskQueueException e )
+        {
+            throw new BuildQueueException( "Error while getting a task from the task queue.", e );
+        }
+    }
+
+    public void enqueue( String projectId, String buildId )
+        throws BuildQueueException
+    {
+        BuildProjectTask task = new BuildProjectTask( projectId, buildId, System.currentTimeMillis() );
+
+        try
+        {
+            taskQueue.put( task );
+        }
+        catch ( TaskQueueException e )
+        {
+            throw new BuildQueueException( "Error while enqueing project.", e );
+        }
+    }
+}

Added: maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/buildqueue/SimpleBuildQueue.java
URL: http://svn.apache.org/viewcvs/maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/buildqueue/SimpleBuildQueue.java?view=auto&rev=160813
==============================================================================
--- maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/buildqueue/SimpleBuildQueue.java (added)
+++ maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/buildqueue/SimpleBuildQueue.java Sun Apr 10 19:21:34 2005
@@ -0,0 +1,53 @@
+package org.apache.maven.continuum.buildqueue;
+
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ * @version $Id: SimpleBuildQueue.java,v 1.1.1.1 2005/03/29 20:42:01 trygvis Exp $
+ */
+public class SimpleBuildQueue
+    extends AbstractBuildQueue
+    implements BuildQueue
+{
+    /**
+     * The queue of elements.
+     */
+    private List queue = new LinkedList();
+
+    public String dequeue()
+    {
+        synchronized ( queue )
+        {
+            if ( queue.size() == 0 )
+                return null;
+
+            return (String) queue.remove( 0 );
+        }
+    }
+
+    public void enqueue( String projectId, String buildId )
+    {
+        synchronized ( queue )
+        {
+            queue.add( projectId );
+        }
+    }
+}

Added: maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/buildqueue/evaluator/BuildProjectTaskViabilityEvaluator.java
URL: http://svn.apache.org/viewcvs/maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/buildqueue/evaluator/BuildProjectTaskViabilityEvaluator.java?view=auto&rev=160813
==============================================================================
--- maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/buildqueue/evaluator/BuildProjectTaskViabilityEvaluator.java (added)
+++ maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/buildqueue/evaluator/BuildProjectTaskViabilityEvaluator.java Sun Apr 10 19:21:34 2005
@@ -0,0 +1,115 @@
+package org.apache.maven.continuum.buildqueue.evaluator;
+
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.continuum.buildqueue.BuildProjectTask;
+
+import org.codehaus.plexus.logging.AbstractLogEnabled;
+import org.codehaus.plexus.taskqueue.TaskQueueException;
+import org.codehaus.plexus.taskqueue.TaskViabilityEvaluator;
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ * @version $Id: BuildProjectTaskViabilityEvaluator.java,v 1.1.1.1 2005/03/29 20:42:01 trygvis Exp $
+ */
+public class BuildProjectTaskViabilityEvaluator
+    extends AbstractLogEnabled
+    implements TaskViabilityEvaluator
+{
+    /** @configuration */
+    private long requiredBuildInterval;
+
+    // ----------------------------------------------------------------------
+    // TaskViabilityEvaluator Implementation
+    // ----------------------------------------------------------------------
+
+    public List evaluate( List tasks )
+        throws TaskQueueException
+    {
+        // ----------------------------------------------------------------------
+        // This code makes a Map with Lists with one list per project. For each
+        // task in the list it puts it in the list for the project that's
+        // requested for a build. Then all each of the lists with tasks is
+        // checked for validity and a list of tasks to remove is returned.
+        // ----------------------------------------------------------------------
+
+        Map projects = new HashMap();
+
+        for ( Iterator it = tasks.iterator(); it.hasNext(); )
+        {
+            BuildProjectTask task = (BuildProjectTask) it.next();
+
+            List projectTasks = (List) projects.get( task.getProjectId() );
+
+            if ( projectTasks == null )
+            {
+                projectTasks = new ArrayList();
+
+                projects.put( task.getProjectId(), projectTasks );
+            }
+
+            projectTasks.add( task );
+        }
+
+        List toBeRemoved = new ArrayList();
+
+        for ( Iterator it = projects.values().iterator(); it.hasNext(); )
+        {
+            toBeRemoved.addAll( checkTasks( (List) it.next() ) );
+        }
+
+        return toBeRemoved;
+    }
+
+    // ----------------------------------------------------------------------
+    //
+    // ----------------------------------------------------------------------
+
+    private List checkTasks( List list )
+    {
+        BuildProjectTask okTask = null;
+
+        List toBeRemoved = new ArrayList();
+
+        for ( Iterator it = list.iterator(); it.hasNext(); )
+        {
+            BuildProjectTask buildProjectTask = (BuildProjectTask) it.next();
+
+            if ( okTask == null )
+            {
+                okTask = buildProjectTask;
+
+                continue;
+            }
+
+            long interval = buildProjectTask.getTimestamp() - okTask.getTimestamp();
+
+            if ( interval < requiredBuildInterval )
+            {
+                toBeRemoved.add( buildProjectTask );
+            }
+        }
+
+        return toBeRemoved;
+    }
+}

Added: maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/network/ConnectionConsumer.java
URL: http://svn.apache.org/viewcvs/maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/network/ConnectionConsumer.java?view=auto&rev=160813
==============================================================================
--- maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/network/ConnectionConsumer.java (added)
+++ maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/network/ConnectionConsumer.java Sun Apr 10 19:21:34 2005
@@ -0,0 +1,33 @@
+package org.apache.maven.continuum.network;
+
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ * @version $Id: ConnectionConsumer.java,v 1.1.1.1 2005/03/29 20:42:01 trygvis Exp $
+ */
+public interface ConnectionConsumer
+{
+    String ROLE = ConnectionConsumer.class.getName();
+
+    void consumeConnection( InputStream input, OutputStream output )
+        throws IOException;
+}

Added: maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/network/ConnectionFactory.java
URL: http://svn.apache.org/viewcvs/maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/network/ConnectionFactory.java?view=auto&rev=160813
==============================================================================
--- maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/network/ConnectionFactory.java (added)
+++ maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/network/ConnectionFactory.java Sun Apr 10 19:21:34 2005
@@ -0,0 +1,26 @@
+package org.apache.maven.continuum.network;
+
+/*
+ * 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.
+ */
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ * @version $Id: ConnectionFactory.java,v 1.1.1.1 2005/03/29 20:42:01 trygvis Exp $
+ */
+public interface ConnectionFactory
+{
+    String ROLE = ConnectionFactory.class.getName();
+}

Added: maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/network/NetCat.java
URL: http://svn.apache.org/viewcvs/maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/network/NetCat.java?view=auto&rev=160813
==============================================================================
--- maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/network/NetCat.java (added)
+++ maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/network/NetCat.java Sun Apr 10 19:21:34 2005
@@ -0,0 +1,89 @@
+package org.apache.maven.continuum.network;
+
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.StringInputStream;
+
+/**
+ * This class emulates the unix tool <code>nc</code>.
+ *
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ * @version $Id: NetCat.java,v 1.1.1.1 2005/03/29 20:42:01 trygvis Exp $
+ */
+public class NetCat
+{
+    private static int defaultBufferSize = 4096;
+
+    private NetCat()
+    {
+    }
+
+    public static String write( String host, int port, String contents )
+        throws IOException
+    {
+        return write( host, port, new StringInputStream( contents ) );
+    }
+
+    public static String write( String host, int port, InputStream contents )
+        throws IOException
+    {
+        OutputStream output = null;
+        InputStream input;
+        Socket socket = null;
+        final byte[] buffer = new byte[defaultBufferSize];
+        int n = 0;
+        ByteArrayOutputStream result = new ByteArrayOutputStream();
+
+        try
+        {
+            socket = new Socket( host, port );
+            output = socket.getOutputStream();
+            input = socket.getInputStream();
+
+            while ( ( n = contents.read( buffer ) ) != -1 )
+            {
+//                for( int i = 0; i < n; i++)
+//                    System.err.print( (char)buffer[i] );
+                output.write( buffer, 0, n );
+            }
+
+            System.err.println( "Reading return value" );
+
+            while ( ( n = input.read( buffer ) ) != -1 )
+            {
+//                for( int i = 0; i < n; i++)
+//                    System.err.print( (char)buffer[i] );
+                result.write( buffer, 0, n );
+            }
+        }
+        finally
+        {
+            IOUtil.close( output );
+
+            NetworkUtils.closeSocket( socket );
+        }
+
+        return result.toString();
+    }
+}

Added: maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/network/NetworkUtils.java
URL: http://svn.apache.org/viewcvs/maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/network/NetworkUtils.java?view=auto&rev=160813
==============================================================================
--- maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/network/NetworkUtils.java (added)
+++ maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/network/NetworkUtils.java Sun Apr 10 19:21:34 2005
@@ -0,0 +1,44 @@
+package org.apache.maven.continuum.network;
+
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.IOException;
+import java.net.Socket;
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ * @version $Id: NetworkUtils.java,v 1.1.1.1 2005/03/29 20:42:01 trygvis Exp $
+ */
+public class NetworkUtils
+{
+    private NetworkUtils()
+    {
+    }
+
+    static public void closeSocket( Socket socket )
+    {
+        try
+        {
+            if ( socket != null )
+                socket.close();
+        }
+        catch ( IOException ex )
+        {
+            // ignore
+        }
+    }
+}

Added: maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/network/SimpleServerSocketConnectionFactory.java
URL: http://svn.apache.org/viewcvs/maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/network/SimpleServerSocketConnectionFactory.java?view=auto&rev=160813
==============================================================================
--- maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/network/SimpleServerSocketConnectionFactory.java (added)
+++ maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/network/SimpleServerSocketConnectionFactory.java Sun Apr 10 19:21:34 2005
@@ -0,0 +1,108 @@
+package org.apache.maven.continuum.network;
+
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.IOException;
+import java.net.ServerSocket;
+
+import org.codehaus.plexus.configuration.PlexusConfigurationException;
+import org.codehaus.plexus.logging.AbstractLogEnabled;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Startable;
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ * @version $Id: SimpleServerSocketConnectionFactory.java,v 1.1.1.1 2005/03/29 20:42:01 trygvis Exp $
+ */
+public class SimpleServerSocketConnectionFactory
+    extends AbstractLogEnabled
+    implements ConnectionFactory, Initializable, Startable
+{
+    /**
+     * @default 0
+     */
+    private int port;
+
+    /**
+     * @default 50
+     */
+    private int backlog;
+
+    private ConnectionConsumer consumer;
+
+    private WorkerThread thread;
+
+    // ----------------------------------------------------------------------
+    // Component Lifecycle
+    // ----------------------------------------------------------------------
+
+    public void initialize()
+        throws Exception
+    {
+        if ( port <= 0 )
+            throw new PlexusConfigurationException( "The port must be bigger than 0." );
+
+        if ( port >= 65536 )
+            throw new PlexusConfigurationException( "The port must be lesser than 65536." );
+
+        if ( backlog < 0 )
+            throw new PlexusConfigurationException( "The valud of the backlog element must be bigger than 0." );
+
+        if ( consumer == null )
+            throw new PlexusConfigurationException( "There is no connection consumer configured." );
+    }
+
+    public void start()
+        throws Exception
+    {
+        getLogger().info( "Starting socket listener on port " + port );
+
+        ServerSocket serverSocket;
+
+        try
+        {
+            serverSocket = new ServerSocket( port, backlog );
+        }
+        catch ( IOException ex )
+        {
+            throw new Exception( "Could not create a server socket.", ex );
+        }
+
+        thread = new WorkerThread( serverSocket, consumer, getLogger() );
+
+        thread.start();
+    }
+
+    public void stop()
+    {
+        getLogger().info( "Stopping socket listener on port " + port );
+
+        thread.shutdown();
+
+        if ( thread.getServerSocket() != null )
+        {
+            try
+            {
+                thread.getServerSocket().close();
+            }
+            catch ( IOException ex )
+            {
+                // ignore
+            }
+        }
+    }
+}

Added: maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/network/WorkerThread.java
URL: http://svn.apache.org/viewcvs/maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/network/WorkerThread.java?view=auto&rev=160813
==============================================================================
--- maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/network/WorkerThread.java (added)
+++ maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/network/WorkerThread.java Sun Apr 10 19:21:34 2005
@@ -0,0 +1,124 @@
+package org.apache.maven.continuum.network;
+
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.util.IOUtil;
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l </a>
+ * @version $Id: WorkerThread.java,v 1.1.1.1 2005/03/29 20:42:01 trygvis Exp $
+ */
+public class WorkerThread
+    extends Thread
+{
+    private boolean running;
+
+    private ServerSocket serverSocket;
+
+    private ConnectionConsumer connectionConsumer;
+
+    private Logger logger;
+
+    public WorkerThread( ServerSocket serverSocket, ConnectionConsumer connectionConsumer, Logger logger )
+    {
+        this.serverSocket = serverSocket;
+
+        this.connectionConsumer = connectionConsumer;
+
+        this.logger = logger;
+    }
+
+    public void run()
+    {
+        running = true;
+
+        while ( running )
+        {
+            Socket socket;
+
+            try
+            {
+                socket = serverSocket.accept();
+            }
+            catch ( IOException ex )
+            {
+                if ( running )
+                    getLogger().warn( "Exception while accepting socket.", ex );
+
+                return;
+            }
+
+            //                getLogger().info( "Got connection from: " +
+            // socket.getInetAddress() );
+
+            InputStream input;
+
+            OutputStream output;
+
+            try
+            {
+                input = socket.getInputStream();
+
+                output = socket.getOutputStream();
+            }
+            catch ( IOException ex )
+            {
+                getLogger().fatalError( "Exception while getting the input and output streams from the socket.", ex );
+                continue;
+            }
+
+            try
+            {
+                connectionConsumer.consumeConnection( input, output );
+            }
+            catch ( IOException ex )
+            {
+                getLogger().fatalError( "Exception while consuming connection.", ex );
+            }
+
+            IOUtil.close( input );
+
+            IOUtil.close( output );
+
+            NetworkUtils.closeSocket( socket );
+        }
+
+//        getLogger().info( "Worker thread for port " + port + " exiting." );
+    }
+
+    public void shutdown()
+    {
+        running = false;
+    }
+
+    public ServerSocket getServerSocket()
+    {
+        return serverSocket;
+    }
+
+    private Logger getLogger()
+    {
+        return logger;
+    }
+}

Added: maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/notification/ContinuumNotificationDispatcher.java
URL: http://svn.apache.org/viewcvs/maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/notification/ContinuumNotificationDispatcher.java?view=auto&rev=160813
==============================================================================
--- maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/notification/ContinuumNotificationDispatcher.java (added)
+++ maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/notification/ContinuumNotificationDispatcher.java Sun Apr 10 19:21:34 2005
@@ -0,0 +1,58 @@
+package org.apache.maven.continuum.notification;
+
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.maven.continuum.project.ContinuumBuild;
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ * @version $Id: ContinuumNotificationDispatcher.java,v 1.1.1.1 2005/03/29 20:42:01 trygvis Exp $
+ */
+public interface ContinuumNotificationDispatcher
+{
+    String ROLE = ContinuumNotificationDispatcher.class.getName();
+
+    String MESSAGE_ID_BUILD_STARTED = "BuildStarted";
+
+    String MESSAGE_ID_CHECKOUT_STARTED = "CheckoutStarted";
+
+    String MESSAGE_ID_CHECKOUT_COMPLETE = "CheckoutComplete";
+
+    String MESSAGE_ID_RUNNING_GOALS = "RunningGoals";
+
+    String MESSAGE_ID_GOALS_COMPLETED = "GoalsCompleted";
+
+    String MESSAGE_ID_BUILD_COMPLETE = "BuildComplete";
+
+    String CONTEXT_BUILD = "build";
+
+    String CONTEXT_PROJECT = "project";
+
+    Object CONTEXT_BUILD_RESULT = "result";
+
+    void buildStarted( ContinuumBuild build );
+
+    void checkoutStarted( ContinuumBuild build );
+
+    void checkoutComplete( ContinuumBuild build );
+
+    void runningGoals( ContinuumBuild build );
+
+    void goalsCompleted( ContinuumBuild build );
+
+    void buildComplete( ContinuumBuild build );
+}

Added: maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/notification/ContinuumRecipientSource.java
URL: http://svn.apache.org/viewcvs/maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/notification/ContinuumRecipientSource.java?view=auto&rev=160813
==============================================================================
--- maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/notification/ContinuumRecipientSource.java (added)
+++ maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/notification/ContinuumRecipientSource.java Sun Apr 10 19:21:34 2005
@@ -0,0 +1,112 @@
+package org.apache.maven.continuum.notification;
+
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.maven.continuum.project.ContinuumProject;
+
+import org.codehaus.plexus.logging.AbstractLogEnabled;
+import org.codehaus.plexus.notification.NotificationException;
+import org.codehaus.plexus.notification.RecipientSource;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
+import org.codehaus.plexus.util.StringUtils;
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ * @version $Id: ContinuumRecipientSource.java,v 1.2 2005/04/01 22:55:52 trygvis Exp $
+ */
+public class ContinuumRecipientSource
+    extends AbstractLogEnabled
+    implements RecipientSource, Initializable
+{
+    /** @configuration */
+    private String toOverride;
+
+    // ----------------------------------------------------------------------
+    // Component Lifecycle
+    // ----------------------------------------------------------------------
+
+    public void initialize()
+        throws Exception
+    {
+        // ----------------------------------------------------------------------
+        // To address
+        // ----------------------------------------------------------------------
+
+        if ( StringUtils.isEmpty( toOverride ) )
+        {
+            getLogger().info( "To override address is not configured, will use the nag email address from the project." );
+        }
+        else
+        {
+            getLogger().warn( "Using '" + toOverride + "' as the to address for all emails." );
+        }
+    }
+
+    // ----------------------------------------------------------------------
+    // RecipientSource Implementation
+    // ----------------------------------------------------------------------
+
+    public Set getRecipients( String notifierType, String messageId, Map context )
+        throws NotificationException
+    {
+        if ( notifierType.equals( "console" ) )
+        {
+            return Collections.EMPTY_SET;
+        }
+        else if ( notifierType.equals( "mail" ) )
+        {
+            return getMailRecipients( context );
+        }
+
+        getLogger().warn( "Unknown notifier type '" + notifierType + "'." );
+
+        return Collections.EMPTY_SET;
+    }
+
+    // ----------------------------------------------------------------------
+    //
+    // ----------------------------------------------------------------------
+
+    private Set getMailRecipients( Map context )
+        throws NotificationException
+    {
+        ContinuumProject project = (ContinuumProject) context.get( ContinuumNotificationDispatcher.CONTEXT_PROJECT );
+
+        if ( project == null )
+        {
+            throw new NotificationException( "Missing project from the notification context." );
+        }
+
+        Set recipients = new HashSet();
+
+        if ( !StringUtils.isEmpty( toOverride ) )
+        {
+            recipients.add( toOverride );
+        }
+        else if ( !StringUtils.isEmpty( project.getNagEmailAddress() ) )
+        {
+            recipients.add( project.getNagEmailAddress() );
+        }
+
+        return recipients;
+    }
+}

Added: maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/notification/DefaultContinuumNotificationDispatcher.java
URL: http://svn.apache.org/viewcvs/maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/notification/DefaultContinuumNotificationDispatcher.java?view=auto&rev=160813
==============================================================================
--- maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/notification/DefaultContinuumNotificationDispatcher.java (added)
+++ maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/notification/DefaultContinuumNotificationDispatcher.java Sun Apr 10 19:21:34 2005
@@ -0,0 +1,110 @@
+package org.apache.maven.continuum.notification;
+
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.maven.continuum.project.ContinuumBuild;
+import org.apache.maven.continuum.store.ContinuumStore;
+import org.apache.maven.continuum.store.ContinuumStoreException;
+
+import org.codehaus.plexus.logging.AbstractLogEnabled;
+import org.codehaus.plexus.notification.NotificationDispatcher;
+import org.codehaus.plexus.notification.NotificationException;
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ * @version $Id: DefaultContinuumNotificationDispatcher.java,v 1.2 2005/04/01 22:55:52 trygvis Exp $
+ */
+public class DefaultContinuumNotificationDispatcher
+    extends AbstractLogEnabled
+    implements ContinuumNotificationDispatcher
+{
+    /** @requirement */
+    private NotificationDispatcher notificationDispatcher;
+
+    /** @requirement */
+    private ContinuumStore store;
+
+    // ----------------------------------------------------------------------
+    // ContinuumNotificationDispatcher Implementation
+    // ----------------------------------------------------------------------
+
+    public void buildStarted( ContinuumBuild build )
+    {
+        sendNotifiaction( MESSAGE_ID_BUILD_STARTED, build );
+    }
+
+    public void checkoutStarted( ContinuumBuild build )
+    {
+        sendNotifiaction( MESSAGE_ID_CHECKOUT_STARTED, build );
+    }
+
+    public void checkoutComplete( ContinuumBuild build )
+    {
+        sendNotifiaction( MESSAGE_ID_CHECKOUT_COMPLETE, build );
+    }
+
+    public void runningGoals( ContinuumBuild build )
+    {
+        sendNotifiaction( MESSAGE_ID_RUNNING_GOALS, build );
+    }
+
+    public void goalsCompleted( ContinuumBuild build )
+    {
+        sendNotifiaction( MESSAGE_ID_GOALS_COMPLETED, build );
+    }
+
+    public void buildComplete( ContinuumBuild build )
+    {
+        sendNotifiaction( MESSAGE_ID_BUILD_COMPLETE, build );
+    }
+
+    // ----------------------------------------------------------------------
+    //
+    // ----------------------------------------------------------------------
+
+    private void sendNotifiaction( String messageId, ContinuumBuild build )
+    {
+        Map context = new HashMap();
+
+        try
+        {
+            context.put( CONTEXT_PROJECT, store.getProjectByBuild( build.getId() ) );
+
+            context.put( CONTEXT_BUILD, build );
+
+            context.put( CONTEXT_BUILD_RESULT, store.getBuildResultForBuild( build.getId() ) );
+        }
+        catch ( ContinuumStoreException e )
+        {
+            getLogger().error( "Error while population the notification context.", e );
+
+            return;
+        }
+
+        try
+        {
+            notificationDispatcher.sendNotification( messageId, context );
+        }
+        catch ( NotificationException e )
+        {
+            getLogger().error( "Error while notifying.", e );
+        }
+    }
+}

Added: maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/notification/console/ConsoleNotifier.java
URL: http://svn.apache.org/viewcvs/maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/notification/console/ConsoleNotifier.java?view=auto&rev=160813
==============================================================================
--- maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/notification/console/ConsoleNotifier.java (added)
+++ maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/notification/console/ConsoleNotifier.java Sun Apr 10 19:21:34 2005
@@ -0,0 +1,140 @@
+package org.apache.maven.continuum.notification.console;
+
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.maven.continuum.notification.ContinuumNotificationDispatcher;
+import org.apache.maven.continuum.project.ContinuumBuild;
+import org.apache.maven.continuum.project.ContinuumBuildResult;
+import org.apache.maven.continuum.project.ContinuumProject;
+
+import org.codehaus.plexus.logging.AbstractLogEnabled;
+import org.codehaus.plexus.notification.NotificationException;
+import org.codehaus.plexus.notification.notifier.Notifier;
+import org.codehaus.plexus.util.StringUtils;
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ * @version $Id: ConsoleNotifier.java,v 1.1.1.1 2005/03/29 20:42:01 trygvis Exp $
+ */
+public class ConsoleNotifier
+    extends AbstractLogEnabled
+    implements Notifier
+{
+    // ----------------------------------------------------------------------
+    // Notifier Implementation
+    // ----------------------------------------------------------------------
+
+    public void sendNotification( String source, Set recipients, Map context )
+        throws NotificationException
+    {
+        ContinuumProject project = (ContinuumProject) context.get( ContinuumNotificationDispatcher.CONTEXT_PROJECT );
+
+        ContinuumBuild build = (ContinuumBuild) context.get( ContinuumNotificationDispatcher.CONTEXT_BUILD );
+
+        ContinuumBuildResult result = (ContinuumBuildResult) context.get( ContinuumNotificationDispatcher.CONTEXT_BUILD_RESULT );
+
+        if ( source.equals( ContinuumNotificationDispatcher.MESSAGE_ID_BUILD_STARTED ) )
+        {
+            buildStarted( project, build );
+        }
+        else if ( source.equals( ContinuumNotificationDispatcher.MESSAGE_ID_CHECKOUT_STARTED ) )
+        {
+            checkoutStarted( project, build );
+        }
+        else if ( source.equals( ContinuumNotificationDispatcher.MESSAGE_ID_CHECKOUT_COMPLETE ) )
+        {
+            checkoutComplete( project, build );
+        }
+        else if ( source.equals( ContinuumNotificationDispatcher.MESSAGE_ID_RUNNING_GOALS ) )
+        {
+            runningGoals( project, build );
+        }
+        else if ( source.equals( ContinuumNotificationDispatcher.MESSAGE_ID_GOALS_COMPLETED ) )
+        {
+            goalsCompleted( project, build, result );
+        }
+        else if ( source.equals( ContinuumNotificationDispatcher.MESSAGE_ID_BUILD_COMPLETE ) )
+        {
+            buildComplete( project, build, result );
+        }
+        else
+        {
+            getLogger().warn( "Unknown source: '" + source + "'." );
+        }
+    }
+
+    // ----------------------------------------------------------------------
+    //
+    // ----------------------------------------------------------------------
+
+    private void buildStarted( ContinuumProject project, ContinuumBuild build )
+    {
+        out( project, build, "Build started." );
+    }
+
+    private void checkoutStarted( ContinuumProject project, ContinuumBuild build )
+    {
+        out( project, build, "Checkout started." );
+    }
+
+    private void checkoutComplete( ContinuumProject project, ContinuumBuild build )
+    {
+        out( project, build, "Checkout complete." );
+    }
+
+    private void runningGoals( ContinuumProject project, ContinuumBuild build )
+    {
+        out( project, build, "Running goals." );
+    }
+
+    private void goalsCompleted( ContinuumProject project, ContinuumBuild build, ContinuumBuildResult result )
+    {
+        if ( result != null )
+        {
+            out( project, build, "Goals completed. state: " + build.getState() );
+        }
+        else
+        {
+            out( project, build, "Goals completed." );
+        }
+    }
+
+    private void buildComplete( ContinuumProject project, ContinuumBuild build, ContinuumBuildResult result )
+    {
+        if ( result != null )
+        {
+            out( project, build, "Build complete. state: " + build.getState() );
+        }
+        else
+        {
+            out( project, build, "Build complete." );
+        }
+    }
+
+    private void out( ContinuumProject project, ContinuumBuild build, String msg )
+    {
+        System.out.println( "Build event for project '" + project.getName() + "':" + msg );
+
+        if ( !StringUtils.isEmpty( build.getError() ) )
+        {
+            System.out.println( build.getError() );
+        }
+    }
+}

Added: maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/notification/mail/FormatterTool.java
URL: http://svn.apache.org/viewcvs/maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/notification/mail/FormatterTool.java?view=auto&rev=160813
==============================================================================
--- maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/notification/mail/FormatterTool.java (added)
+++ maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/notification/mail/FormatterTool.java Sun Apr 10 19:21:34 2005
@@ -0,0 +1,126 @@
+package org.apache.maven.continuum.notification.mail;
+
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.apache.maven.continuum.project.ContinuumProjectState;
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ * @version $Id: FormatterTool.java,v 1.2 2005/04/03 21:53:22 trygvis Exp $
+ */
+public class FormatterTool
+{
+    private String timestampFormatString;
+
+    private ThreadLocal timestampFormat = new ThreadLocal();
+
+    public FormatterTool( String timestampFormatString )
+    {
+        this.timestampFormatString = timestampFormatString;
+    }
+
+    // TODO: Add i18n
+    public String formatProjectState( int state )
+    {
+        if ( state == ContinuumProjectState.NEW )
+        {
+            return "New";
+        }
+        else if ( state == ContinuumProjectState.OK )
+        {
+            return "Ok";
+        }
+        else if ( state == ContinuumProjectState.FAILED )
+        {
+            return "Failed";
+        }
+        else if ( state == ContinuumProjectState.ERROR )
+        {
+            return "Error";
+        }
+        else if ( state == ContinuumProjectState.BUILD_SIGNALED )
+        {
+            return "Build signaled";
+        }
+        else if ( state == ContinuumProjectState.BUILDING )
+        {
+            return "Building";
+        }
+        else
+        {
+            return "Unknown project state '" + state + "'";
+        }
+    }
+
+    public String formatTimestamp( long timestamp )
+    {
+        return getSimpleDateFormat( timestampFormat, timestampFormatString ).format( new Date( timestamp ) );
+    }
+
+    public String formatInterval( long start, long end )
+    {
+        long diff = end - start;
+
+        long interval = diff / 1000L;
+
+        long hours = interval / 3600L;
+
+        interval -= hours * 3600;
+
+        long minutes = interval / 60;
+
+        interval -= minutes * 60;
+
+        long seconds = interval;
+
+        if ( hours > 0 )
+        {
+            return Long.toString( hours ) + "h " +
+                   Long.toString( minutes ) + "m " +
+                   Long.toString( seconds ) + "s";
+        }
+
+        if ( minutes > 0 )
+        {
+            return Long.toString( minutes ) + "m " +
+                   Long.toString( seconds ) + "s";
+        }
+
+        return Long.toString( seconds ) + "s";
+    }
+
+    // ----------------------------------------------------------------------
+    //
+    // ----------------------------------------------------------------------
+
+    private SimpleDateFormat getSimpleDateFormat( ThreadLocal threadLocal, String format )
+    {
+        SimpleDateFormat dateFormat = (SimpleDateFormat) threadLocal.get();
+
+        if ( dateFormat == null )
+        {
+            dateFormat = new SimpleDateFormat( format );
+
+            threadLocal.set( dateFormat );
+        }
+
+        return dateFormat;
+    }
+}

Added: maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/notification/mail/MailContinuumNotifier.java
URL: http://svn.apache.org/viewcvs/maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/notification/mail/MailContinuumNotifier.java?view=auto&rev=160813
==============================================================================
--- maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/notification/mail/MailContinuumNotifier.java (added)
+++ maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/notification/mail/MailContinuumNotifier.java Sun Apr 10 19:21:34 2005
@@ -0,0 +1,409 @@
+package org.apache.maven.continuum.notification.mail;
+
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.StringWriter;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.maven.continuum.ContinuumException;
+import org.apache.maven.continuum.notification.ContinuumNotificationDispatcher;
+import org.apache.maven.continuum.project.ContinuumBuild;
+import org.apache.maven.continuum.project.ContinuumBuildResult;
+import org.apache.maven.continuum.project.ContinuumProject;
+import org.apache.maven.continuum.project.ContinuumProjectState;
+import org.apache.maven.continuum.store.ContinuumStore;
+import org.apache.maven.continuum.store.ContinuumStoreException;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.exception.ResourceNotFoundException;
+
+import org.codehaus.plexus.logging.AbstractLogEnabled;
+import org.codehaus.plexus.mailsender.MailMessage;
+import org.codehaus.plexus.mailsender.MailSender;
+import org.codehaus.plexus.mailsender.MailSenderException;
+import org.codehaus.plexus.notification.NotificationException;
+import org.codehaus.plexus.notification.notifier.Notifier;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
+import org.codehaus.plexus.util.StringUtils;
+import org.codehaus.plexus.velocity.VelocityComponent;
+
+/**
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
+ * @version $Id: MailContinuumNotifier.java,v 1.3 2005/04/02 21:40:04 trygvis Exp $
+ */
+public class MailContinuumNotifier
+    extends AbstractLogEnabled
+    implements Initializable, Notifier
+{
+    // ----------------------------------------------------------------------
+    // Requirements
+    // ----------------------------------------------------------------------
+
+    /** @requirement */
+    private VelocityComponent velocity;
+
+    /** @configuration */
+    private ContinuumStore store;
+
+    /** @configuration */
+    private MailSender mailSender;
+
+    // ----------------------------------------------------------------------
+    // Configuration
+    // ----------------------------------------------------------------------
+
+    /** @configuration */
+    private String fromMailbox;
+
+    /** @configuration */
+    private String fromName;
+
+    /** @configuration */
+    private String timestampFormat;
+
+    // ----------------------------------------------------------------------
+    //
+    // ----------------------------------------------------------------------
+
+    private String localHostName;
+
+    private FormatterTool formatterTool;
+
+    // ----------------------------------------------------------------------
+    //
+    // ----------------------------------------------------------------------
+
+    private static final String FALLBACK_FROM_MAILBOX = "continuum@localhost";
+
+    // ----------------------------------------------------------------------
+    // Component Lifecycle
+    // ----------------------------------------------------------------------
+
+    public void initialize()
+        throws Exception
+    {
+        // ----------------------------------------------------------------------
+        // From mailbox
+        // ----------------------------------------------------------------------
+
+        if ( StringUtils.isEmpty( fromMailbox ) )
+        {
+            getLogger().info( "The from mailbox is not configured, will use the nag email address from the project." );
+
+            fromMailbox = null;
+        }
+        else
+        {
+            getLogger().info( "Using '" + fromMailbox + "' as the from mailbox for all emails." );
+        }
+
+        if ( StringUtils.isEmpty( fromName ) )
+        {
+            try
+            {
+                InetAddress address = InetAddress.getLocalHost();
+
+                localHostName = address.getCanonicalHostName();
+
+                fromName = "Continuum@" + localHostName;
+            }
+            catch ( UnknownHostException ex )
+            {
+                fromName = "Continuum";
+            }
+        }
+
+        getLogger().info( "From name: " + fromName );
+
+        // ----------------------------------------------------------------------
+        //
+        // ----------------------------------------------------------------------
+
+        formatterTool = new FormatterTool( timestampFormat );
+    }
+
+    // ----------------------------------------------------------------------
+    // Notifier Implementation
+    // ----------------------------------------------------------------------
+
+    public void sendNotification( String source, Set recipients, Map context )
+        throws NotificationException
+    {
+        ContinuumProject project = (ContinuumProject) context.get( ContinuumNotificationDispatcher.CONTEXT_PROJECT );
+
+        ContinuumBuild build = (ContinuumBuild) context.get( ContinuumNotificationDispatcher.CONTEXT_BUILD );
+
+        ContinuumBuildResult result = (ContinuumBuildResult) context.get( ContinuumNotificationDispatcher.CONTEXT_BUILD_RESULT );
+
+        try
+        {
+            if ( source.equals( ContinuumNotificationDispatcher.MESSAGE_ID_BUILD_COMPLETE ) )
+            {
+                buildComplete( project, build, result, source, recipients );
+            }
+        }
+        catch ( ContinuumException e )
+        {
+            throw new NotificationException( "Error while notifiying.", e );
+        }
+    }
+
+    private void buildComplete( ContinuumProject project, ContinuumBuild build, ContinuumBuildResult buildResult,
+                                String source, Set recipients )
+        throws ContinuumException
+    {
+        // ----------------------------------------------------------------------
+        // Check if the mail should be sent at all
+        // ----------------------------------------------------------------------
+
+        ContinuumBuild previousBuild = getPreviousBuild( project, build );
+
+        if ( !shouldNotify( build, previousBuild ) )
+        {
+            return;
+        }
+
+        // ----------------------------------------------------------------------
+        // Generate the mail contents
+        // ----------------------------------------------------------------------
+
+        String packageName = getClass().getPackage().getName().replace( '.', '/' );
+
+        String templateName = "/" + packageName + "/templates/" + project.getBuilderId() + "/" + source + ".vm";
+
+        StringWriter writer = new StringWriter();
+
+        String content;
+
+        try
+        {
+            VelocityContext context = new VelocityContext();
+
+            // ----------------------------------------------------------------------
+            // Data objects
+            // ----------------------------------------------------------------------
+
+            context.put( "project", project );
+
+            context.put( "build", build );
+
+            context.put( "build", build );
+
+            context.put( "previousBuild", previousBuild );
+
+            context.put( "buildResult", buildResult );
+
+            // ----------------------------------------------------------------------
+            // Tools
+            // ----------------------------------------------------------------------
+
+            context.put( "formatter", formatterTool );
+
+            // TODO: Make the build host a part of the build
+
+            context.put( "buildHost", localHostName );
+
+            // ----------------------------------------------------------------------
+            //
+            // ----------------------------------------------------------------------
+
+            velocity.getEngine().mergeTemplate( templateName, context, writer );
+
+            content = writer.getBuffer().toString();
+        }
+        catch ( ResourceNotFoundException e )
+        {
+            getLogger().info( "No such template: '" + templateName + "'." );
+
+            return;
+        }
+        catch ( Exception e )
+        {
+            throw new ContinuumException( "Error while generating mail contents." , e );
+        }
+
+        // ----------------------------------------------------------------------
+        // Send the mail
+        // ----------------------------------------------------------------------
+
+        String subject = generateSubject( project, build, buildResult );
+
+        sendMessage( project, recipients, subject, content );
+    }
+
+    // ----------------------------------------------------------------------
+    //
+    // ----------------------------------------------------------------------
+
+    private static String generateSubject( ContinuumProject project, ContinuumBuild build, ContinuumBuildResult result )
+    {
+        int state = build.getState();
+
+        if ( state == ContinuumProjectState.ERROR )
+        {
+            return "[continuum] BUILD ERROR: " + project.getName();
+        }
+        else if ( state == ContinuumProjectState.OK || state == ContinuumProjectState.FAILED )
+        {
+            if ( !result.isSuccess() )
+            {
+                return "[continuum] BUILD FAILURE: " + project.getName();
+            }
+            else
+            {
+                return "[continuum] BUILD SUCCESSFUL: " + project.getName();
+            }
+        }
+        else
+        {
+            return "[continuum] ERROR: Unknown build state";
+        }
+    }
+
+    private void sendMessage( ContinuumProject project, Set recipients, String subject, String content )
+        throws ContinuumException
+    {
+        String fromMailbox = getFromMailbox( project );
+
+        if ( fromMailbox == null )
+        {
+            getLogger().warn( project.getName() + ": Project is missing nag email and global from mailbox is missing, not sending mail." );
+
+            return;
+        }
+
+        MailMessage message = new MailMessage();
+
+        message.addHeader( "X-Continuum-Host", localHostName );
+
+        message.addHeader( "X-Continuum-Project-Id", project.getId() );
+
+        message.addHeader( "X-Continuum-Project-Name", project.getName() );
+
+        try
+        {
+            message.setSubject( subject );
+
+            message.setContent( content );
+
+            MailMessage.Address from = new MailMessage.Address( fromMailbox, fromName );
+
+            message.setFrom( from );
+
+            getLogger().info( "Sending message: From '" + from + "'." );
+
+            for ( Iterator it = recipients.iterator(); it.hasNext(); )
+            {
+                String mailbox = (String) it.next();
+
+                // TODO: set a proper name
+                MailMessage.Address to = new MailMessage.Address( mailbox  );
+
+                getLogger().info( "Recipient: To '" + to + "'." );
+
+                message.addTo( to );
+            }
+
+            mailSender.send( message );
+        }
+        catch ( MailSenderException ex )
+        {
+            throw new ContinuumException( "Exception while sending message.", ex );
+        }
+    }
+
+    private String getFromMailbox( ContinuumProject project )
+    {
+        if ( fromMailbox != null )
+        {
+            return fromMailbox;
+        }
+
+        if ( StringUtils.isEmpty( project.getNagEmailAddress() ) )
+        {
+            return FALLBACK_FROM_MAILBOX;
+        }
+
+        return project.getNagEmailAddress();
+    }
+
+    private boolean shouldNotify( ContinuumBuild build, ContinuumBuild previousBuild )
+    {
+        // Always send if the project failed
+        if ( build.getState() == ContinuumProjectState.FAILED )
+        {
+            return true;
+        }
+
+        // Send if this is the first build
+        if ( previousBuild == null )
+        {
+            return true;
+        }
+
+        // Send if the state has changed
+        getLogger().info( "Current build state: " + build.getState() + ", previous build state: " + previousBuild.getState() );
+
+        if ( build.getState() != previousBuild.getState() )
+        {
+            return true;
+        }
+
+        getLogger().info( "Same state, not sending mail." );
+
+        return false;
+    }
+
+    private ContinuumBuild getPreviousBuild( ContinuumProject project, ContinuumBuild currentBuild )
+        throws ContinuumException
+    {
+        Iterator it;
+
+        try
+        {
+            it = store.getBuildsForProject( project.getId(), 0, 0 );
+        }
+        catch ( ContinuumStoreException ex )
+        {
+            throw new ContinuumException( "Error while finding the last project build.", ex );
+        }
+
+        if ( !it.hasNext() )
+        {
+            return null;
+        }
+
+        ContinuumBuild build = (ContinuumBuild) it.next();
+
+        if ( !build.getId().equals( currentBuild.getId() ) )
+        {
+            throw new ContinuumException( "INTERNAL ERROR: The current build wasn't the first in the build list. " +
+                                          "Current build: '" + currentBuild.getId() + "', " +
+                                          "first build: '" + build.getId() + "'." );
+        }
+
+        if ( !it.hasNext() )
+        {
+            return null;
+        }
+
+        return (ContinuumBuild) it.next();
+    }
+}

Added: maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/project/ContinuumProjectState.java
URL: http://svn.apache.org/viewcvs/maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/project/ContinuumProjectState.java?view=auto&rev=160813
==============================================================================
--- maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/project/ContinuumProjectState.java (added)
+++ maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/project/ContinuumProjectState.java Sun Apr 10 19:21:34 2005
@@ -0,0 +1,108 @@
+package org.apache.maven.continuum.project;
+
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.Serializable;
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ * @version $Id: ContinuumProjectState.java,v 1.1.1.1 2005/03/29 20:42:02 trygvis Exp $
+ */
+public class ContinuumProjectState
+    implements Serializable
+{
+    /**
+     * This state indicates that the project is new and has never been build.
+     */
+//    public final static ContinuumProjectState NEW = new ContinuumProjectState( "new" );
+    public final static int NEW = 1;
+
+    /**
+     * This state indicates that the project has been successfully build.
+     */
+//    public final static ContinuumProjectState OK = new ContinuumProjectState( "ok" );
+    public final static int OK = 2;
+
+    /**
+     * This state indicates that the project didn't build successfully.
+     */
+//    public final static ContinuumProjectState FAILED = new ContinuumProjectState( "failed" );
+    public final static int FAILED = 3;
+
+    /**
+     * This stats indicates that there was a error while building the project.
+     * <p/>
+     * A error while building the project might indicate that it couldn't
+     * download the sources or other things that continuum doesn't have any
+     * control over.
+     */
+//    public final static ContinuumProjectState ERROR = new ContinuumProjectState( "error" );
+    public final static int ERROR = 4;
+
+    /**
+     * This state indicates that this project has been placed on the build queue.
+     * <p/>
+     * Continuum can be configured with a delay from the first build signal to
+     * the actual build starts to make.
+     */
+//    public final static ContinuumProjectState BUILD_SIGNALED = new ContinuumProjectState( "signaled" );
+    public final static int BUILD_SIGNALED = 5;
+
+    /**
+     * This state indicates that a project is currently beeing build.
+     */
+//    public final static ContinuumProjectState BUILDING = new ContinuumProjectState( "building" );
+    public final static int BUILDING = 6;
+
+    private String name;
+
+    protected ContinuumProjectState( String name )
+    {
+        this.name = name;
+    }
+
+    public String getI18nKey()
+    {
+        return "org.apache.maven.continuum.project.state." + name;
+    }
+
+    // ----------------------------------------------------------------------
+    // Object Overrides
+    // ----------------------------------------------------------------------
+
+    public boolean equals( Object object )
+    {
+        if ( !( object instanceof ContinuumProjectState ) )
+        {
+            return false;
+        }
+
+        ContinuumProjectState other = (ContinuumProjectState) object;
+
+        return name.equals( other.name );
+    }
+
+    public int hashCode()
+    {
+        return name.hashCode();
+    }
+
+    public String toString()
+    {
+        return name;
+    }
+}

Added: maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/registration/AbstractContinuumRegistrar.java
URL: http://svn.apache.org/viewcvs/maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/registration/AbstractContinuumRegistrar.java?view=auto&rev=160813
==============================================================================
--- maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/registration/AbstractContinuumRegistrar.java (added)
+++ maven/continuum/continuum-core/src/main/java/org/apache/maven/continuum/registration/AbstractContinuumRegistrar.java Sun Apr 10 19:21:34 2005
@@ -0,0 +1,38 @@
+package org.apache.maven.continuum.registration;
+
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.maven.continuum.Continuum;
+
+import org.codehaus.plexus.logging.AbstractLogEnabled;
+
+/**
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
+ * @version $Id: AbstractContinuumRegistrar.java,v 1.1.1.1 2005/03/29 20:42:02 trygvis Exp $
+ */
+public abstract class AbstractContinuumRegistrar
+    extends AbstractLogEnabled
+    implements ContinuumRegistrar
+{
+    /** @requirement */
+    private Continuum continuum;
+
+    public Continuum getContinuum()
+    {
+        return continuum;
+    }
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
For additional commands, e-mail: dev-help@maven.apache.org