You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by jd...@apache.org on 2011/05/17 18:57:54 UTC

svn commit: r1104405 [3/6] - in /maven/sandbox/trunk/mae: ./ boms/ boms/mae-app-bom/ boms/mae-library-bom/ mae-api/ mae-api/src/ mae-api/src/main/ mae-api/src/main/java/ mae-api/src/main/java/org/ mae-api/src/main/java/org/apache/ mae-api/src/main/java...

Added: maven/sandbox/trunk/mae/mae-booter/pom.xml
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mae/mae-booter/pom.xml?rev=1104405&view=auto
==============================================================================
--- maven/sandbox/trunk/mae/mae-booter/pom.xml (added)
+++ maven/sandbox/trunk/mae/mae-booter/pom.xml Tue May 17 16:57:50 2011
@@ -0,0 +1,90 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 2010 Red Hat, Inc.
+  
+  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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>mae</artifactId>
+    <groupId>org.apache.maven.mae</groupId>
+    <version>0.6-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>mae-booter</artifactId>
+  <name>Maven App Engine: Booter</name>
+  
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>org.apache.maven.mae</groupId>
+        <artifactId>mae-library-bom</artifactId>
+        <version>${project.version}</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.maven.mae</groupId>
+      <artifactId>mae-api</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven.mae</groupId>
+      <artifactId>mae-container</artifactId>
+      <version>${project.version}</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>log4j</groupId>
+      <artifactId>log4j</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <!-- <dependency>
+      <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-container-default</artifactId>
+      <scope>compile</scope>
+    </dependency> -->
+    <dependency>
+      <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-classworlds</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-embedder</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>commons-cli</groupId>
+      <artifactId>commons-cli</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+    </dependency>
+  </dependencies>
+  
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.codehaus.plexus</groupId>
+        <artifactId>plexus-component-metadata</artifactId>
+      </plugin>
+    </plugins>
+  </build>
+</project>

Propchange: maven/sandbox/trunk/mae/mae-booter/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/Maven3BooterLibrary.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/Maven3BooterLibrary.java?rev=1104405&view=auto
==============================================================================
--- maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/Maven3BooterLibrary.java (added)
+++ maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/Maven3BooterLibrary.java Tue May 17 16:57:50 2011
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * 
+ * 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.
+ */
+
+package org.apache.maven.mae.boot;
+
+import org.apache.maven.mae.conf.AbstractMAELibrary;
+import org.apache.maven.mae.conf.MAELibrary;
+import org.apache.maven.mae.conf.MavenPomVersionProvider;
+import org.commonjava.atservice.annotation.Service;
+
+@Service( MAELibrary.class )
+public class Maven3BooterLibrary
+    extends AbstractMAELibrary
+{
+    public Maven3BooterLibrary()
+    {
+        super( "boot", "EMB-Booter", new MavenPomVersionProvider( "org.commonjava.emb", "emb-booter" ), "core" );
+    }
+}

