All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sonar.maven.SonarMavenEmbedder Maven / Gradle / Ivy

/*
 * Sonar, open source software quality management tool.
 * Copyright (C) 2009 SonarSource SA
 * mailto:contact AT sonarsource DOT com
 *
 * Sonar is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * Sonar is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with Sonar; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
 */
package org.sonar.maven;

import java.io.File;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;

import org.apache.maven.BuildFailureException;
import org.apache.maven.artifact.manager.WagonManager;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.ArtifactRepositoryFactory;
import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.embedder.MavenEmbedderException;
import org.apache.maven.embedder.MavenEmbedderLogger;
import org.apache.maven.embedder.MavenEmbedderLoggerManager;
import org.apache.maven.embedder.PlexusLoggerAdapter;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.execution.ReactorManager;
import org.apache.maven.lifecycle.LifecycleExecutionException;
import org.apache.maven.lifecycle.LifecycleExecutor;
import org.apache.maven.monitor.event.DefaultEventDispatcher;
import org.apache.maven.monitor.event.EventDispatcher;
import org.apache.maven.monitor.event.EventMonitor;
import org.apache.maven.profiles.DefaultProfileManager;
import org.apache.maven.profiles.ProfileManager;
import org.apache.maven.project.DuplicateProjectException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectBuilder;
import org.apache.maven.project.ProjectBuildingException;
import org.apache.maven.settings.Mirror;
import org.apache.maven.settings.Proxy;
import org.apache.maven.settings.Server;
import org.apache.maven.settings.Settings;
import org.apache.maven.wagon.events.TransferListener;
import org.codehaus.classworlds.ClassWorld;
import org.codehaus.plexus.PlexusContainerException;
import org.codehaus.plexus.component.repository.exception.ComponentLifecycleException;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.embed.Embedder;
import org.codehaus.plexus.util.dag.CycleDetectedException;
import org.codehaus.plexus.util.xml.Xpp3Dom;

/**
 * Maven embedder which fixes issues with class loading, proxy settings, mirror settings
 * maven custom settings files
 */
public class SonarMavenEmbedder {

  public static final String DEFAULT_LOCAL_REPO_ID = "local";
  public static final String DEFAULT_LAYOUT_ID = "default";
  
  private Embedder embedder;
  private MavenProjectBuilder mavenProjectBuilder;
  private ArtifactRepositoryFactory artifactRepositoryFactory;
  private LifecycleExecutor lifecycleExecutor;
  private WagonManager wagonManager;
  private ProfileManager profileManager;
  private ArtifactRepositoryLayout defaultArtifactRepositoryLayout;

  private Settings settings;
  private ArtifactRepository localRepository;
  private MavenEmbedderLogger logger;
  private ClassWorld classworld;

  public SonarMavenEmbedder(Settings settings, ClassWorld classworld) {
    super();
    this.settings = settings;
    this.classworld = classworld;
  }

  public ArtifactRepository getLocalRepository() {
    return localRepository;
  }

  public MavenEmbedderLogger getLogger() {
    return logger;
  }

  public void setLogger( MavenEmbedderLogger logger ) {
    this.logger = logger;
  }

  public MavenProject readProjectWithDependencies( File mavenProject )
  throws ProjectBuildingException, ArtifactResolutionException, ArtifactNotFoundException {
    return mavenProjectBuilder.buildWithDependencies( mavenProject, localRepository, profileManager );
  }

  public void execute( MavenProject project, List goals, EventMonitor eventMonitor,
                       TransferListener transferListener, Properties properties, File executionRootDirectory )
                       throws CycleDetectedException, LifecycleExecutionException, BuildFailureException, DuplicateProjectException {
    execute( Collections.singletonList( project ), goals, eventMonitor, transferListener, properties, executionRootDirectory );
  }

  public void execute( List projects, List goals, EventMonitor eventMonitor,
                       TransferListener transferListener, Properties properties, File executionRootDirectory )
                       throws CycleDetectedException, LifecycleExecutionException, BuildFailureException, DuplicateProjectException {
    ReactorManager rm = new ReactorManager( projects );
    EventDispatcher eventDispatcher = new DefaultEventDispatcher();
    eventDispatcher.addEventMonitor( eventMonitor );

    // If this option is set the exception seems to be hidden ...
    rm.setFailureBehavior( ReactorManager.FAIL_FAST );

    MavenSession session = new MavenSession( embedder.getContainer(), settings, localRepository,
                                             eventDispatcher, rm, goals, executionRootDirectory.getAbsolutePath(),
                                             properties, new Date() );

    session.setUsingPOMsFromFilesystem( true );
    if ( transferListener != null ) {
      wagonManager.setDownloadMonitor( transferListener );
    }

    // ----------------------------------------------------------------------
    // Maven should not be using system properties internally but because
    // it does for now I'll just take properties that are handed to me
    // and set them so that the plugin expression evaluator will work
    // as expected.
    // ----------------------------------------------------------------------

    if ( properties != null ) {
      for ( Iterator i = properties.keySet().iterator(); i.hasNext(); ) {
        String key = (String)i.next();
        String value = properties.getProperty( key );
        System.setProperty( key, value );
      }
    }
    lifecycleExecutor.execute( session, rm, session.getEventDispatcher() );
  }

