package com.intellij.flex.maven; import org.apache.maven.execution.MavenSession; import org.apache.maven.lifecycle.internal.LifecycleExecutionPlanCalculator; import org.apache.maven.model.Plugin; import org.apache.maven.model.PluginExecution; import org.apache.maven.model.building.ModelBuildingRequest; import org.apache.maven.plugin.BuildPluginManager; import org.apache.maven.plugin.MojoExecution; import org.apache.maven.plugin.PluginManagerException; import org.apache.maven.plugin.PluginResolutionException; import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.plugin.version.DefaultPluginVersionRequest; import org.apache.maven.plugin.version.PluginVersionResolver; import org.apache.maven.project.MavenProject; import org.apache.maven.project.ProjectBuilder; import org.apache.maven.project.ProjectBuildingRequest; import org.codehaus.plexus.PlexusContainer; import org.codehaus.plexus.classworlds.realm.ClassRealm; import org.codehaus.plexus.component.repository.exception.ComponentLookupException; import org.codehaus.plexus.logging.Logger; import java.io.File; import java.util.Date; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; final class Maven { private final ConcurrentMap<File, AtomicNotNullLazyValue<MavenProject>> projectsCache = new ConcurrentHashMap<File, AtomicNotNullLazyValue<MavenProject>>(); private final PlexusContainer plexusContainer; private final MavenSession session; private final BuildPluginManager pluginManager; private final ProjectBuilder projectBuilder; private final Date buildStartDate = new Date(); public Maven(PlexusContainer plexusContainer, MavenSession session) throws ComponentLookupException { this.plexusContainer = plexusContainer; this.session = session; pluginManager = plexusContainer.lookup(BuildPluginManager.class); projectBuilder = plexusContainer.lookup(ProjectBuilder.class); } /** * Copied from com.intellij.openapi.util.* * @author peter */ private abstract class AtomicNotNullLazyValue<T> { private volatile T myValue; protected abstract T compute(); public final T getValue() { T value = myValue; if (value != null) { return value; } synchronized (this) { value = myValue; if (value == null) { myValue = value = compute(); } } return value; } } // @Nullable return null if cannot read public MavenProject readProject(final File pomFile, final Logger logger) { AtomicNotNullLazyValue<MavenProject> projectRef = projectsCache.get(pomFile); if (projectRef == null) { AtomicNotNullLazyValue<MavenProject> candidate = projectsCache.putIfAbsent(pomFile, projectRef = new AtomicNotNullLazyValue<MavenProject>() { @Override protected MavenProject compute() { ProjectBuildingRequest projectBuildingRequest = session.getRequest().getProjectBuildingRequest(); projectBuildingRequest.setResolveDependencies(true); projectBuildingRequest.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL); projectBuildingRequest.setRepositorySession(session.getRepositorySession()); projectBuildingRequest.setBuildStartTime(buildStartDate); try { return projectBuilder.build(pomFile, projectBuildingRequest).getProject(); } catch (Throwable e) { logger.error("Cannot read project " + pomFile.getPath(), e); return null; } } }); if (candidate != null) { projectRef = candidate; } } return projectRef.getValue(); } public MojoExecution createMojoExecution(Plugin plugin, String goal, MavenProject project) throws Exception { if (plugin.getVersion() == null) { plugin.setVersion(plexusContainer.lookup(PluginVersionResolver.class).resolve(new DefaultPluginVersionRequest(plugin, session)).getVersion()); } MojoDescriptor mojoDescriptor = pluginManager.getMojoDescriptor(plugin, goal, project.getRemotePluginRepositories(), session.getRepositorySession()); List<PluginExecution> executions = plugin.getExecutions(); MojoExecution mojoExecution = new MojoExecution(mojoDescriptor, executions.isEmpty() ? null : executions.get(executions.size() - 1).getId(), MojoExecution.Source.CLI); plexusContainer.lookup(LifecycleExecutionPlanCalculator.class).setupMojoExecution(session, project, mojoExecution); return mojoExecution; } @SuppressWarnings("UnusedParameters") public synchronized void releaseMojoExecution(MojoExecution mojoExecution) throws Exception { } public ClassRealm getPluginRealm(MojoExecution mojoExecution) throws PluginManagerException, PluginResolutionException { return pluginManager.getPluginRealm(session, mojoExecution.getMojoDescriptor().getPluginDescriptor()); } }