Propchange: maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/Maven3BooterLibrary.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/embed/EMBEmbedder.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/embed/EMBEmbedder.java?rev=1104405&view=auto
==============================================================================
--- maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/embed/EMBEmbedder.java (added)
+++ maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/embed/EMBEmbedder.java Tue May 17 16:57:50 2011
@@ -0,0 +1,734 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * 
+ * 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.
+ */
+
+package org.apache.maven.mae.boot.embed;
+
+import static org.apache.maven.mae.conf.MAELibraries.loadLibraries;
+
+import org.apache.maven.Maven;
+import org.apache.maven.cli.CLIReportingUtils;
+import org.apache.maven.exception.DefaultExceptionHandler;
+import org.apache.maven.exception.ExceptionHandler;
+import org.apache.maven.exception.ExceptionSummary;
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.execution.MavenExecutionRequestPopulationException;
+import org.apache.maven.execution.MavenExecutionRequestPopulator;
+import org.apache.maven.execution.MavenExecutionResult;
+import org.apache.maven.lifecycle.LifecycleExecutionException;
+import org.apache.maven.mae.MAEExecutionRequest;
+import org.apache.maven.mae.boot.log.EventLogger;
+import org.apache.maven.mae.boot.main.EMBMain;
+import org.apache.maven.mae.boot.services.EMBServiceManager;
+import org.apache.maven.mae.conf.MAEConfiguration;
+import org.apache.maven.mae.conf.MAELibrary;
+import org.apache.maven.mae.conf.loader.MAELibraryLoader;
+import org.apache.maven.mae.conf.mgmt.MAEManagementException;
+import org.apache.maven.mae.conf.mgmt.MAEManagementView;
+import org.apache.maven.mae.conf.mgmt.LoadOnFinish;
+import org.apache.maven.mae.conf.mgmt.LoadOnStart;
+import org.apache.maven.mae.internal.container.ComponentKey;
+import org.apache.maven.mae.internal.container.ExtrudablePlexusContainer;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.properties.internal.EnvironmentUtils;
+import org.apache.maven.settings.Settings;
+import org.apache.maven.settings.building.DefaultSettingsBuildingRequest;
+import org.apache.maven.settings.building.SettingsBuilder;
+import org.apache.maven.settings.building.SettingsBuildingException;
+import org.apache.maven.settings.building.SettingsBuildingRequest;
+import org.apache.maven.settings.building.SettingsBuildingResult;
+import org.apache.maven.settings.building.SettingsProblem;
+import org.codehaus.plexus.PlexusConstants;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.util.StringUtils;
+import org.sonatype.plexus.components.cipher.DefaultPlexusCipher;
+import org.sonatype.plexus.components.cipher.PlexusCipherException;
+import org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher;
+import org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException;
+import org.sonatype.plexus.components.sec.dispatcher.SecUtil;
+import org.sonatype.plexus.components.sec.dispatcher.model.SettingsSecurity;
+
+import com.google.inject.Injector;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+@Component( role = EMBEmbedder.class )
+public class EMBEmbedder
+{
+
+    private static boolean embInfoShown;
+
+    private final Logger logger;
+
+    private final PrintStream standardOut;
+
+    private final boolean shouldShowErrors;
+
+    private final Maven maven;
+
+    private final boolean showVersion;
+
+    private final ExtrudablePlexusContainer container;
+
+    private final MAEConfiguration embConfiguration;
+
+    private final SettingsBuilder settingsBuilder;
+
+    private final MavenExecutionRequestPopulator executionRequestPopulator;
+
+    private final DefaultSecDispatcher securityDispatcher;
+
+    private transient final EMBServiceManager serviceManager;
+
+    private final List<MAELibraryLoader> libraryLoaders;
+
+    private boolean infoPrinted = false;
+
+    EMBEmbedder( final Maven maven, final MAEConfiguration embConfiguration, final ExtrudablePlexusContainer container,
+                 final SettingsBuilder settingsBuilder, final MavenExecutionRequestPopulator executionRequestPopulator,
+                 final DefaultSecDispatcher securityDispatcher, final EMBServiceManager serviceManager,
+                 final List<MAELibraryLoader> libraryLoaders, final PrintStream standardOut, final Logger logger,
+                 final boolean shouldShowErrors, final boolean showVersion )
+    {
+        this.maven = maven;
+        this.embConfiguration = embConfiguration;
+        this.container = container;
+
+        this.settingsBuilder = settingsBuilder;
+        this.executionRequestPopulator = executionRequestPopulator;
+        this.securityDispatcher = securityDispatcher;
+        this.serviceManager = serviceManager;
+        this.libraryLoaders = libraryLoaders;
+        this.standardOut = standardOut;
+        this.logger = logger;
+        this.shouldShowErrors = shouldShowErrors;
+        this.showVersion = showVersion;
+    }
+
+    public synchronized Injector injector()
+        throws EMBEmbeddingException
+    {
+        printInfo( null );
+        return container.getInjector();
+    }
+
+    public synchronized Map<Object, Throwable> wire( final Object... instances )
+        throws EMBEmbeddingException
+    {
+        printInfo( null );
+        return container.extrudeDependencies( instances );
+    }
+
+    public synchronized EMBServiceManager serviceManager()
+        throws EMBEmbeddingException
+    {
+        printInfo( null );
+        return serviceManager;
+    }
+
+    public MavenExecutionResult execute( final MAEExecutionRequest request )
+        throws EMBEmbeddingException
+    {
+        final PrintStream oldOut = System.out;
+        try
+        {
+            if ( standardOut != null )
+            {
+                System.setOut( standardOut );
+            }
+
+            doExecutionStarting();
+
+            injectEnvironment( request );
+            printInfo( request );
+            return maven.execute( request.asMavenExecutionRequest() );
+        }
+        finally
+        {
+            doExecutionFinished();
+            System.setOut( oldOut );
+        }
+    }
+
+    public String encryptMasterPassword( final MAEExecutionRequest request )
+        throws EMBEmbeddingException
+    {
+        printInfo( null );
+
+        String passwd = request.getPasswordToEncyrpt();
+        if ( passwd == null )
+        {
+            passwd = "";
+        }
+
+        try
+        {
+            final DefaultPlexusCipher cipher = new DefaultPlexusCipher();
+
+            final String result = cipher.encryptAndDecorate( passwd, DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION );
+            logger.info( result );
+
+            return result;
+        }
+        catch ( final PlexusCipherException e )
+        {
+            throw new EMBEmbeddingException( "Failed to encrypt master password: {0}", e, e.getMessage() );
+        }
+    }
+
+    public String encryptPassword( final MAEExecutionRequest request )
+        throws EMBEmbeddingException
+    {
+        printInfo( null );
+
+        final String passwd = request.getPasswordToEncyrpt();
+
+        String configurationFile = securityDispatcher.getConfigurationFile();
+
+        if ( configurationFile.startsWith( "~" ) )
+        {
+            configurationFile = System.getProperty( "user.home" ) + configurationFile.substring( 1 );
+        }
+
+        final String file = System.getProperty( DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION, configurationFile );
+
+        String master = null;
+
+        try
+        {
+            final SettingsSecurity sec = SecUtil.read( file, true );
+            if ( sec != null )
+            {
+                master = sec.getMaster();
+            }
+
+            if ( master == null )
+            {
+                throw new IllegalStateException( "Master password is not set in the setting security file: " + file );
+            }
+
+            final DefaultPlexusCipher cipher = new DefaultPlexusCipher();
+            final String masterPasswd =
+                cipher.decryptDecorated( master, DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION );
+
+            final String result = cipher.encryptAndDecorate( passwd, masterPasswd );
+            logger.info( result );
+
+            return result;
+        }
+        catch ( final PlexusCipherException e )
+        {
+            throw new EMBEmbeddingException( "Failed to encrypt password: {0}", e, e.getMessage() );
+        }
+        catch ( final SecDispatcherException e )
+        {
+            throw new EMBEmbeddingException( "Failed to encrypt password: {0}", e, e.getMessage() );
+        }
+    }
+
+    protected void doExecutionStarting()
+        throws EMBEmbeddingException
+    {
+        for ( final MAELibrary library : embConfiguration.getLibraries() )
+        {
+            final Set<ComponentKey<?>> components = library.getManagementComponents( LoadOnStart.class );
+            if ( components != null && !components.isEmpty() )
+            {
+                final MAEManagementView mgmtView = new EmbedderManagementView( container, embConfiguration );
+                for ( final ComponentKey<?> key : components )
+                {
+                    try
+                    {
+                        final LoadOnStart los = (LoadOnStart) container.lookup( key.getRole(), key.getHint() );
+                        los.executionStarting( mgmtView );
+                    }
+                    catch ( final ComponentLookupException e )
+                    {
+                        throw new EMBEmbeddingException(
+                                                         "Failed to lookup load-on-start component for initialization: %s.\nReason: %s",
+                                                         e, key, e.getMessage() );
+                    }
+                }
+            }
+        }
+    }
+
+    protected void doExecutionFinished()
+    {
+        for ( final MAELibrary library : embConfiguration.getLibraries() )
+        {
+            final Set<ComponentKey<?>> components = library.getManagementComponents( LoadOnFinish.class );
+            if ( components != null && !components.isEmpty() )
+            {
+                final MAEManagementView mgmtView = new EmbedderManagementView( container, embConfiguration );
+                for ( final ComponentKey<?> key : components )
+                {
+                    try
+                    {
+                        final LoadOnFinish lof = (LoadOnFinish) container.lookup( key.getRole(), key.getHint() );
+                        lof.executionFinished( mgmtView );
+                    }
+                    catch ( final ComponentLookupException e )
+                    {
+                        logger.error( String.format( "Failed to lookup load-on-start component for initialization: %s.\nReason: %s",
+                                                     key, e.getMessage() ), e );
+                    }
+                }
+            }
+        }
+    }
+
+    protected synchronized void injectEnvironment( final MAEExecutionRequest request )
+        throws EMBEmbeddingException
+    {
+        injectLogSettings( request );
+
+        initializeEMB( request );
+
+        injectProperties( request );
+
+        injectSettings( request );
+
+        injectFromProperties( request );
+    }
+
+    private void initializeEMB( final MAEExecutionRequest request )
+    {
+        embConfiguration.withEMBExecutionRequest( request );
+        if ( request.isInteractiveMode() )
+        {
+            embConfiguration.interactive();
+        }
+        else
+        {
+            embConfiguration.nonInteractive();
+        }
+
+        if ( Logger.LEVEL_DEBUG == request.getLoggingLevel() )
+        {
+            embConfiguration.withDebug();
+        }
+        else
+        {
+            embConfiguration.withoutDebug();
+        }
+    }
+
+    protected void injectFromProperties( final MAEExecutionRequest request )
+    {
+        String localRepoProperty = request.getUserProperties().getProperty( EMBMain.LOCAL_REPO_PROPERTY );
+
+        if ( localRepoProperty == null )
+        {
+            localRepoProperty = request.getSystemProperties().getProperty( EMBMain.LOCAL_REPO_PROPERTY );
+        }
+
+        if ( localRepoProperty != null )
+        {
+            request.setLocalRepositoryPath( localRepoProperty );
+        }
+    }
+
+    protected void injectLogSettings( final MAEExecutionRequest request )
+    {
+        final int logLevel = request.getLoggingLevel();
+
+        if ( Logger.LEVEL_DEBUG == logLevel )
+        {
+            embConfiguration.withDebug();
+        }
+        else
+        {
+            embConfiguration.withoutDebug();
+        }
+
+        logger.setThreshold( logLevel );
+        container.getLoggerManager().setThresholds( request.getLoggingLevel() );
+
+        // final Configurator log4jConfigurator = new Configurator()
+        // {
+        // @SuppressWarnings( "unchecked" )
+        // public void doConfigure( final URL notUsed, final LoggerRepository repo )
+        // {
+        // final Enumeration<org.apache.log4j.Logger> loggers = repo.getCurrentLoggers();
+        // while ( loggers.hasMoreElements() )
+        // {
+        // final org.apache.log4j.Logger logger = loggers.nextElement();
+        // if ( Logger.LEVEL_DEBUG == logLevel )
+        // {
+        // logger.setLevel( Level.DEBUG );
+        // }
+        // else if ( Logger.LEVEL_ERROR == logLevel )
+        // {
+        // logger.setLevel( Level.ERROR );
+        // }
+        // }
+        // }
+        // };
+        //
+        // log4jConfigurator.doConfigure( null, LogManager.getLoggerRepository() );
+
+        request.setExecutionListener( new EventLogger( logger ) );
+    }
+
+    protected void injectProperties( final MAEExecutionRequest request )
+    {
+        final Properties systemProperties = new Properties();
+
+        EnvironmentUtils.addEnvVars( systemProperties );
+        systemProperties.putAll( System.getProperties() );
+
+        if ( request.getSystemProperties() != null )
+        {
+            systemProperties.putAll( request.getSystemProperties() );
+        }
+
+        request.setSystemProperties( systemProperties );
+    }
+
+    protected void injectSettings( final MAEExecutionRequest request )
+        throws EMBEmbeddingException
+    {
+        Settings settings = request.getSettings();
+        SettingsBuildingResult settingsResult = null;
+        if ( settings == null )
+        {
+            final SettingsBuildingRequest settingsRequest = new DefaultSettingsBuildingRequest();
+            settingsRequest.setGlobalSettingsFile( request.getGlobalSettingsFile() );
+            settingsRequest.setUserSettingsFile( request.getUserSettingsFile() );
+
+            settingsRequest.setSystemProperties( request.getSystemProperties() );
+            settingsRequest.setUserProperties( request.getUserProperties() );
+
+            try
+            {
+                settingsResult = settingsBuilder.build( settingsRequest );
+            }
+            catch ( final SettingsBuildingException e )
+            {
+                throw new EMBEmbeddingException(
+                                                 "Failed to build settings; {0}\nGlobal settings: {1}\nUser settings: {2}",
+                                                 e, e.getMessage(), request.getGlobalSettingsFile(),
+                                                 request.getUserSettingsFile() );
+            }
+
+            settings = settingsResult.getEffectiveSettings();
+        }
+
+        try
+        {
+            executionRequestPopulator.populateFromSettings( request.asMavenExecutionRequest(), settings );
+        }
+        catch ( final MavenExecutionRequestPopulationException e )
+        {
+            throw new EMBEmbeddingException( "Failed to populate request from settings; {0}", e, e.getMessage() );
+        }
+
+        if ( !settingsResult.getProblems().isEmpty() && logger.isWarnEnabled() )
+        {
+            logger.warn( "" );
+            logger.warn( "Some problems were encountered while building the effective settings" );
+
+            for ( final SettingsProblem problem : settingsResult.getProblems() )
+            {
+                logger.warn( problem.getMessage() + " @ " + problem.getLocation() );
+            }
+
+            logger.warn( "" );
+        }
+    }
+
+    public static void showEMBInfo( final MAEConfiguration embConfig, final List<MAELibraryLoader> loaders,
+                                    final PrintStream standardOut )
+        throws IOException
+    {
+        if ( embInfoShown )
+        {
+            return;
+        }
+
+        standardOut.println();
+        standardOut.println( "-- EMB Libraries Loaded --" );
+        standardOut.println();
+
+        final Collection<MAELibrary> libraries = loadLibraries( embConfig, loaders );
+        for ( final MAELibrary ext : libraries )
+        {
+            standardOut.println( "+" + ext.getLabel() + " (Log handle: '" + ext.getLogHandle() + "')" );
+        }
+
+        standardOut.println();
+        standardOut.println( "--------------------------" );
+        standardOut.println();
+
+        embInfoShown = true;
+    }
+
+    public static void showVersion( final MAEConfiguration embConfig, final List<MAELibraryLoader> loaders,
+                                    final PrintStream standardOut )
+        throws IOException
+    {
+        showEMBInfo( embConfig, loaders, standardOut );
+        CLIReportingUtils.showVersion( standardOut );
+    }
+
+    protected synchronized void printInfo( final MAEExecutionRequest request )
+    {
+        if ( infoPrinted )
+        {
+            return;
+        }
+
+        infoPrinted = true;
+        if ( showVersion || ( request != null && Logger.LEVEL_DEBUG == request.getLoggingLevel() ) )
+        {
+            try
+            {
+                showVersion( embConfiguration, libraryLoaders, standardOut );
+            }
+            catch ( final IOException e )
+            {
+                logger.error( "Failed to retrieve EMB extension information: " + e.getMessage(), e );
+            }
+        }
+
+        if ( shouldShowErrors )
+        {
+            logger.info( "Error stacktraces are turned on." );
+        }
+
+        if ( request != null )
+        {
+            if ( MavenExecutionRequest.CHECKSUM_POLICY_WARN.equals( request.getGlobalChecksumPolicy() ) )
+            {
+                logger.info( "Disabling strict checksum verification on all artifact downloads." );
+            }
+            else if ( MavenExecutionRequest.CHECKSUM_POLICY_FAIL.equals( request.getGlobalChecksumPolicy() ) )
+            {
+                logger.info( "Enabling strict checksum verification on all artifact downloads." );
+            }
+        }
+    }
+
+    public int formatErrorOutput( final MAEExecutionRequest request, final MavenExecutionResult result )
+    {
+        if ( result.hasExceptions() )
+        {
+            final ExceptionHandler handler = new DefaultExceptionHandler();
+
+            final Map<String, String> references = new LinkedHashMap<String, String>();
+
+            MavenProject project = null;
+
+            for ( final Throwable exception : result.getExceptions() )
+            {
+                final ExceptionSummary summary = handler.handleException( exception );
+
+                logSummary( summary, references, "", shouldShowErrors );
+
+                if ( project == null && exception instanceof LifecycleExecutionException )
+                {
+                    project = ( (LifecycleExecutionException) exception ).getProject();
+                }
+            }
+
+            logger.error( "" );
+
+            if ( !shouldShowErrors )
+            {
+                logger.error( "To see the full stack trace of the errors, re-run Maven with the -e switch." );
+            }
+            if ( !logger.isDebugEnabled() )
+            {
+                logger.error( "Re-run Maven using the -X switch to enable full debug logging." );
+            }
+
+            if ( !references.isEmpty() )
+            {
+                logger.error( "" );
+                logger.error( "For more information about the errors and possible solutions"
+                                + ", please read the following articles:" );
+
+                for ( final Map.Entry<String, String> entry : references.entrySet() )
+                {
+                    logger.error( entry.getValue() + " " + entry.getKey() );
+                }
+            }
+
+            if ( project != null && !project.equals( result.getTopologicallySortedProjects().get( 0 ) ) )
+            {
+                logger.error( "" );
+                logger.error( "After correcting the problems, you can resume the build with the command" );
+                logger.error( "  mvn <goals> -rf :" + project.getArtifactId() );
+            }
+
+            if ( MavenExecutionRequest.REACTOR_FAIL_NEVER.equals( request.getReactorFailureBehavior() ) )
+            {
+                logger.info( "Build failures were ignored." );
+
+                return 0;
+            }
+            else
+            {
+                return 1;
+            }
+        }
+        else
+        {
+            return 0;
+        }
+    }
+
+    protected void logSummary( final ExceptionSummary summary, final Map<String, String> references, String indent,
+                               final boolean showErrors )
+    {
+        String referenceKey = "";
+
+        if ( StringUtils.isNotEmpty( summary.getReference() ) )
+        {
+            referenceKey = references.get( summary.getReference() );
+            if ( referenceKey == null )
+            {
+                referenceKey = "[Help " + ( references.size() + 1 ) + "]";
+                references.put( summary.getReference(), referenceKey );
+            }
+        }
+
+        String msg = indent + summary.getMessage();
+
+        if ( StringUtils.isNotEmpty( referenceKey ) )
+        {
+            if ( msg.indexOf( '\n' ) < 0 )
+            {
+                msg += " -> " + referenceKey;
+            }
+            else
+            {
+                msg += '\n' + indent + "-> " + referenceKey;
+            }
+        }
+
+        if ( showErrors )
+        {
+            logger.error( msg, summary.getException() );
+        }
+        else
+        {
+            logger.error( msg );
+        }
+
+        indent += "  ";
+
+        for ( final ExceptionSummary child : summary.getChildren() )
+        {
+            logSummary( child, references, indent, showErrors );
+        }
+    }
+
+    private static final class EmbedderManagementView
+        implements MAEManagementView
+    {
+
+        private final PlexusContainer container;
+
+        private final MAEConfiguration configuration;
+
+        EmbedderManagementView( final PlexusContainer container, final MAEConfiguration configuration )
+        {
+            this.container = container;
+            this.configuration = configuration;
+        }
+
+        @Override
+        public <T> T lookup( final Class<T> role, final String hint )
+            throws MAEManagementException
+        {
+            try
+            {
+                return container.lookup( role, hint );
+            }
+            catch ( final ComponentLookupException e )
+            {
+                throw new MAEManagementException(
+                                                  "Failed to lookup component for managed component.\nRole: %s\nHint: %s\nReason: %s",
+                                                  e, role, hint, e.getMessage() );
+            }
+        }
+
+        @Override
+        public <T> T lookup( final Class<T> role )
+            throws MAEManagementException
+        {
+            try
+            {
+                return container.lookup( role );
+            }
+            catch ( final ComponentLookupException e )
+            {
+                throw new MAEManagementException(
+                                                  "Failed to lookup component for managed component.\nRole: %s\nHint: %s\nReason: %s",
+                                                  e, role, PlexusConstants.PLEXUS_DEFAULT_HINT, e.getMessage() );
+            }
+        }
+
+        @Override
+        public MAEConfiguration getConfiguration()
+        {
+            return configuration;
+        }
+
+        public <T> Map<String, T> lookupMap( final Class<T> role )
+            throws MAEManagementException
+        {
+            try
+            {
+                return container.lookupMap( role );
+            }
+            catch ( final ComponentLookupException e )
+            {
+                throw new MAEManagementException(
+                                                  "Failed to lookup component-map for managed component.\nRole: %s\nReason: %s",
+                                                  e, role, e.getMessage() );
+            }
+        }
+
+        public <T> List<T> lookupList( final Class<T> role )
+            throws MAEManagementException
+        {
+            try
+            {
+                return container.lookupList( role );
+            }
+            catch ( final ComponentLookupException e )
+            {
+                throw new MAEManagementException(
+                                                  "Failed to lookup component-list for managed component.\nRole: %s\nReason: %s",
+                                                  e, role, e.getMessage() );
+            }
+        }
+
+    }
+
+}

Propchange: maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/embed/EMBEmbedder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/embed/EMBEmbedderBuilder.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/embed/EMBEmbedderBuilder.java?rev=1104405&view=auto
==============================================================================
--- maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/embed/EMBEmbedderBuilder.java (added)
+++ maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/embed/EMBEmbedderBuilder.java Tue May 17 16:57:50 2011
@@ -0,0 +1,842 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * 
+ * 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.
+ */
+
+package org.apache.maven.mae.boot.embed;
+
+import static org.apache.maven.mae.conf.MAELibraries.loadLibraries;
+
+import org.apache.log4j.Level;
+import org.apache.maven.Maven;
+import org.apache.maven.cli.MavenLoggerManager;
+import org.apache.maven.cli.PrintStreamLogger;
+import org.apache.maven.execution.MavenExecutionRequestPopulator;
+import org.apache.maven.mae.boot.services.EMBServiceManager;
+import org.apache.maven.mae.conf.CoreLibrary;
+import org.apache.maven.mae.conf.MAEConfiguration;
+import org.apache.maven.mae.conf.MAELibrary;
+import org.apache.maven.mae.conf.loader.MAELibraryLoader;
+import org.apache.maven.mae.conf.loader.ServiceLibraryLoader;
+import org.apache.maven.mae.internal.container.ComponentKey;
+import org.apache.maven.mae.internal.container.ComponentSelector;
+import org.apache.maven.mae.internal.container.InstanceRegistry;
+import org.apache.maven.mae.internal.container.MAEContainer;
+import org.apache.maven.mae.internal.container.ExtrudablePlexusContainer;
+import org.apache.maven.mae.internal.container.VirtualInstance;
+import org.apache.maven.model.building.ModelProcessor;
+import org.apache.maven.settings.building.SettingsBuilder;
+import org.codehaus.plexus.ContainerConfiguration;
+import org.codehaus.plexus.DefaultContainerConfiguration;
+import org.codehaus.plexus.PlexusContainerException;
+import org.codehaus.plexus.classworlds.ClassWorld;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+import org.codehaus.plexus.logging.Logger;
+import org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher;
+import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+public class EMBEmbedderBuilder
+{
+
+    private static final MAELibraryLoader CORE_LOADER = new MAELibraryLoader()
+    {
+        @Override
+        public Collection<? extends MAELibrary> loadLibraries( final MAEConfiguration embConfig )
+            throws IOException
+        {
+            return Collections.singleton( new CoreLibrary() );
+        }
+    };
+
+    private boolean showErrors = false;
+
+    private boolean quiet = false;
+
+    private boolean debug = false;
+
+    private boolean showVersion = false;
+
+    private PrintStream stdout = System.out;
+
+    private PrintStream stderr = System.err;
+
+    private InputStream stdin = System.in;
+
+    private Logger logger;
+
+    private File logFile;
+
+    private MAEConfiguration embConfiguration;
+
+    private ClassWorld classWorld;
+
+    private ClassLoader coreClassLoader;
+
+    private Maven maven;
+
+    private ModelProcessor modelProcessor;
+
+    private ExtrudablePlexusContainer container;
+
+    private MavenExecutionRequestPopulator executionRequestPopulator;
+
+    private SettingsBuilder settingsBuilder;
+
+    private DefaultSecDispatcher securityDispatcher;
+
+    private EMBServiceManager serviceManager;
+
+    private transient String mavenHome;
+
+    private transient boolean loggerAutoCreated = false;
+
+    private EMBEmbedder embedder;
+
+    private String[] debugLogHandles;
+
+    private boolean modelProcessorProvided;
+
+    private boolean mavenProvided;
+
+    private boolean executionRequestPopulatorProvided;
+
+    private boolean settingsBuilderProvided;
+
+    private boolean securityDispatcherProvided;
+
+    private boolean serviceManagerProvided;
+
+    private boolean logHandlesConfigured;
+
+    private boolean embConfigurationProvided;
+
+    private ContainerConfiguration containerConfiguration;
+
+    private boolean classScanningEnabled;
+
+    private List<MAELibraryLoader> libraryLoaders;
+
+    private final VirtualInstance<EMBEmbedder> embVirtual = new VirtualInstance<EMBEmbedder>( EMBEmbedder.class );
+
+    public synchronized EMBEmbedderBuilder withSettingsBuilder( final SettingsBuilder settingsBuilder )
+    {
+        this.settingsBuilder = settingsBuilder;
+        settingsBuilderProvided = true;
+        return this;
+    }
+
+    public synchronized SettingsBuilder settingsBuilder()
+        throws EMBEmbeddingException
+    {
+        if ( settingsBuilder == null )
+        {
+            settingsBuilder = lookup( SettingsBuilder.class );
+            settingsBuilderProvided = false;
+        }
+        return settingsBuilder;
+    }
+
+    public synchronized EMBEmbedderBuilder withSecurityDispatcher( final DefaultSecDispatcher securityDispatcher )
+    {
+        this.securityDispatcher = securityDispatcher;
+        securityDispatcherProvided = true;
+        return this;
+    }
+
+    public synchronized DefaultSecDispatcher securityDispatcher()
+        throws EMBEmbeddingException
+    {
+        if ( securityDispatcher == null )
+        {
+            securityDispatcher = (DefaultSecDispatcher) lookup( SecDispatcher.class, "maven" );
+            securityDispatcherProvided = false;
+        }
+        return securityDispatcher;
+    }
+
+    public synchronized EMBEmbedderBuilder withServiceManager( final EMBServiceManager serviceManager )
+    {
+        this.serviceManager = serviceManager;
+        serviceManagerProvided = true;
+        return this;
+    }
+
+    public synchronized EMBServiceManager serviceManager()
+        throws EMBEmbeddingException
+    {
+        if ( serviceManager == null )
+        {
+            serviceManager = lookup( EMBServiceManager.class );
+            serviceManagerProvided = true;
+        }
+        return serviceManager;
+    }
+
+    public synchronized EMBEmbedderBuilder withExecutionRequestPopulator( final MavenExecutionRequestPopulator executionRequestPopulator )
+    {
+        this.executionRequestPopulator = executionRequestPopulator;
+        executionRequestPopulatorProvided = true;
+        return this;
+    }
+
+    public synchronized MavenExecutionRequestPopulator executionRequestPopulator()
+        throws EMBEmbeddingException
+    {
+        if ( executionRequestPopulator == null )
+        {
+            executionRequestPopulator = lookup( MavenExecutionRequestPopulator.class );
+            executionRequestPopulatorProvided = false;
+        }
+
+        return executionRequestPopulator;
+    }
+
+    public synchronized EMBEmbedderBuilder withCoreClassLoader( final ClassLoader classLoader )
+    {
+        coreClassLoader = classLoader;
+        return this;
+    }
+
+    public synchronized EMBEmbedderBuilder withCoreClassLoader( final ClassLoader root, final Object... constituents )
+        throws MalformedURLException
+    {
+        if ( constituents != null && constituents.length > 0 )
+        {
+            final Set<URL> urls = new LinkedHashSet<URL>();
+            for ( final Object object : constituents )
+            {
+                if ( object instanceof URL )
+                {
+                    urls.add( (URL) object );
+                }
+                else if ( object instanceof CharSequence )
+                {
+                    urls.add( new URL( object.toString() ) );
+                }
+                else if ( object instanceof File )
+                {
+                    urls.add( ( (File) object ).toURI().toURL() );
+                }
+                else
+                {
+                    String fname;
+                    ClassLoader cloader;
+                    if ( object instanceof Class<?> )
+                    {
+                        fname = ( (Class<?>) object ).getName();
+                        cloader = ( (Class<?>) object ).getClassLoader();
+                    }
+                    else
+                    {
+                        fname = object.getClass().getName();
+                        cloader = object.getClass().getClassLoader();
+                    }
+
+                    fname = "/" + fname.replace( '.', '/' ) + ".class";
+
+                    final URL resource = cloader.getResource( fname );
+                    if ( resource == null )
+                    {
+                        throw new IllegalStateException( "Class doesn't appear in its own classloader! ["
+                                        + object.getClass().getName() + "]" );
+                    }
+
+                    String path = resource.toExternalForm();
+                    if ( path.startsWith( "jar:" ) )
+                    {
+                        path = path.substring( "jar:".length() );
+                    }
+
+                    final int idx = path.indexOf( '!' );
+                    if ( idx > -1 )
+                    {
+                        path = path.substring( 0, idx );
+                    }
+
+                    urls.add( new URL( path ) );
+                }
+            }
+
+            coreClassLoader = new URLClassLoader( urls.toArray( new URL[] {} ), root );
+        }
+        else
+        {
+            coreClassLoader = root;
+        }
+
+        return this;
+    }
+
+    public synchronized EMBEmbedderBuilder withClassWorld( final ClassWorld classWorld )
+    {
+        this.classWorld = classWorld;
+        return this;
+    }
+
+    public synchronized ClassLoader coreClassLoader()
+    {
+        if ( coreClassLoader == null )
+        {
+            coreClassLoader = Thread.currentThread().getContextClassLoader();
+        }
+
+        return coreClassLoader;
+    }
+
+    public synchronized ClassWorld classWorld()
+    {
+        if ( classWorld == null )
+        {
+            classWorld = new ClassWorld( "plexus.core", coreClassLoader() );
+        }
+
+        return classWorld;
+    }
+
+    public synchronized EMBEmbedderBuilder withContainerConfiguration( final ContainerConfiguration containerConfiguration )
+    {
+        this.containerConfiguration = containerConfiguration;
+        return this;
+    }
+
+    public synchronized ContainerConfiguration containerConfiguration()
+    {
+        if ( containerConfiguration == null )
+        {
+            containerConfiguration =
+                new DefaultContainerConfiguration().setClassWorld( classWorld() )
+                                                   .setName( "maven" )
+                                                   .setClassPathScanning( classScanningEnabled ? "ON" : "OFF" );
+        }
+
+        return containerConfiguration;
+    }
+
+    public synchronized EMBEmbedderBuilder withClassScanningEnabled( final boolean classScanningEnabled )
+    {
+        this.classScanningEnabled = classScanningEnabled;
+        return this;
+    }
+
+    public boolean isClassScanningEnabled()
+    {
+        return classScanningEnabled;
+    }
+
+    public synchronized EMBEmbedderBuilder withMaven( final Maven maven )
+    {
+        this.maven = maven;
+        mavenProvided = true;
+        return this;
+    }
+
+    public synchronized Maven maven()
+        throws EMBEmbeddingException
+    {
+        if ( maven == null )
+        {
+            maven = lookup( Maven.class );
+            mavenProvided = false;
+        }
+        return maven;
+    }
+
+    public synchronized EMBEmbedderBuilder withModelProcessor( final ModelProcessor modelProcessor )
+    {
+        this.modelProcessor = modelProcessor;
+        modelProcessorProvided = true;
+        return this;
+    }
+
+    public synchronized ModelProcessor modelProcessor()
+        throws EMBEmbeddingException
+    {
+        if ( modelProcessor == null )
+        {
+            modelProcessor = lookup( ModelProcessor.class );
+            modelProcessorProvided = false;
+        }
+
+        return modelProcessor;
+    }
+
+    private <T> T lookup( final Class<T> cls )
+        throws EMBEmbeddingException
+    {
+        try
+        {
+            return container().lookup( cls );
+        }
+        catch ( final ComponentLookupException e )
+        {
+            throw new EMBEmbeddingException( "Failed to lookup component: %s. Reason: %s", e, cls.getName(),
+                                             e.getMessage() );
+        }
+    }
+
+    private <T> T lookup( final Class<T> cls, final String hint )
+        throws EMBEmbeddingException
+    {
+        try
+        {
+            return container().lookup( cls, hint );
+        }
+        catch ( final ComponentLookupException e )
+        {
+            throw new EMBEmbeddingException( "Failed to lookup component: {0} with hint: {1}. Reason: {2}", e,
+                                             cls.getName(), hint, e.getMessage() );
+        }
+    }
+
+    public synchronized EMBEmbedderBuilder withContainer( final ExtrudablePlexusContainer container )
+    {
+        this.container = container;
+        resetContainer();
+
+        return this;
+    }
+
+    public synchronized void resetContainer()
+    {
+        if ( !modelProcessorProvided )
+        {
+            modelProcessor = null;
+        }
+        if ( !executionRequestPopulatorProvided )
+        {
+            executionRequestPopulator = null;
+        }
+        if ( !settingsBuilderProvided )
+        {
+            settingsBuilder = null;
+        }
+        if ( !securityDispatcherProvided )
+        {
+            securityDispatcher = null;
+        }
+        if ( !serviceManagerProvided )
+        {
+            serviceManager = null;
+        }
+        if ( !mavenProvided )
+        {
+            maven = null;
+        }
+        if ( !embConfigurationProvided )
+        {
+            embConfiguration = null;
+        }
+        if ( container != null )
+        {
+            container = null;
+        }
+    }
+
+    public synchronized ExtrudablePlexusContainer container()
+        throws EMBEmbeddingException
+    {
+        // Need to switch to using: org.codehaus.plexus.MutablePlexusContainer.addPlexusInjector(List<PlexusBeanModule>,
+        // Module...)
+        if ( container == null )
+        {
+            final ContainerConfiguration cc = containerConfiguration();
+
+            final InstanceRegistry reg = new InstanceRegistry( instanceRegistry() );
+            reg.addVirtual( new ComponentKey<EMBEmbedder>( EMBEmbedder.class ), embVirtual );
+
+            MAEContainer c;
+            try
+            {
+                c = new MAEContainer( cc, selector(), reg );
+            }
+            catch ( final PlexusContainerException e )
+            {
+                throw new EMBEmbeddingException( "Failed to initialize component container: {0}", e, e.getMessage() );
+            }
+
+            c.setLoggerManager( new MavenLoggerManager( logger ) );
+
+            container = c;
+        }
+
+        return container;
+    }
+
+    public synchronized ComponentSelector selector()
+    {
+        return embConfiguration().getComponentSelector();
+    }
+
+    public synchronized InstanceRegistry instanceRegistry()
+    {
+        return embConfiguration().getInstanceRegistry();
+    }
+
+    public EMBEmbedderBuilder withEMBConfiguration( final MAEConfiguration config )
+    {
+        embConfiguration = config;
+        embConfigurationProvided = true;
+        return this;
+    }
+
+    public synchronized MAEConfiguration embConfiguration()
+    {
+        final String[] debugLogHandles = debugLogHandles();
+        if ( !logHandlesConfigured && debugLogHandles != null )
+        {
+            for ( final String logHandle : debugLogHandles )
+            {
+                final org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger( logHandle );
+                logger.setLevel( Level.DEBUG );
+            }
+
+            logHandlesConfigured = true;
+        }
+
+        if ( embConfiguration == null )
+        {
+            embConfiguration = new MAEConfiguration();
+
+            if ( shouldShowDebug() )
+            {
+                embConfiguration.withDebug();
+            }
+            else
+            {
+                embConfiguration.withoutDebug();
+            }
+
+            try
+            {
+                final List<MAELibraryLoader> loaders = libraryLoaders();
+                final Collection<MAELibrary> libraries = loadLibraries( embConfiguration, loaders );
+                embConfiguration.withLibraries( libraries );
+
+                if ( debugLogHandles != null
+                                && Arrays.binarySearch( debugLogHandles, MAEConfiguration.STANDARD_LOG_HANDLE_CORE ) > -1 )
+                {
+                    EMBEmbedder.showEMBInfo( embConfiguration, loaders, standardOut() );
+                }
+            }
+            catch ( final IOException e )
+            {
+                logger.error( "Failed to query context classloader for component-overrides files. Reason: "
+                                              + e.getMessage(), e );
+            }
+
+            embConfigurationProvided = false;
+        }
+
+        return embConfiguration;
+    }
+
+    public EMBEmbedderBuilder withServiceLibraryLoader( final boolean enabled )
+    {
+        boolean found = false;
+        final Collection<? extends MAELibraryLoader> loaders = libraryLoadersInternal();
+        for ( final MAELibraryLoader loader : new LinkedHashSet<MAELibraryLoader>( loaders ) )
+        {
+            if ( loader instanceof ServiceLibraryLoader )
+            {
+                found = true;
+                if ( !enabled )
+                {
+                    loaders.remove( loader );
+                }
+                else
+                {
+                    break;
+                }
+            }
+        }
+
+        if ( enabled && !found )
+        {
+            withLibraryLoader( new ServiceLibraryLoader() );
+        }
+
+        return this;
+    }
+
+    public boolean isServiceLibraryLoaderUsed()
+    {
+        for ( final MAELibraryLoader loader : libraryLoadersInternal() )
+        {
+            if ( loader instanceof ServiceLibraryLoader )
+            {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    public EMBEmbedderBuilder withLibraryLoader( final MAELibraryLoader loader )
+    {
+        libraryLoadersInternal().add( loader );
+        return this;
+    }
+
+    public EMBEmbedderBuilder withLibraryLoader( final MAELibraryLoader loader, final int offset )
+    {
+        final List<MAELibraryLoader> loaders = libraryLoadersInternal();
+        if ( offset < 0 )
+        {
+            // idx is negative, so we can add to the size here to get the insert index.
+            loaders.add( loaders.size() + offset, loader );
+        }
+        else
+        {
+            loaders.add( offset, loader );
+        }
+
+        return this;
+    }
+
+    private List<MAELibraryLoader> libraryLoadersInternal()
+    {
+        if ( libraryLoaders == null )
+        {
+            libraryLoaders = new ArrayList<MAELibraryLoader>( Collections.singletonList( new ServiceLibraryLoader() ) );
+        }
+
+        return libraryLoaders;
+    }
+
+    public List<MAELibraryLoader> libraryLoaders()
+    {
+        final List<MAELibraryLoader> loaders = libraryLoadersInternal();
+
+        if ( !loaders.isEmpty() && CORE_LOADER != loaders.get( 0 ) )
+        {
+            loaders.remove( CORE_LOADER );
+        }
+
+        loaders.add( CORE_LOADER );
+
+        return loaders;
+    }
+
+    public EMBEmbedderBuilder withVersion( final boolean showVersion )
+    {
+        this.showVersion = showVersion;
+        return this;
+    }
+
+    public boolean showVersion()
+    {
+        return showVersion;
+    }
+
+    public EMBEmbedderBuilder withLogFile( final File logFile )
+    {
+        this.logFile = logFile;
+        return this;
+    }
+
+    public File logFile()
+    {
+        return logFile;
+    }
+
+    public EMBEmbedderBuilder withQuietMode( final boolean quiet )
+    {
+        this.quiet = quiet;
+        return this;
+    }
+
+    public boolean shouldBeQuiet()
+    {
+        return quiet;
+    }
+
+    public EMBEmbedderBuilder withDebugMode( final boolean debug )
+    {
+        this.debug = debug;
+        return this;
+    }
+
+    public boolean shouldShowDebug()
+    {
+        return debug;
+    }
+
+    public EMBEmbedderBuilder withErrorMode( final boolean showErrors )
+    {
+        this.showErrors = showErrors;
+        return this;
+    }
+
+    public boolean shouldShowErrors()
+    {
+        return showErrors;
+    }
+
+    public synchronized EMBEmbedderBuilder withStandardOut( final PrintStream stdout )
+    {
+        this.stdout = stdout;
+
+        if ( loggerAutoCreated )
+        {
+            logger = null;
+        }
+
+        return this;
+    }
+
+    public PrintStream standardOut()
+    {
+        return stdout;
+    }
+
+    public EMBEmbedderBuilder withStandardErr( final PrintStream stderr )
+    {
+        this.stderr = stderr;
+        return this;
+    }
+
+    public PrintStream standardErr()
+    {
+        return stderr;
+    }
+
+    public EMBEmbedderBuilder withStandardIn( final InputStream stdin )
+    {
+        this.stdin = stdin;
+        return this;
+    }
+
+    public InputStream standardIn()
+    {
+        return stdin;
+    }
+
+    public EMBEmbedderBuilder withLogger( final Logger logger )
+    {
+        this.logger = logger;
+        return this;
+    }
+
+    public synchronized Logger logger()
+    {
+        if ( logger == null )
+        {
+            logger = new PrintStreamLogger( stdout );
+            loggerAutoCreated = true;
+        }
+
+        return logger;
+    }
+
+    public synchronized String mavenHome()
+    {
+        if ( mavenHome == null )
+        {
+            String mavenHome = System.getProperty( "maven.home" );
+
+            if ( mavenHome != null )
+            {
+                try
+                {
+                    mavenHome = new File( mavenHome ).getCanonicalPath();
+                }
+                catch ( final IOException e )
+                {
+                    mavenHome = new File( mavenHome ).getAbsolutePath();
+                }
+
+                System.setProperty( "maven.home", mavenHome );
+                this.mavenHome = mavenHome;
+            }
+        }
+
+        return mavenHome;
+    }
+
+    protected synchronized void wireLogging()
+    {
+        if ( logFile() != null )
+        {
+            try
+            {
+                final PrintStream newOut = new PrintStream( logFile );
+                withStandardOut( newOut );
+            }
+            catch ( final FileNotFoundException e )
+            {
+            }
+        }
+
+        logger();
+    }
+
+    protected synchronized EMBEmbedder createEmbedder()
+        throws EMBEmbeddingException
+    {
+        final EMBEmbedder embedder =
+            new EMBEmbedder( maven(), embConfiguration(), container(), settingsBuilder(), executionRequestPopulator(),
+                             securityDispatcher(), serviceManager(), libraryLoaders(), standardOut(), logger(),
+                             shouldShowErrors(), showVersion() );
+
+        embVirtual.setInstance( embedder );
+
+        return embedder;
+    }
+
+    public synchronized EMBEmbedder build()
+        throws EMBEmbeddingException
+    {
+        if ( embedder == null )
+        {
+            logger();
+            embConfiguration();
+            mavenHome();
+
+            wireLogging();
+            embedder = createEmbedder();
+        }
+
+        return embedder;
+    }
+
+    public EMBEmbedderBuilder withDebugLogHandles( final String[] debugLogHandles )
+    {
+        this.debugLogHandles = debugLogHandles;
+        logHandlesConfigured = false;
+
+        return this;
+    }
+
+    public String[] debugLogHandles()
+    {
+        return debugLogHandles;
+    }
+
+}

Propchange: maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/embed/EMBEmbedderBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/embed/EMBEmbeddingException.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/embed/EMBEmbeddingException.java?rev=1104405&view=auto
==============================================================================
--- maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/embed/EMBEmbeddingException.java (added)
+++ maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/embed/EMBEmbeddingException.java Tue May 17 16:57:50 2011
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * 
+ * 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.
+ */
+
+package org.apache.maven.mae.boot.embed;
+
+import org.apache.maven.mae.MAEException;
+
+public class EMBEmbeddingException
+    extends MAEException
+{
+
+    private static final long serialVersionUID = 2L;
+
+    public EMBEmbeddingException( final String message, final Throwable cause )
+    {
+        super( message, cause );
+    }
+
+    public EMBEmbeddingException( final String message )
+    {
+        super( message );
+    }
+
+    public EMBEmbeddingException( final String message, final Throwable cause, final Object... params )
+    {
+        super( message, cause, params );
+    }
+
+    public EMBEmbeddingException( final String message, final Object... params )
+    {
+        super( message, params );
+    }
+
+}

Propchange: maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/embed/EMBEmbeddingException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/log/BatchTransferListener.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/log/BatchTransferListener.java?rev=1104405&view=auto
==============================================================================
--- maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/log/BatchTransferListener.java (added)
+++ maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/log/BatchTransferListener.java Tue May 17 16:57:50 2011
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * 
+ * 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.
+ */
+
+package org.apache.maven.mae.boot.log;
+
+import org.apache.maven.repository.ArtifactTransferEvent;
+import org.apache.maven.repository.ArtifactTransferListener;
+import org.apache.maven.repository.ArtifactTransferResource;
+
+import java.io.PrintStream;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.util.Locale;
+
+/**
+ * 
+ */
+public class BatchTransferListener
+    implements ArtifactTransferListener
+{
+    protected PrintStream out;
+
+    private boolean showChecksumEvents;
+
+    public BatchTransferListener( final PrintStream out )
+    {
+        this.out = ( out != null ) ? out : System.out;
+    }
+
+    protected boolean showEvent( final ArtifactTransferEvent event )
+    {
+        if ( event.getResource() == null )
+        {
+            return true;
+        }
+
+        final String resource = event.getResource().getName();
+
+        if ( resource == null || resource.trim().length() == 0 )
+        {
+            return true;
+        }
+
+        if ( resource.endsWith( ".sha1" ) || resource.endsWith( ".md5" ) )
+        {
+            return showChecksumEvents;
+        }
+
+        return true;
+    }
+
+    public void transferInitiated( final ArtifactTransferEvent transferEvent )
+    {
+        if ( !showEvent( transferEvent ) )
+        {
+            return;
+        }
+
+        doInitiated( transferEvent );
+    }
+
+    protected void doInitiated( final ArtifactTransferEvent transferEvent )
+    {
+        final String message =
+            transferEvent.getRequestType() == ArtifactTransferEvent.REQUEST_PUT ? "Uploading" : "Downloading";
+
+        out.println( message + ": " + transferEvent.getResource().getUrl() );
+    }
+
+    public void transferStarted( final ArtifactTransferEvent transferEvent )
+    {
+        if ( !showEvent( transferEvent ) )
+        {
+            return;
+        }
+
+        doStarted( transferEvent );
+    }
+
+    protected void doStarted( final ArtifactTransferEvent transferEvent )
+    {
+        // to be overriden by sub classes
+    }
+
+    public void transferProgress( final ArtifactTransferEvent transferEvent )
+    {
+        if ( !showEvent( transferEvent ) )
+        {
+            return;
+        }
+
+        doProgress( transferEvent );
+    }
+
+    protected void doProgress( final ArtifactTransferEvent transferEvent )
+    {
+        // to be overriden by sub classes
+    }
+
+    public void transferCompleted( final ArtifactTransferEvent transferEvent )
+    {
+        if ( !showEvent( transferEvent ) )
+        {
+            return;
+        }
+
+        doCompleted( transferEvent );
+    }
+
+    protected void doCompleted( final ArtifactTransferEvent transferEvent )
+    {
+        final ArtifactTransferResource artifact = transferEvent.getResource();
+        final long contentLength = transferEvent.getTransferredBytes();
+        if ( contentLength >= 0 )
+        {
+            final String type =
+                ( transferEvent.getRequestType() == ArtifactTransferEvent.REQUEST_PUT ? "Uploaded" : "Downloaded" );
+            final String len = contentLength >= 1024 ? toKB( contentLength ) + " KB" : contentLength + " B";
+
+            String throughput = "";
+            final long duration = System.currentTimeMillis() - artifact.getTransferStartTime();
+            if ( duration > 0 )
+            {
+                final DecimalFormat format = new DecimalFormat( "0.0", new DecimalFormatSymbols( Locale.ENGLISH ) );
+                final double kbPerSec = ( contentLength / 1024.0 ) / ( duration / 1000.0 );
+                throughput = " at " + format.format( kbPerSec ) + " KB/sec";
+            }
+
+            out.println( type + ": " + artifact.getUrl() + " (" + len + throughput + ")" );
+        }
+    }
+
+    protected long toKB( final long bytes )
+    {
+        return ( bytes + 1023 ) / 1024;
+    }
+
+    public boolean isShowChecksumEvents()
+    {
+        return showChecksumEvents;
+    }
+
+    public void setShowChecksumEvents( final boolean showChecksumEvents )
+    {
+        this.showChecksumEvents = showChecksumEvents;
+    }
+
+}

Propchange: maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/log/BatchTransferListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/log/EventLogger.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/log/EventLogger.java?rev=1104405&view=auto
==============================================================================
--- maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/log/EventLogger.java (added)
+++ maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/log/EventLogger.java Tue May 17 16:57:50 2011
@@ -0,0 +1,349 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * 
+ * 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.
+ */
+
+package org.apache.maven.mae.boot.log;
+
+import org.apache.maven.execution.BuildFailure;
+import org.apache.maven.execution.BuildSuccess;
+import org.apache.maven.execution.BuildSummary;
+import org.apache.maven.execution.ExecutionEvent;
+import org.apache.maven.execution.ExecutionListener;
+import org.apache.maven.execution.MavenExecutionResult;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.logging.Logger;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+public class EventLogger
+    implements ExecutionListener
+{
+    private final Logger logger;
+
+    private static final int LINE_LENGTH = 72;
+
+    public EventLogger( final Logger logger )
+    {
+        if ( logger == null )
+        {
+            throw new IllegalArgumentException( "logger missing" );
+        }
+
+        this.logger = logger;
+    }
+
+    private static String chars( final char c, final int count )
+    {
+        final StringBuilder buffer = new StringBuilder( count );
+
+        for ( int i = count; i > 0; i-- )
+        {
+            buffer.append( c );
+        }
+
+        return buffer.toString();
+    }
+
+    private static String getFormattedTime( final long time )
+    {
+        String pattern = "s.SSS's'";
+
+        if ( time / 60000L > 0 )
+        {
+            pattern = "m:s" + pattern;
+
+            if ( time / 3600000L > 0 )
+            {
+                pattern = "H:m" + pattern;
+            }
+        }
+
+        final DateFormat fmt = new SimpleDateFormat( pattern );
+        fmt.setTimeZone( TimeZone.getTimeZone( "UTC" ) );
+
+        return fmt.format( new Date( time ) );
+    }
+
+    public void projectDiscoveryStarted( final ExecutionEvent event )
+    {
+        if ( logger.isInfoEnabled() )
+        {
+            logger.info( "Scanning for projects..." );
+        }
+    }
+
+    public void sessionStarted( final ExecutionEvent event )
+    {
+        if ( logger.isInfoEnabled() && event.getSession().getProjects().size() > 1 )
+        {
+            logger.info( chars( '-', LINE_LENGTH ) );
+
+            logger.info( "Reactor Build Order:" );
+
+            logger.info( "" );
+
+            for ( final MavenProject project : event.getSession().getProjects() )
+            {
+                logger.info( project.getName() );
+            }
+        }
+    }
+
+    public void sessionEnded( final ExecutionEvent event )
+    {
+        if ( logger.isInfoEnabled() )
+        {
+            if ( event.getSession().getProjects().size() > 1 )
+            {
+                logReactorSummary( event.getSession() );
+            }
+
+            logResult( event.getSession() );
+
+            logStats( event.getSession() );
+
+            logger.info( chars( '-', LINE_LENGTH ) );
+        }
+    }
+
+    private void logReactorSummary( final MavenSession session )
+    {
+        logger.info( chars( '-', LINE_LENGTH ) );
+
+        logger.info( "Reactor Summary:" );
+
+        logger.info( "" );
+
+        final MavenExecutionResult result = session.getResult();
+
+        for ( final MavenProject project : session.getProjects() )
+        {
+            final StringBuilder buffer = new StringBuilder( 128 );
+
+            buffer.append( project.getName() );
+
+            buffer.append( ' ' );
+            while ( buffer.length() < LINE_LENGTH - 21 )
+            {
+                buffer.append( '.' );
+            }
+            buffer.append( ' ' );
+
+            final BuildSummary buildSummary = result.getBuildSummary( project );
+
+            if ( buildSummary == null )
+            {
+                buffer.append( "SKIPPED" );
+            }
+            else if ( buildSummary instanceof BuildSuccess )
+            {
+                buffer.append( "SUCCESS [" );
+                buffer.append( getFormattedTime( buildSummary.getTime() ) );
+                buffer.append( "]" );
+            }
+            else if ( buildSummary instanceof BuildFailure )
+            {
+                buffer.append( "FAILURE [" );
+                buffer.append( getFormattedTime( buildSummary.getTime() ) );
+                buffer.append( "]" );
+            }
+
+            logger.info( buffer.toString() );
+        }
+    }
+
+    private void logResult( final MavenSession session )
+    {
+        logger.info( chars( '-', LINE_LENGTH ) );
+
+        if ( session.getResult().hasExceptions() )
+        {
+            logger.info( "BUILD FAILURE" );
+        }
+        else
+        {
+            logger.info( "BUILD SUCCESS" );
+        }
+    }
+
+    private void logStats( final MavenSession session )
+    {
+        logger.info( chars( '-', LINE_LENGTH ) );
+
+        final Date finish = new Date();
+
+        final long time = finish.getTime() - session.getRequest().getStartTime().getTime();
+
+        final String wallClock = session.getRequest().isThreadConfigurationPresent() ? " (Wall Clock)" : "";
+
+        logger.info( "Total time: " + getFormattedTime( time ) + wallClock );
+
+        logger.info( "Finished at: " + finish );
+
+        System.gc();
+
+        final Runtime r = Runtime.getRuntime();
+
+        final long MB = 1024 * 1024;
+
+        logger.info( "Final Memory: " + ( r.totalMemory() - r.freeMemory() ) / MB + "M/" + r.totalMemory() / MB + "M" );
+    }
+
+    public void projectSkipped( final ExecutionEvent event )
+    {
+        if ( logger.isInfoEnabled() )
+        {
+            logger.info( chars( ' ', LINE_LENGTH ) );
+            logger.info( chars( '-', LINE_LENGTH ) );
+
+            logger.info( "Skipping " + event.getProject().getName() );
+            logger.info( "This project has been banned from the build due to previous failures." );
+
+            logger.info( chars( '-', LINE_LENGTH ) );
+        }
+    }
+
+    public void projectStarted( final ExecutionEvent event )
+    {
+        if ( logger.isInfoEnabled() )
+        {
+            logger.info( chars( ' ', LINE_LENGTH ) );
+            logger.info( chars( '-', LINE_LENGTH ) );
+
+            logger.info( "Building " + event.getProject().getName() + " " + event.getProject().getVersion() );
+
+            logger.info( chars( '-', LINE_LENGTH ) );
+        }
+    }
+
+    public void mojoSkipped( final ExecutionEvent event )
+    {
+        if ( logger.isWarnEnabled() )
+        {
+            logger.warn( "Goal " + event.getMojoExecution().getGoal()
+                            + " requires online mode for execution but Maven is currently offline, skipping" );
+        }
+    }
+
+    public void mojoStarted( final ExecutionEvent event )
+    {
+        if ( logger.isInfoEnabled() )
+        {
+            final StringBuilder buffer = new StringBuilder( 128 );
+
+            buffer.append( "--- " );
+            append( buffer, event.getMojoExecution() );
+            append( buffer, event.getProject() );
+            buffer.append( " ---" );
+
+            logger.info( "" );
+            logger.info( buffer.toString() );
+        }
+    }
+
+    public void forkStarted( final ExecutionEvent event )
+    {
+        if ( logger.isInfoEnabled() )
+        {
+            final StringBuilder buffer = new StringBuilder( 128 );
+
+            buffer.append( ">>> " );
+            append( buffer, event.getMojoExecution() );
+            append( buffer, event.getProject() );
+            buffer.append( " >>>" );
+
+            logger.info( "" );
+            logger.info( buffer.toString() );
+        }
+    }
+
+    public void forkSucceeded( final ExecutionEvent event )
+    {
+        if ( logger.isInfoEnabled() )
+        {
+            final StringBuilder buffer = new StringBuilder( 128 );
+
+            buffer.append( "<<< " );
+            append( buffer, event.getMojoExecution() );
+            append( buffer, event.getProject() );
+            buffer.append( " <<<" );
+
+            logger.info( "" );
+            logger.info( buffer.toString() );
+        }
+    }
+
+    private void append( final StringBuilder buffer, final MojoExecution me )
+    {
+        buffer.append( me.getArtifactId() ).append( ':' ).append( me.getVersion() );
+        buffer.append( ':' ).append( me.getGoal() );
+        if ( me.getExecutionId() != null )
+        {
+            buffer.append( " (" ).append( me.getExecutionId() ).append( ')' );
+        }
+    }
+
+    private void append( final StringBuilder buffer, final MavenProject project )
+    {
+        buffer.append( " @ " ).append( project.getArtifactId() );
+    }
+
+    public void forkedProjectStarted( final ExecutionEvent event )
+    {
+        if ( logger.isInfoEnabled() && event.getMojoExecution().getForkedExecutions().size() > 1 )
+        {
+            logger.info( chars( ' ', LINE_LENGTH ) );
+            logger.info( chars( '>', LINE_LENGTH ) );
+
+            logger.info( "Forking " + event.getProject().getName() + " " + event.getProject().getVersion() );
+
+            logger.info( chars( '>', LINE_LENGTH ) );
+        }
+    }
+
+    public void forkFailed( final ExecutionEvent event )
+    {
+    }
+
+    public void forkedProjectFailed( final ExecutionEvent event )
+    {
+    }
+
+    public void forkedProjectSucceeded( final ExecutionEvent event )
+    {
+    }
+
+    public void mojoFailed( final ExecutionEvent event )
+    {
+    }
+
+    public void mojoSucceeded( final ExecutionEvent event )
+    {
+    }
+
+    public void projectFailed( final ExecutionEvent event )
+    {
+    }
+
+    public void projectSucceeded( final ExecutionEvent event )
+    {
+    }
+
+}

Propchange: maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/log/EventLogger.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/log/InteractiveTransferListener.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/log/InteractiveTransferListener.java?rev=1104405&view=auto
==============================================================================
--- maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/log/InteractiveTransferListener.java (added)
+++ maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/log/InteractiveTransferListener.java Tue May 17 16:57:50 2011
@@ -0,0 +1,222 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * 
+ * 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.
+ */
+
+package org.apache.maven.mae.boot.log;
+
+import org.apache.maven.repository.ArtifactTransferEvent;
+import org.apache.maven.repository.ArtifactTransferListener;
+import org.apache.maven.repository.ArtifactTransferResource;
+
+import java.io.PrintStream;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class InteractiveTransferListener
+    implements ArtifactTransferListener
+{
+
+    private final Map<ArtifactTransferResource, Long> downloads =
+        new ConcurrentHashMap<ArtifactTransferResource, Long>();
+
+    private int lastLength;
+
+    protected PrintStream out;
+
+    private boolean showChecksumEvents;
+
+    public InteractiveTransferListener( final PrintStream out )
+    {
+        this.out = out;
+    }
+
+    protected void doProgress( final ArtifactTransferEvent transferEvent )
+    {
+        final ArtifactTransferResource resource = transferEvent.getResource();
+        downloads.put( resource, Long.valueOf( transferEvent.getTransferredBytes() ) );
+
+        final StringBuilder buffer = new StringBuilder( 64 );
+
+        for ( final Map.Entry<ArtifactTransferResource, Long> entry : downloads.entrySet() )
+        {
+            final long total = entry.getKey().getContentLength();
+            final long complete = entry.getValue().longValue();
+
+            buffer.append( getStatus( complete, total ) ).append( "  " );
+        }
+
+        final int pad = lastLength - buffer.length();
+        lastLength = buffer.length();
+        pad( buffer, pad );
+        buffer.append( '\r' );
+
+        out.print( buffer );
+    }
+
+    private String getStatus( final long complete, final long total )
+    {
+        if ( total >= 1024 )
+        {
+            return toKB( complete ) + "/" + toKB( total ) + " KB ";
+        }
+        else if ( total >= 0 )
+        {
+            return complete + "/" + total + " B ";
+        }
+        else if ( complete >= 1024 )
+        {
+            return toKB( complete ) + " KB ";
+        }
+        else
+        {
+            return complete + " B ";
+        }
+    }
+
+    private void pad( final StringBuilder buffer, int spaces )
+    {
+        final String block = "                                        ";
+        while ( spaces > 0 )
+        {
+            final int n = Math.min( spaces, block.length() );
+            buffer.append( block, 0, n );
+            spaces -= n;
+        }
+    }
+
+    public void transferCompleted( final ArtifactTransferEvent transferEvent )
+    {
+        downloads.remove( transferEvent.getResource() );
+
+        final StringBuilder buffer = new StringBuilder( 64 );
+        pad( buffer, lastLength );
+        buffer.append( '\r' );
+        out.print( buffer );
+
+        if ( !showEvent( transferEvent ) )
+        {
+            return;
+        }
+
+        doCompleted( transferEvent );
+    }
+
+    protected boolean showEvent( final ArtifactTransferEvent event )
+    {
+        if ( event.getResource() == null )
+        {
+            return true;
+        }
+
+        final String resource = event.getResource().getName();
+
+        if ( resource == null || resource.trim().length() == 0 )
+        {
+            return true;
+        }
+
+        if ( resource.endsWith( ".sha1" ) || resource.endsWith( ".md5" ) )
+        {
+            return showChecksumEvents;
+        }
+
+        return true;
+    }
+
+    public void transferInitiated( final ArtifactTransferEvent transferEvent )
+    {
+        if ( !showEvent( transferEvent ) )
+        {
+            return;
+        }
+
+        doInitiated( transferEvent );
+    }
+
+    protected void doInitiated( final ArtifactTransferEvent transferEvent )
+    {
+        final String message =
+            transferEvent.getRequestType() == ArtifactTransferEvent.REQUEST_PUT ? "Uploading" : "Downloading";
+
+        out.println( message + ": " + transferEvent.getResource().getUrl() );
+    }
+
+    public void transferStarted( final ArtifactTransferEvent transferEvent )
+    {
+        if ( !showEvent( transferEvent ) )
+        {
+            return;
+        }
+
+        doStarted( transferEvent );
+    }
+
+    protected void doStarted( final ArtifactTransferEvent transferEvent )
+    {
+        // to be overriden by sub classes
+    }
+
+    public void transferProgress( final ArtifactTransferEvent transferEvent )
+    {
+        if ( !showEvent( transferEvent ) )
+        {
+            return;
+        }
+
+        doProgress( transferEvent );
+    }
+
+    protected void doCompleted( final ArtifactTransferEvent transferEvent )
+    {
+        final ArtifactTransferResource artifact = transferEvent.getResource();
+        final long contentLength = transferEvent.getTransferredBytes();
+        if ( contentLength >= 0 )
+        {
+            final String type =
+                ( transferEvent.getRequestType() == ArtifactTransferEvent.REQUEST_PUT ? "Uploaded" : "Downloaded" );
+            final String len = contentLength >= 1024 ? toKB( contentLength ) + " KB" : contentLength + " B";
+
+            String throughput = "";
+            final long duration = System.currentTimeMillis() - artifact.getTransferStartTime();
+            if ( duration > 0 )
+            {
+                final DecimalFormat format = new DecimalFormat( "0.0", new DecimalFormatSymbols( Locale.ENGLISH ) );
+                final double kbPerSec = ( contentLength / 1024.0 ) / ( duration / 1000.0 );
+                throughput = " at " + format.format( kbPerSec ) + " KB/sec";
+            }
+
+            out.println( type + ": " + artifact.getUrl() + " (" + len + throughput + ")" );
+        }
+    }
+
+    protected long toKB( final long bytes )
+    {
+        return ( bytes + 1023 ) / 1024;
+    }
+
+    public boolean isShowChecksumEvents()
+    {
+        return showChecksumEvents;
+    }
+
+    public void setShowChecksumEvents( final boolean showChecksumEvents )
+    {
+        this.showChecksumEvents = showChecksumEvents;
+    }
+
+}

Propchange: maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/log/InteractiveTransferListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/main/CliRequest.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/main/CliRequest.java?rev=1104405&view=auto
==============================================================================
--- maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/main/CliRequest.java (added)
+++ maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/main/CliRequest.java Tue May 17 16:57:50 2011
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * 
+ * 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.
+ */
+
+package org.apache.maven.mae.boot.main;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.maven.mae.DefaultMAEExecutionRequest;
+import org.apache.maven.mae.MAEExecutionRequest;
+import org.apache.maven.mae.boot.embed.EMBEmbedderBuilder;
+import org.codehaus.plexus.classworlds.ClassWorld;
+
+import java.io.PrintStream;
+import java.util.Properties;
+
+public final class CliRequest
+{
+    public String[] args;
+
+    public CommandLine commandLine;
+
+    public String workingDirectory;
+
+    public PrintStream fileStream;
+
+    public Properties userProperties = new Properties();
+
+    public Properties systemProperties = new Properties();
+
+    public MAEExecutionRequest request;
+
+    public EMBEmbedderBuilder builder;
+
+    public CliRequest( final String[] args, final ClassWorld classWorld )
+    {
+        this.args = args;
+        builder = new EMBEmbedderBuilder().withClassWorld( classWorld );
+        request = new DefaultMAEExecutionRequest();
+    }
+
+}

Propchange: maven/sandbox/trunk/mae/mae-booter/src/main/java/org/apache/maven/mae/boot/main/CliRequest.java
------------------------------------------------------------------------------
    svn:eol-style = native