  private ArtifactRepository createLocalRepository( Settings settings ) throws ComponentLookupException {
    return createLocalRepository( settings.getLocalRepository(), DEFAULT_LOCAL_REPO_ID );
  }

  private ArtifactRepository createLocalRepository( String url, String repositoryId ) throws ComponentLookupException {
    if ( !url.startsWith( "file:" ) ) {
      url = "file://" + url;
    }
    return createRepository( url, repositoryId );
  }

  private ArtifactRepository createRepository( String url, String repositoryId ) throws ComponentLookupException {

    String updatePolicyFlag = ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS;
    String checksumPolicyFlag = ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN;
    ArtifactRepositoryPolicy snapshotsPolicy = new ArtifactRepositoryPolicy( true, updatePolicyFlag, checksumPolicyFlag );
    ArtifactRepositoryPolicy releasesPolicy = new ArtifactRepositoryPolicy( true, updatePolicyFlag, checksumPolicyFlag );
    return artifactRepositoryFactory.createArtifactRepository( repositoryId, url, defaultArtifactRepositoryLayout, snapshotsPolicy, releasesPolicy );
  }

  public void start() throws MavenEmbedderException {

    embedder = new Embedder();

    if ( logger != null ) {
      embedder.setLoggerManager( new MavenEmbedderLoggerManager( new PlexusLoggerAdapter( logger ) ) );
    }

    try {
      embedder.start( classworld );

      profileManager = new DefaultProfileManager( embedder.getContainer(), settings, System.getProperties() );
      mavenProjectBuilder = (MavenProjectBuilder) embedder.lookup( MavenProjectBuilder.ROLE );
      artifactRepositoryFactory = (ArtifactRepositoryFactory) embedder.lookup( ArtifactRepositoryFactory.ROLE );
      defaultArtifactRepositoryLayout = (ArtifactRepositoryLayout) embedder.lookup( ArtifactRepositoryLayout.ROLE, DEFAULT_LAYOUT_ID );
      lifecycleExecutor = (LifecycleExecutor) embedder.lookup( LifecycleExecutor.ROLE );
      wagonManager = (WagonManager) embedder.lookup( WagonManager.ROLE );

      setupWagonManager();

      localRepository = createLocalRepository( settings );
    } catch ( PlexusContainerException e ) {
      throw new MavenEmbedderException( "Cannot start Plexus embedder.", e );
    } catch ( ComponentLookupException e ) {
      throw new MavenEmbedderException( "Cannot lookup required component.", e );
    }
  }

  private void setupWagonManager() {
    wagonManager.setOnline(true);
    wagonManager.setInteractive(false);
    
    if ( settings.getActiveProxy() != null ) {
      Proxy proxy = settings.getActiveProxy();
      getLogger().debug("Setting wagon manager active proxy " + proxy.getProtocol() + "," + proxy.getHost() + "," + 
          proxy.getPort() + "," + proxy.getUsername() + "," +  proxy.getNonProxyHosts());
      wagonManager.addProxy( proxy.getProtocol(), proxy.getHost(), proxy.getPort(), proxy.getUsername(), proxy.getPassword(), proxy.getNonProxyHosts());
    }

    if ( settings.getMirrors() != null ) {
      List mirrors = settings.getMirrors();
      for (Mirror mirror : mirrors) {
        getLogger().debug("Setting wagon manager mirror settings " + mirror.getId() + "," + mirror.getMirrorOf() + "," + mirror.getUrl());
        wagonManager.addMirror(mirror.getId(), mirror.getMirrorOf(), mirror.getUrl());
      }
    }
    
    if ( settings.getServers() != null ) {
      List servers = settings.getServers();
      for (Server server : servers) {
        getLogger().debug("Setting wagon manager auth info " + server.getId() + "," + 
            server.getUsername() + "," + server.getPrivateKey() + "," + server.getPassphrase());
        wagonManager.addAuthenticationInfo(server.getId(), server.getUsername(), server.getPassword(), server.getPrivateKey(), server.getPassphrase());
        getLogger().debug("Setting wagon manager perm info " + 
            server.getId() + "," + server.getFilePermissions()  + "," + server.getDirectoryPermissions());
        wagonManager.addPermissionInfo(server.getId(), server.getFilePermissions(), server.getDirectoryPermissions());
        
        Object serverConfig = server.getConfiguration();
        if (serverConfig != null && serverConfig instanceof Xpp3Dom) {
          getLogger().debug("Setting wagon manager server config " + 
              server.getId() + "," + serverConfig);
          wagonManager.addConfiguration(server.getId(), (Xpp3Dom)serverConfig);
        }
      }
    }
  }

  public void stop() throws MavenEmbedderException {
    try {
      embedder.release( mavenProjectBuilder );
      embedder.release( artifactRepositoryFactory );
      embedder.release( lifecycleExecutor );
      embedder.getContainer().dispose();
      embedder.stop();
      embedder = null;
    } catch ( ComponentLifecycleException e ) {
      throw new MavenEmbedderException( "Cannot stop the embedder.", e );
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy