package org.apache.maven.diagrams.connector_api.context; import java.io.File; import java.util.Arrays; import org.apache.maven.diagrams.connector_api.ConnectorException; import org.apache.maven.diagrams.connector_api.logger.ConnectorLoggerToMavenEmbadderLoggerAdapter; import org.apache.maven.embedder.Configuration; import org.apache.maven.embedder.ConfigurationValidationResult; import org.apache.maven.embedder.DefaultConfiguration; import org.apache.maven.embedder.MavenEmbedder; import org.apache.maven.embedder.MavenEmbedderException; import org.apache.maven.execution.DefaultMavenExecutionRequest; import org.apache.maven.execution.MavenExecutionRequest; import org.apache.maven.execution.MavenExecutionResult; import org.apache.maven.project.MavenProject; /** * The ConnectorContext's implementation lazily runs the embadded maven (from mavenHomeDir) in given (baseDir) * directory. The resulting mavenProject is stored for the future calls to the getMavenProject() method. * * @author Piotr Tabor (ptab@newitech.com) */ public class RunMavenConnectorContext extends AbstractConnectorContext { private File baseDir; private String mavenPhase; private File mavenHomeDir; private MavenProject root; /* ----------------- Constructors --------------------------- */ /** * Creates configuration for run maven's "package" phase in current directory */ public RunMavenConnectorContext() { super(); baseDir = null; mavenPhase = "package"; mavenHomeDir = null; } /** * Creates configuration for run maven's "mavenPhase" phase in given baseDir directory */ public RunMavenConnectorContext( File baseDir, String mavenPhase ) { super(); this.baseDir = baseDir; this.mavenPhase = mavenPhase; this.mavenHomeDir = null; } /** * Create configuration for run maven's "mavenPhase" phase in given baseDir directory * * It uses mavenHomeDirectory to find maven's configuration files */ public RunMavenConnectorContext( File baseDir, String mavenPhase, File mavenHomeDir ) { super(); this.baseDir = baseDir; this.mavenPhase = mavenPhase; this.mavenHomeDir = mavenHomeDir; } /*------------------------- Logic --------------------------- */ public synchronized MavenProject getMavenProject() throws ConnectorException { if ( root == null ) { root = prepareMavenProject(); } return root; } /** * The method tries to path to Maven's global settings by first available options from: * * <ol> * <li>mavenHomeDir/conf/settings.xml (if mavenHomeDir is not null) * <li>maven.home/conf/settings.xml (where maven.home is system property)</li> * <li>M2_HOME/conf/settings.xml (where M2_HOME is environment variable)</li> * <li>MavenEmbedder.DEFAULT_GLOBAL_SETTINGS_FILE</li> * </ol> * * @return */ protected File getGlobalSettingsFile() { if ( mavenHomeDir == null ) { if ( System.getProperty( "maven.home" ) != null ) return new File( System.getProperty( "maven.home" ), "conf/settings.xml" ); if ( System.getenv( "M2_HOME" ) != null ) return new File( System.getenv( "M2_HOME" ), "conf/settings.xml" ); if ( getLogger() != null ) getLogger().error( "RunMavenConnectorContext.mavenHomeDir nor maven.home variable nor M2_HOME environment variable is not set !!!" ); return MavenEmbedder.DEFAULT_GLOBAL_SETTINGS_FILE; } else { return new File( mavenHomeDir, "conf/settings/xml" ); } } /** * The method runs embedded maven and returns the mavenProject. * * @return created mavenProject * @throws ConnectorException */ private synchronized MavenProject prepareMavenProject() throws ConnectorException { try { File projectDirectory = baseDir == null ? new File( "." ) : baseDir; Configuration configuration = new DefaultConfiguration(); configuration.setUserSettingsFile( MavenEmbedder.DEFAULT_USER_SETTINGS_FILE ); configuration.setGlobalSettingsFile( getGlobalSettingsFile() ); ConfigurationValidationResult validationResult = MavenEmbedder.validateConfiguration( configuration ); if ( validationResult.isValid() ) { MavenEmbedder embedder; embedder = new MavenEmbedder( configuration ); embedder.setLogger( new ConnectorLoggerToMavenEmbadderLoggerAdapter( getLogger() ) ); MavenExecutionRequest request = new DefaultMavenExecutionRequest().setBaseDirectory( projectDirectory ).setGoals( Arrays.asList( new String[] { mavenPhase } ) ); MavenExecutionResult result = embedder.execute( request ); if ( result.hasExceptions() ) { throw new ConnectorException( "Embadded maven exception", (Exception) result.getExceptions().iterator().next() ); } MavenProject project = result.getMavenProject(); if ( getLogger() != null ) getLogger().info( project.getArtifactMap().toString() ); return project; } else { throw new ConnectorException( "Embadded maven configuration is not valid" ); } } catch ( MavenEmbedderException e ) { throw new ConnectorException( e.getMessage(), e ); } } /*------------------- Getters and Setters ----------------------*/ /** * Gets the directory in which the embedded maven will be run in. * The directory should contain the 'pom.xml' file. */ public File getBaseDir() { return baseDir; } /** * Sets the directory in which the embedded maven will be run in. * The directory should contain the 'pom.xml' file. */ public void setBaseDir( File baseDir ) { this.baseDir = baseDir; } /** * Gets the phase to which the project will be build to. * @return the maven phase. */ public String getMavenPhase() { return mavenPhase; } /** * Sets the phase to which the project will be build to. * * @param mavenPhase that will be set up. */ public void setMavenPhase( String mavenPhase ) { this.mavenPhase = mavenPhase; } /** * Returns the directory in which the maven's configuration file will be looked for. * * @return the installed maven home directory. */ public File getMavenHomeDir() { return mavenHomeDir; } /** * Sets the directory in which the maven's configuration file will be looked for. * * @param mavenHomeDir */ public void setMavenHomeDir( File mavenHomeDir ) { this.mavenHomeDir = mavenHomeDir; } }