0001: package org.apache.maven.plugin;
0002:
0003: /*
0004: * Licensed to the Apache Software Foundation (ASF) under one
0005: * or more contributor license agreements. See the NOTICE file
0006: * distributed with this work for additional information
0007: * regarding copyright ownership. The ASF licenses this file
0008: * to you under the Apache License, Version 2.0 (the
0009: * "License"); you may not use this file except in compliance
0010: * with the License. You may obtain a copy of the License at
0011: *
0012: * http://www.apache.org/licenses/LICENSE-2.0
0013: *
0014: * Unless required by applicable law or agreed to in writing,
0015: * software distributed under the License is distributed on an
0016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
0017: * KIND, either express or implied. See the License for the
0018: * specific language governing permissions and limitations
0019: * under the License.
0020: */
0021:
0022: import org.apache.maven.ArtifactFilterManager;
0023: import org.apache.maven.artifact.Artifact;
0024: import org.apache.maven.artifact.factory.ArtifactFactory;
0025: import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
0026: import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
0027: import org.apache.maven.artifact.metadata.ResolutionGroup;
0028: import org.apache.maven.artifact.repository.ArtifactRepository;
0029: import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
0030: import org.apache.maven.artifact.resolver.ArtifactResolutionException;
0031: import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
0032: import org.apache.maven.artifact.resolver.ArtifactResolver;
0033: import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
0034: import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
0035: import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
0036: import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
0037: import org.apache.maven.artifact.versioning.VersionRange;
0038: import org.apache.maven.context.BuildContextManager;
0039: import org.apache.maven.execution.MavenSession;
0040: import org.apache.maven.execution.RuntimeInformation;
0041: import org.apache.maven.lifecycle.LifecycleExecutionContext;
0042: import org.apache.maven.lifecycle.statemgmt.StateManagementUtils;
0043: import org.apache.maven.model.Plugin;
0044: import org.apache.maven.model.ReportPlugin;
0045: import org.apache.maven.monitor.event.EventDispatcher;
0046: import org.apache.maven.monitor.event.MavenEvents;
0047: import org.apache.maven.monitor.logging.DefaultLog;
0048: import org.apache.maven.plugin.descriptor.MojoDescriptor;
0049: import org.apache.maven.plugin.descriptor.Parameter;
0050: import org.apache.maven.plugin.descriptor.PluginDescriptor;
0051: import org.apache.maven.plugin.descriptor.PluginDescriptorBuilder;
0052: import org.apache.maven.plugin.logging.Log;
0053: import org.apache.maven.plugin.version.PluginVersionManager;
0054: import org.apache.maven.plugin.version.PluginVersionNotFoundException;
0055: import org.apache.maven.plugin.version.PluginVersionResolutionException;
0056: import org.apache.maven.project.MavenProject;
0057: import org.apache.maven.project.MavenProjectBuilder;
0058: import org.apache.maven.project.ProjectBuildingException;
0059: import org.apache.maven.project.artifact.InvalidDependencyVersionException;
0060: import org.apache.maven.project.artifact.MavenMetadataSource;
0061: import org.apache.maven.project.path.PathTranslator;
0062: import org.apache.maven.reporting.MavenReport;
0063: import org.codehaus.plexus.PlexusConstants;
0064: import org.codehaus.plexus.PlexusContainer;
0065: import org.codehaus.plexus.PlexusContainerException;
0066: import org.codehaus.plexus.classworlds.realm.ClassRealm;
0067: import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
0068: import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
0069: import org.codehaus.plexus.component.configurator.ComponentConfigurator;
0070: import org.codehaus.plexus.component.configurator.ConfigurationListener;
0071: import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
0072: import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
0073: import org.codehaus.plexus.component.repository.exception.ComponentLifecycleException;
0074: import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
0075: import org.codehaus.plexus.configuration.PlexusConfiguration;
0076: import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
0077: import org.codehaus.plexus.context.Context;
0078: import org.codehaus.plexus.context.ContextException;
0079: import org.codehaus.plexus.logging.AbstractLogEnabled;
0080: import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
0081: import org.codehaus.plexus.util.StringUtils;
0082: import org.codehaus.plexus.util.xml.Xpp3Dom;
0083:
0084: import java.util.ArrayList;
0085: import java.util.Collection;
0086: import java.util.Collections;
0087: import java.util.HashSet;
0088: import java.util.Iterator;
0089: import java.util.LinkedHashSet;
0090: import java.util.List;
0091: import java.util.Map;
0092: import java.util.Set;
0093:
0094: public class DefaultPluginManager extends AbstractLogEnabled implements
0095: PluginManager, Contextualizable {
0096: private static final List RESERVED_GROUP_IDS;
0097:
0098: static {
0099: List rgids = new ArrayList();
0100:
0101: rgids.add(StateManagementUtils.GROUP_ID);
0102:
0103: RESERVED_GROUP_IDS = rgids;
0104: }
0105:
0106: protected PlexusContainer container;
0107:
0108: protected PluginDescriptorBuilder pluginDescriptorBuilder;
0109:
0110: protected ArtifactFilterManager coreArtifactFilterManager;
0111:
0112: private Log mojoLogger;
0113:
0114: // component requirements
0115: protected PathTranslator pathTranslator;
0116:
0117: protected MavenPluginCollector pluginCollector;
0118:
0119: protected PluginVersionManager pluginVersionManager;
0120:
0121: protected ArtifactFactory artifactFactory;
0122:
0123: protected ArtifactResolver artifactResolver;
0124:
0125: protected ArtifactMetadataSource artifactMetadataSource;
0126:
0127: protected RuntimeInformation runtimeInformation;
0128:
0129: protected MavenProjectBuilder mavenProjectBuilder;
0130:
0131: protected PluginMappingManager pluginMappingManager;
0132:
0133: private BuildContextManager buildContextManager;
0134:
0135: // END component requirements
0136:
0137: public DefaultPluginManager() {
0138: pluginDescriptorBuilder = new PluginDescriptorBuilder();
0139: }
0140:
0141: // ----------------------------------------------------------------------
0142: //
0143: // ----------------------------------------------------------------------
0144:
0145: public PluginDescriptor getPluginDescriptorForPrefix(String prefix) {
0146: return pluginCollector.getPluginDescriptorForPrefix(prefix);
0147: }
0148:
0149: public Plugin getPluginDefinitionForPrefix(String prefix,
0150: MavenSession session, MavenProject project) {
0151: // TODO: since this is only used in the lifecycle executor, maybe it should be moved there? There is no other
0152: // use for the mapping manager in here
0153: return pluginMappingManager.getByPrefix(prefix, session
0154: .getSettings().getPluginGroups(), project
0155: .getPluginArtifactRepositories(), session
0156: .getLocalRepository());
0157: }
0158:
0159: public PluginDescriptor verifyPlugin(Plugin plugin,
0160: MavenProject project, MavenSession session)
0161: throws ArtifactResolutionException,
0162: PluginVersionResolutionException,
0163: ArtifactNotFoundException,
0164: InvalidVersionSpecificationException,
0165: InvalidPluginException, PluginManagerException,
0166: PluginNotFoundException, PluginVersionNotFoundException {
0167: // TODO: this should be possibly outside
0168: // All version-resolution logic has been moved to DefaultPluginVersionManager.
0169: if (plugin.getVersion() == null) {
0170: getLogger().debug(
0171: "Resolving version for plugin: " + plugin.getKey());
0172: String version = pluginVersionManager.resolvePluginVersion(
0173: plugin.getGroupId(), plugin.getArtifactId(),
0174: project, session);
0175: plugin.setVersion(version);
0176: }
0177:
0178: return verifyVersionedPlugin(plugin, project, session);
0179: }
0180:
0181: private PluginDescriptor verifyVersionedPlugin(Plugin plugin,
0182: MavenProject project, MavenSession session)
0183: throws PluginVersionResolutionException,
0184: ArtifactNotFoundException, ArtifactResolutionException,
0185: InvalidVersionSpecificationException,
0186: InvalidPluginException, PluginManagerException,
0187: PluginNotFoundException {
0188: ArtifactRepository localRepository = session
0189: .getLocalRepository();
0190:
0191: return verifyVersionedPlugin(plugin, project, localRepository);
0192: }
0193:
0194: private PluginDescriptor verifyVersionedPlugin(Plugin plugin,
0195: MavenProject project, ArtifactRepository localRepository)
0196: throws PluginVersionResolutionException,
0197: ArtifactNotFoundException, ArtifactResolutionException,
0198: InvalidVersionSpecificationException,
0199: InvalidPluginException, PluginManagerException,
0200: PluginNotFoundException {
0201: getLogger().debug(
0202: "In verifyVersionedPlugin for: " + plugin.getKey());
0203:
0204: // TODO: this might result in an artifact "RELEASE" being resolved continuously
0205: // FIXME: need to find out how a plugin gets marked as 'installed'
0206: // and no ChildContainer exists. The check for that below fixes
0207: // the 'Can't find plexus container for plugin: xxx' error.
0208: try {
0209: // if the groupId is internal, don't try to resolve it...
0210: if (!RESERVED_GROUP_IDS.contains(plugin.getGroupId())) {
0211: VersionRange versionRange = VersionRange
0212: .createFromVersionSpec(plugin.getVersion());
0213:
0214: List remoteRepositories = new ArrayList();
0215:
0216: remoteRepositories.addAll(project
0217: .getPluginArtifactRepositories());
0218:
0219: remoteRepositories.addAll(project
0220: .getRemoteArtifactRepositories());
0221:
0222: checkRequiredMavenVersion(plugin, localRepository,
0223: remoteRepositories);
0224:
0225: Artifact pluginArtifact = artifactFactory
0226: .createPluginArtifact(plugin.getGroupId(),
0227: plugin.getArtifactId(), versionRange);
0228:
0229: pluginArtifact = project
0230: .replaceWithActiveArtifact(pluginArtifact);
0231:
0232: artifactResolver.resolve(pluginArtifact, project
0233: .getPluginArtifactRepositories(),
0234: localRepository);
0235:
0236: addPlugin(plugin, pluginArtifact, project,
0237: localRepository);
0238: } else {
0239: getLogger().debug(
0240: "Skipping resolution for Maven built-in plugin: "
0241: + plugin.getKey());
0242:
0243: PluginDescriptor pd = pluginCollector
0244: .getPluginDescriptor(plugin);
0245: pd.setClassRealm(container.getContainerRealm());
0246: }
0247:
0248: project.addPlugin(plugin);
0249: } catch (ArtifactNotFoundException e) {
0250: String groupId = plugin.getGroupId();
0251:
0252: String artifactId = plugin.getArtifactId();
0253:
0254: String version = plugin.getVersion();
0255:
0256: if ((groupId == null) || (artifactId == null)
0257: || (version == null)) {
0258: throw new PluginNotFoundException(e);
0259: } else if (groupId.equals(e.getGroupId())
0260: && artifactId.equals(e.getArtifactId())
0261: && version.equals(e.getVersion())
0262: && "maven-plugin".equals(e.getType())) {
0263: throw new PluginNotFoundException(e);
0264: } else {
0265: throw e;
0266: }
0267: }
0268:
0269: PluginDescriptor pluginDescriptor = pluginCollector
0270: .getPluginDescriptor(plugin);
0271:
0272: return pluginDescriptor;
0273: }
0274:
0275: /**
0276: * @todo would be better to store this in the plugin descriptor, but then it won't be available to the version
0277: * manager which executes before the plugin is instantiated
0278: */
0279: private void checkRequiredMavenVersion(Plugin plugin,
0280: ArtifactRepository localRepository, List remoteRepositories)
0281: throws PluginVersionResolutionException,
0282: InvalidPluginException {
0283: try {
0284: Artifact artifact = artifactFactory.createProjectArtifact(
0285: plugin.getGroupId(), plugin.getArtifactId(), plugin
0286: .getVersion());
0287: MavenProject project = mavenProjectBuilder
0288: .buildFromRepository(artifact, remoteRepositories,
0289: localRepository, false);
0290: // if we don't have the required Maven version, then ignore an update
0291: if ((project.getPrerequisites() != null)
0292: && (project.getPrerequisites().getMaven() != null)) {
0293: DefaultArtifactVersion requiredVersion = new DefaultArtifactVersion(
0294: project.getPrerequisites().getMaven());
0295: if (runtimeInformation.getApplicationVersion()
0296: .compareTo(requiredVersion) < 0) {
0297: throw new PluginVersionResolutionException(plugin
0298: .getGroupId(), plugin.getArtifactId(),
0299: "Plugin requires Maven version "
0300: + requiredVersion);
0301: }
0302: }
0303: } catch (ProjectBuildingException e) {
0304: throw new InvalidPluginException(
0305: "Unable to build project for plugin '"
0306: + plugin.getKey() + "': " + e.getMessage(),
0307: e);
0308: }
0309: }
0310:
0311: protected void addPlugin(Plugin plugin, Artifact pluginArtifact,
0312: MavenProject project, ArtifactRepository localRepository)
0313: throws ArtifactNotFoundException,
0314: ArtifactResolutionException, PluginManagerException,
0315: InvalidPluginException {
0316: // ----------------------------------------------------------------------------
0317: // Get the dependencies for the Plugin
0318: // ----------------------------------------------------------------------------
0319:
0320: // the only Plugin instance which will have dependencies is the one specified in the project.
0321: // We need to look for a Plugin instance there, in case the instance we're using didn't come from
0322: // the project.
0323: Plugin projectPlugin = (Plugin) project.getBuild()
0324: .getPluginsAsMap().get(plugin.getKey());
0325:
0326: if (projectPlugin == null) {
0327: projectPlugin = plugin;
0328: }
0329:
0330: Set artifacts = getPluginArtifacts(pluginArtifact,
0331: projectPlugin, project, localRepository);
0332:
0333: addPlugin(plugin, projectPlugin, pluginArtifact, artifacts);
0334: }
0335:
0336: protected void addPlugin(Plugin plugin, Artifact pluginArtifact,
0337: MavenProject project, MavenSession session)
0338: throws ArtifactNotFoundException,
0339: ArtifactResolutionException, PluginManagerException,
0340: InvalidPluginException {
0341: // ----------------------------------------------------------------------------
0342: // Get the dependencies for the Plugin
0343: // ----------------------------------------------------------------------------
0344:
0345: // the only Plugin instance which will have dependencies is the one specified in the project.
0346: // We need to look for a Plugin instance there, in case the instance we're using didn't come from
0347: // the project.
0348: Plugin projectPlugin = (Plugin) project.getBuild()
0349: .getPluginsAsMap().get(plugin.getKey());
0350:
0351: if (projectPlugin == null) {
0352: projectPlugin = plugin;
0353: }
0354:
0355: Set artifacts = getPluginArtifacts(pluginArtifact,
0356: projectPlugin, project, session.getLocalRepository());
0357:
0358: addPlugin(plugin, projectPlugin, pluginArtifact, artifacts);
0359: }
0360:
0361: private void addPlugin(Plugin plugin, Plugin projectPlugin,
0362: Artifact pluginArtifact, Set artifacts)
0363: throws ArtifactNotFoundException,
0364: ArtifactResolutionException, PluginManagerException,
0365: InvalidPluginException {
0366: // TODO When/if we go to project-level plugin instances (like for plugin-level deps in the
0367: // POM), we need to undo this somehow.
0368: ClassRealm pluginRealm = container
0369: .getComponentRealm(projectPlugin.getKey());
0370:
0371: if ((pluginRealm != null)
0372: && (pluginRealm != container.getContainerRealm())) {
0373: getLogger().debug(
0374: "Realm already exists for: "
0375: + projectPlugin.getKey()
0376: + ". Skipping addition...");
0377: // we've already discovered this plugin, and configured it, so skip it this time.
0378:
0379: return;
0380: }
0381:
0382: // ----------------------------------------------------------------------------
0383: // Realm creation for a plugin
0384: // ----------------------------------------------------------------------------
0385:
0386: ClassRealm componentRealm = null;
0387:
0388: try {
0389: List jars = new ArrayList();
0390:
0391: for (Iterator i = artifacts.iterator(); i.hasNext();) {
0392: Artifact artifact = (Artifact) i.next();
0393:
0394: jars.add(artifact.getFile());
0395: }
0396:
0397: jars.add(pluginArtifact.getFile());
0398:
0399: // Now here we need the artifact coreArtifactFilter stuff
0400:
0401: componentRealm = container.createComponentRealm(
0402: projectPlugin.getKey(), jars);
0403:
0404: // adding for MNG-3012 to try to work around problems with Xpp3Dom (from plexus-utils)
0405: // spawning a ClassCastException when a mojo calls plugin.getConfiguration() from maven-model...
0406: componentRealm.importFrom(componentRealm.getParentRealm()
0407: .getId(), Xpp3Dom.class.getName());
0408: componentRealm.importFrom(componentRealm.getParentRealm()
0409: .getId(), "org.codehaus.plexus.util.xml.pull");
0410:
0411: // Adding for MNG-2878, since maven-reporting-impl was removed from the
0412: // internal list of artifacts managed by maven, the classloader is different
0413: // between maven-reporting-impl and maven-reporting-api...so this resource
0414: // is not available from the AbstractMavenReport since it uses:
0415: // getClass().getResourceAsStream( "/default-report.xml" )
0416: // (maven-reporting-impl version 2.0; line 134; affects: checkstyle plugin, and probably others)
0417: componentRealm.importFrom(componentRealm.getParentRealm()
0418: .getId(), "/default-report.xml");
0419: } catch (PlexusContainerException e) {
0420: throw new PluginManagerException(
0421: "Failed to create realm for plugin '"
0422: + projectPlugin + ".", e);
0423: } catch (NoSuchRealmException e) {
0424: throw new PluginManagerException(
0425: "Failed to import Xpp3Dom from parent realm for plugin: '"
0426: + projectPlugin + ".", e);
0427: }
0428:
0429: // ----------------------------------------------------------------------------
0430: // The PluginCollector will now know about the plugin we are trying to load
0431: // ----------------------------------------------------------------------------
0432:
0433: getLogger().debug(
0434: "Checking for plugin descriptor for: "
0435: + plugin.getKey() + " in collector: "
0436: + pluginCollector);
0437:
0438: PluginDescriptor pluginDescriptor = pluginCollector
0439: .getPluginDescriptor(projectPlugin);
0440:
0441: if (pluginDescriptor == null) {
0442: throw new IllegalStateException(
0443: "The PluginDescriptor for the plugin "
0444: + projectPlugin.getKey() + " was not found");
0445: }
0446:
0447: pluginDescriptor.setPluginArtifact(pluginArtifact);
0448:
0449: // we're only setting the plugin's artifact itself as the artifact list, to allow it to be retrieved
0450: // later when the plugin is first invoked. Retrieving this artifact will in turn allow us to
0451: // transitively resolve its dependencies, and add them to the plugin container...
0452: //pluginDescriptor.setArtifacts( Collections.singletonList( pluginArtifact ) );
0453:
0454: //pluginDescriptor.setIntroducedDependencyArtifacts( artifacts );
0455:
0456: pluginDescriptor.setArtifacts(new ArrayList(artifacts));
0457:
0458: getLogger().debug(
0459: "Realm for plugin: " + plugin.getKey() + ":\n"
0460: + componentRealm);
0461:
0462: pluginDescriptor.setClassRealm(componentRealm);
0463: }
0464:
0465: private Set getPluginArtifacts(Artifact pluginArtifact,
0466: Plugin plugin, MavenProject project,
0467: ArtifactRepository localRepository)
0468: throws InvalidPluginException, ArtifactNotFoundException,
0469: ArtifactResolutionException {
0470:
0471: Set projectPluginDependencies;
0472:
0473: try {
0474: projectPluginDependencies = MavenMetadataSource
0475: .createArtifacts(artifactFactory, plugin
0476: .getDependencies(), null,
0477: coreArtifactFilterManager
0478: .getCoreArtifactFilter(), project);
0479: } catch (InvalidDependencyVersionException e) {
0480: throw new InvalidPluginException("Plugin '" + plugin
0481: + "' is invalid: " + e.getMessage(), e);
0482: }
0483:
0484: ResolutionGroup resolutionGroup;
0485:
0486: try {
0487: resolutionGroup = artifactMetadataSource.retrieve(
0488: pluginArtifact, localRepository, project
0489: .getPluginArtifactRepositories());
0490: } catch (ArtifactMetadataRetrievalException e) {
0491: throw new ArtifactResolutionException(
0492: "Unable to download metadata from repository for plugin '"
0493: + pluginArtifact.getId() + "': "
0494: + e.getMessage(), pluginArtifact, e);
0495: }
0496:
0497: checkPlexusUtils(resolutionGroup, artifactFactory);
0498:
0499: Set dependencies = new LinkedHashSet();
0500:
0501: // resolve the plugin dependencies specified in <plugin><dependencies> first:
0502: dependencies.addAll(projectPluginDependencies);
0503:
0504: // followed by the plugin's default artifact set
0505: dependencies.addAll(resolutionGroup.getArtifacts());
0506:
0507: List repositories = new ArrayList();
0508:
0509: repositories
0510: .addAll(resolutionGroup.getResolutionRepositories());
0511:
0512: repositories.addAll(project.getRemoteArtifactRepositories());
0513:
0514: ArtifactResolutionResult result = artifactResolver
0515: .resolveTransitively(dependencies, pluginArtifact,
0516: Collections.EMPTY_MAP, localRepository,
0517: repositories, artifactMetadataSource,
0518: coreArtifactFilterManager.getArtifactFilter());
0519:
0520: Set resolved = new HashSet(result.getArtifacts());
0521:
0522: for (Iterator it = resolved.iterator(); it.hasNext();) {
0523: Artifact artifact = (Artifact) it.next();
0524:
0525: if (!artifact.equals(pluginArtifact)) {
0526: artifact = project.replaceWithActiveArtifact(artifact);
0527: }
0528: }
0529:
0530: getLogger().debug(
0531: "Using the following artifacts for classpath of: "
0532: + pluginArtifact.getId() + ":\n\n"
0533: + resolved.toString().replace(',', '\n'));
0534:
0535: return resolved;
0536: }
0537:
0538: // ----------------------------------------------------------------------
0539: // Mojo execution
0540: // ----------------------------------------------------------------------
0541:
0542: public void executeMojo(MavenProject project,
0543: MojoExecution mojoExecution, MavenSession session)
0544: throws ArtifactResolutionException, MojoExecutionException,
0545: MojoFailureException, ArtifactNotFoundException,
0546: InvalidDependencyVersionException, PluginManagerException,
0547: PluginConfigurationException {
0548: MojoDescriptor mojoDescriptor = mojoExecution
0549: .getMojoDescriptor();
0550:
0551: // NOTE: I'm putting these checks in here, since this is the central point of access for
0552: // anything that wants to execute a mojo.
0553: if (mojoDescriptor.isProjectRequired()
0554: && !session.isUsingPOMsFromFilesystem()) {
0555: throw new MojoExecutionException(
0556: "Cannot execute mojo: "
0557: + mojoDescriptor.getGoal()
0558: + ". It requires a project with an existing pom.xml, but the build is not using one.");
0559: }
0560:
0561: if (mojoDescriptor.isOnlineRequired()
0562: && session.getSettings().isOffline()) {
0563: // TODO: Should we error out, or simply warn and skip??
0564: throw new MojoExecutionException(
0565: "Mojo: "
0566: + mojoDescriptor.getGoal()
0567: + " requires online mode for execution. Maven is currently offline.");
0568: }
0569:
0570: if (mojoDescriptor.isDependencyResolutionRequired() != null) {
0571: Collection projects;
0572:
0573: if (mojoDescriptor.isAggregator()) {
0574: projects = session.getSortedProjects();
0575: } else {
0576: projects = Collections.singleton(project);
0577: }
0578:
0579: for (Iterator i = projects.iterator(); i.hasNext();) {
0580: MavenProject p = (MavenProject) i.next();
0581:
0582: resolveTransitiveDependencies(session,
0583: artifactResolver, mojoDescriptor
0584: .isDependencyResolutionRequired(),
0585: artifactFactory, p);
0586: }
0587:
0588: downloadDependencies(project, session, artifactResolver);
0589: }
0590:
0591: String goalName = mojoDescriptor.getFullGoalName();
0592:
0593: Mojo plugin;
0594:
0595: PluginDescriptor pluginDescriptor = mojoDescriptor
0596: .getPluginDescriptor();
0597:
0598: Xpp3Dom dom = mojoExecution.getConfiguration();
0599: if (dom != null) {
0600: // make a defensive copy, to keep things from getting polluted.
0601: dom = new Xpp3Dom(dom);
0602: }
0603:
0604: plugin = getConfiguredMojo(session, dom, project, false,
0605: mojoExecution);
0606:
0607: // Event monitoring.
0608: String event = MavenEvents.MOJO_EXECUTION;
0609:
0610: EventDispatcher dispatcher = session.getEventDispatcher();
0611:
0612: String goalExecId = goalName;
0613:
0614: if (mojoExecution.getExecutionId() != null) {
0615: goalExecId += " {execution: "
0616: + mojoExecution.getExecutionId() + "}";
0617: }
0618:
0619: dispatcher.dispatchStart(event, goalExecId);
0620:
0621: ClassLoader oldClassLoader = Thread.currentThread()
0622: .getContextClassLoader();
0623:
0624: ClassRealm pluginRealm = pluginDescriptor.getClassRealm();
0625:
0626: try {
0627: Thread.currentThread().setContextClassLoader(pluginRealm);
0628:
0629: ClassRealm oldRealm = container.setLookupRealm(pluginRealm);
0630:
0631: plugin.execute();
0632:
0633: // NEW: If the mojo that just executed is a report, store it in the LifecycleExecutionContext
0634: // for reference by future mojos.
0635: if (plugin instanceof MavenReport) {
0636: LifecycleExecutionContext ctx = LifecycleExecutionContext
0637: .read(buildContextManager);
0638: if (ctx == null) {
0639: ctx = new LifecycleExecutionContext(project);
0640: }
0641:
0642: ctx.addReport(mojoDescriptor, (MavenReport) plugin);
0643: ctx.store(buildContextManager);
0644: }
0645:
0646: container.setLookupRealm(oldRealm);
0647:
0648: dispatcher.dispatchEnd(event, goalExecId);
0649: } catch (MojoExecutionException e) {
0650: session.getEventDispatcher().dispatchError(event,
0651: goalExecId, e);
0652:
0653: throw e;
0654: } catch (MojoFailureException e) {
0655: session.getEventDispatcher().dispatchError(event,
0656: goalExecId, e);
0657:
0658: throw e;
0659: } finally {
0660:
0661: Thread.currentThread()
0662: .setContextClassLoader(oldClassLoader);
0663: }
0664: }
0665:
0666: public MavenReport getReport(MavenProject project,
0667: MojoExecution mojoExecution, MavenSession session)
0668: throws ArtifactNotFoundException,
0669: PluginConfigurationException, PluginManagerException,
0670: ArtifactResolutionException {
0671: MojoDescriptor mojoDescriptor = mojoExecution
0672: .getMojoDescriptor();
0673: PluginDescriptor descriptor = mojoDescriptor
0674: .getPluginDescriptor();
0675: Xpp3Dom dom = project.getReportConfiguration(descriptor
0676: .getGroupId(), descriptor.getArtifactId(),
0677: mojoExecution.getExecutionId());
0678: if (mojoExecution.getConfiguration() != null) {
0679: dom = Xpp3Dom.mergeXpp3Dom(dom, mojoExecution
0680: .getConfiguration());
0681: }
0682:
0683: return (MavenReport) getConfiguredMojo(session, dom, project,
0684: true, mojoExecution);
0685: }
0686:
0687: public PluginDescriptor verifyReportPlugin(
0688: ReportPlugin reportPlugin, MavenProject project,
0689: MavenSession session)
0690: throws PluginVersionResolutionException,
0691: ArtifactResolutionException, ArtifactNotFoundException,
0692: InvalidVersionSpecificationException,
0693: InvalidPluginException, PluginManagerException,
0694: PluginNotFoundException, PluginVersionNotFoundException {
0695: String version = reportPlugin.getVersion();
0696:
0697: if (version == null) {
0698: version = pluginVersionManager.resolveReportPluginVersion(
0699: reportPlugin.getGroupId(), reportPlugin
0700: .getArtifactId(), project, session);
0701:
0702: reportPlugin.setVersion(version);
0703: }
0704:
0705: Plugin forLookup = new Plugin();
0706:
0707: forLookup.setGroupId(reportPlugin.getGroupId());
0708: forLookup.setArtifactId(reportPlugin.getArtifactId());
0709: forLookup.setVersion(version);
0710:
0711: return verifyVersionedPlugin(forLookup, project, session);
0712: }
0713:
0714: private Mojo getConfiguredMojo(MavenSession session, Xpp3Dom dom,
0715: MavenProject project, boolean report,
0716: MojoExecution mojoExecution)
0717: throws PluginConfigurationException,
0718: ArtifactNotFoundException, PluginManagerException,
0719: ArtifactResolutionException {
0720: MojoDescriptor mojoDescriptor = mojoExecution
0721: .getMojoDescriptor();
0722:
0723: PluginDescriptor pluginDescriptor = mojoDescriptor
0724: .getPluginDescriptor();
0725:
0726: // if this is the first time this plugin has been used, the plugin's container will only
0727: // contain the plugin's artifact in isolation; we need to finish resolving the plugin's
0728: // dependencies, and add them to the container.
0729: //getPluginArtifacts( pluginDescriptor, container, project, session );
0730:
0731: Mojo plugin;
0732:
0733: try {
0734: ClassRealm realm = mojoDescriptor.getPluginDescriptor()
0735: .getClassRealm();
0736:
0737: // We are forcing the use of the plugin realm for all lookups that might occur during
0738: // the lifecycle that is part of the lookup. Here we are specifically trying to keep
0739: // lookups that occur in contextualize calls in line with the right realm.
0740:
0741: if (realm != null) {
0742: ClassRealm oldRealm = container.setLookupRealm(realm);
0743:
0744: getLogger().debug(
0745: "Looking up mojo "
0746: + mojoDescriptor.getRoleHint()
0747: + " in realm " + realm.getId()
0748: + " - descRealmId="
0749: + mojoDescriptor.getRealmId());
0750:
0751: plugin = (Mojo) container.lookup(Mojo.ROLE,
0752: mojoDescriptor.getRoleHint(), realm);
0753:
0754: if (plugin != null) {
0755: getLogger().debug(
0756: "Looked up - "
0757: + plugin
0758: + " - "
0759: + plugin.getClass()
0760: .getClassLoader());
0761: } else {
0762: getLogger().warn("No luck.");
0763: }
0764:
0765: container.setLookupRealm(oldRealm);
0766: } else {
0767: getLogger().info(
0768: "Looking up mojo "
0769: + mojoDescriptor.getRoleHint()
0770: + " in default realm "
0771: + container.getLookupRealm()
0772: + " - descRealmId="
0773: + mojoDescriptor.getRealmId());
0774:
0775: plugin = (Mojo) container.lookup(Mojo.ROLE,
0776: mojoDescriptor.getRoleHint());
0777:
0778: if (plugin != null) {
0779: getLogger().info(
0780: "Looked up - "
0781: + plugin
0782: + " - "
0783: + plugin.getClass()
0784: .getClassLoader());
0785: } else {
0786: getLogger().warn("No luck.");
0787: }
0788:
0789: }
0790:
0791: if (report && !(plugin instanceof MavenReport)) {
0792: // TODO: the mojoDescriptor should actually capture this information so we don't get this far
0793: return null;
0794: }
0795: } catch (ComponentLookupException e) {
0796: throw new PluginManagerException(
0797: "Unable to find the mojo '"
0798: + mojoDescriptor.getRoleHint()
0799: + "' in the plugin '"
0800: + pluginDescriptor.getPluginLookupKey()
0801: + "'", e);
0802: }
0803:
0804: if (plugin instanceof ContextEnabled) {
0805: Map pluginContext = session.getPluginContext(
0806: pluginDescriptor, project);
0807:
0808: pluginContext.put("project", project);
0809:
0810: pluginContext.put("pluginDescriptor", pluginDescriptor);
0811:
0812: ((ContextEnabled) plugin).setPluginContext(pluginContext);
0813: }
0814:
0815: plugin.setLog(mojoLogger);
0816:
0817: XmlPlexusConfiguration pomConfiguration;
0818:
0819: if (dom == null) {
0820: pomConfiguration = new XmlPlexusConfiguration(
0821: "configuration");
0822: } else {
0823: pomConfiguration = new XmlPlexusConfiguration(dom);
0824: }
0825:
0826: // Validate against non-editable (@readonly) parameters, to make sure users aren't trying to
0827: // override in the POM.
0828: validatePomConfiguration(mojoDescriptor, pomConfiguration);
0829:
0830: PlexusConfiguration mergedConfiguration = mergeMojoConfiguration(
0831: pomConfiguration, mojoDescriptor);
0832:
0833: // TODO: plexus changes to make this more like the component descriptor so this can be used instead
0834: // PlexusConfiguration mergedConfiguration = mergeConfiguration( pomConfiguration,
0835: // mojoDescriptor.getConfiguration() );
0836:
0837: // NEW: Pass in the LifecycleExecutionContext so we have access to the current project,
0838: // forked project stack (future), and reports.
0839: LifecycleExecutionContext ctx = LifecycleExecutionContext
0840: .read(buildContextManager);
0841: if (ctx == null) {
0842: ctx = new LifecycleExecutionContext(project);
0843: }
0844:
0845: ExpressionEvaluator expressionEvaluator = new PluginParameterExpressionEvaluator(
0846: session, mojoExecution, pathTranslator, ctx,
0847: getLogger(), session.getExecutionProperties());
0848:
0849: PlexusConfiguration extractedMojoConfiguration = extractMojoConfiguration(
0850: mergedConfiguration, mojoDescriptor);
0851:
0852: checkRequiredParameters(mojoDescriptor,
0853: extractedMojoConfiguration, expressionEvaluator);
0854:
0855: populatePluginFields(plugin, mojoDescriptor,
0856: extractedMojoConfiguration, container,
0857: expressionEvaluator);
0858:
0859: return plugin;
0860: }
0861:
0862: private PlexusConfiguration extractMojoConfiguration(
0863: PlexusConfiguration mergedConfiguration,
0864: MojoDescriptor mojoDescriptor) {
0865: Map parameterMap = mojoDescriptor.getParameterMap();
0866:
0867: PlexusConfiguration[] mergedChildren = mergedConfiguration
0868: .getChildren();
0869:
0870: XmlPlexusConfiguration extractedConfiguration = new XmlPlexusConfiguration(
0871: "configuration");
0872:
0873: for (int i = 0; i < mergedChildren.length; i++) {
0874: PlexusConfiguration child = mergedChildren[i];
0875:
0876: if (parameterMap.containsKey(child.getName())) {
0877: extractedConfiguration
0878: .addChild(copyConfiguration(child));
0879: } else {
0880: // TODO: I defy anyone to find these messages in the '-X' output! Do we need a new log level?
0881: // ideally, this would be elevated above the true debug output, but below the default INFO level...
0882: // [BP] (2004-07-18): need to understand the context more but would prefer this could be either WARN or
0883: // removed - shouldn't need DEBUG to diagnose a problem most of the time.
0884: getLogger().debug(
0885: "*** WARNING: Configuration \'"
0886: + child.getName()
0887: + "\' is not used in goal \'"
0888: + mojoDescriptor.getFullGoalName()
0889: + "; this may indicate a typo... ***");
0890: }
0891: }
0892:
0893: return extractedConfiguration;
0894: }
0895:
0896: private void checkRequiredParameters(MojoDescriptor goal,
0897: PlexusConfiguration configuration,
0898: ExpressionEvaluator expressionEvaluator)
0899: throws PluginConfigurationException {
0900: // TODO: this should be built in to the configurator, as we presently double process the expressions
0901:
0902: List parameters = goal.getParameters();
0903:
0904: if (parameters == null) {
0905: return;
0906: }
0907:
0908: List invalidParameters = new ArrayList();
0909:
0910: for (int i = 0; i < parameters.size(); i++) {
0911: Parameter parameter = (Parameter) parameters.get(i);
0912:
0913: if (parameter.isRequired()) {
0914: // the key for the configuration map we're building.
0915: String key = parameter.getName();
0916:
0917: Object fieldValue = null;
0918: String expression = null;
0919: PlexusConfiguration value = configuration.getChild(key,
0920: false);
0921: try {
0922: if (value != null) {
0923: expression = value.getValue(null);
0924:
0925: fieldValue = expressionEvaluator
0926: .evaluate(expression);
0927:
0928: if (fieldValue == null) {
0929: fieldValue = value.getAttribute(
0930: "default-value", null);
0931: }
0932: }
0933:
0934: if ((fieldValue == null)
0935: && StringUtils.isNotEmpty(parameter
0936: .getAlias())) {
0937: value = configuration.getChild(parameter
0938: .getAlias(), false);
0939: if (value != null) {
0940: expression = value.getValue(null);
0941: fieldValue = expressionEvaluator
0942: .evaluate(expression);
0943: if (fieldValue == null) {
0944: fieldValue = value.getAttribute(
0945: "default-value", null);
0946: }
0947: }
0948: }
0949: } catch (ExpressionEvaluationException e) {
0950: throw new PluginConfigurationException(goal
0951: .getPluginDescriptor(), e.getMessage(), e);
0952: }
0953:
0954: // only mark as invalid if there are no child nodes
0955: if ((fieldValue == null)
0956: && ((value == null) || (value.getChildCount() == 0))) {
0957: parameter.setExpression(expression);
0958: invalidParameters.add(parameter);
0959: }
0960: }
0961: }
0962:
0963: if (!invalidParameters.isEmpty()) {
0964: throw new PluginParameterException(goal, invalidParameters);
0965: }
0966: }
0967:
0968: private void validatePomConfiguration(MojoDescriptor goal,
0969: PlexusConfiguration pomConfiguration)
0970: throws PluginConfigurationException {
0971: List parameters = goal.getParameters();
0972:
0973: if (parameters == null) {
0974: return;
0975: }
0976:
0977: for (int i = 0; i < parameters.size(); i++) {
0978: Parameter parameter = (Parameter) parameters.get(i);
0979:
0980: // the key for the configuration map we're building.
0981: String key = parameter.getName();
0982:
0983: PlexusConfiguration value = pomConfiguration.getChild(key,
0984: false);
0985:
0986: if ((value == null)
0987: && StringUtils.isNotEmpty(parameter.getAlias())) {
0988: key = parameter.getAlias();
0989: value = pomConfiguration.getChild(key, false);
0990: }
0991:
0992: if (value != null) {
0993: // Make sure the parameter is either editable/configurable, or else is NOT specified in the POM
0994: if (!parameter.isEditable()) {
0995: StringBuffer errorMessage = new StringBuffer()
0996: .append("ERROR: Cannot override read-only parameter: ");
0997: errorMessage.append(key);
0998: errorMessage.append(" in goal: ").append(
0999: goal.getFullGoalName());
1000:
1001: throw new PluginConfigurationException(goal
1002: .getPluginDescriptor(), errorMessage
1003: .toString());
1004: }
1005:
1006: String deprecated = parameter.getDeprecated();
1007: if (StringUtils.isNotEmpty(deprecated)) {
1008: getLogger().warn(
1009: "DEPRECATED [" + parameter.getName()
1010: + "]: " + deprecated);
1011: }
1012: }
1013: }
1014: }
1015:
1016: private PlexusConfiguration mergeMojoConfiguration(
1017: XmlPlexusConfiguration fromPom,
1018: MojoDescriptor mojoDescriptor) {
1019: XmlPlexusConfiguration result = new XmlPlexusConfiguration(
1020: fromPom.getName());
1021: result.setValue(fromPom.getValue(null));
1022:
1023: if (mojoDescriptor.getParameters() != null) {
1024: PlexusConfiguration fromMojo = mojoDescriptor
1025: .getMojoConfiguration();
1026:
1027: for (Iterator it = mojoDescriptor.getParameters()
1028: .iterator(); it.hasNext();) {
1029: Parameter parameter = (Parameter) it.next();
1030:
1031: String paramName = parameter.getName();
1032: String alias = parameter.getAlias();
1033: String implementation = parameter.getImplementation();
1034:
1035: PlexusConfiguration pomConfig = fromPom
1036: .getChild(paramName);
1037: PlexusConfiguration aliased = null;
1038:
1039: if (alias != null) {
1040: aliased = fromPom.getChild(alias);
1041: }
1042:
1043: PlexusConfiguration mojoConfig = fromMojo.getChild(
1044: paramName, false);
1045:
1046: // first we'll merge configurations from the aliased and real params.
1047: // TODO: Is this the right thing to do?
1048: if (aliased != null) {
1049: if (pomConfig == null) {
1050: pomConfig = new XmlPlexusConfiguration(
1051: paramName);
1052: }
1053:
1054: pomConfig = buildTopDownMergedConfiguration(
1055: pomConfig, aliased);
1056: }
1057:
1058: PlexusConfiguration toAdd = null;
1059:
1060: if (pomConfig != null) {
1061: pomConfig = buildTopDownMergedConfiguration(
1062: pomConfig, mojoConfig);
1063:
1064: if (StringUtils
1065: .isNotEmpty(pomConfig.getValue(null))
1066: || (pomConfig.getChildCount() > 0)) {
1067: toAdd = pomConfig;
1068: }
1069: }
1070:
1071: if ((toAdd == null) && (mojoConfig != null)) {
1072: toAdd = copyConfiguration(mojoConfig);
1073: }
1074:
1075: if (toAdd != null) {
1076: if ((implementation != null)
1077: && (toAdd.getAttribute("implementation",
1078: null) == null)) {
1079:
1080: XmlPlexusConfiguration implementationConf = new XmlPlexusConfiguration(
1081: paramName);
1082:
1083: implementationConf.setAttribute(
1084: "implementation", parameter
1085: .getImplementation());
1086:
1087: toAdd = buildTopDownMergedConfiguration(toAdd,
1088: implementationConf);
1089: }
1090:
1091: result.addChild(toAdd);
1092: }
1093: }
1094: }
1095: return result;
1096: }
1097:
1098: private XmlPlexusConfiguration buildTopDownMergedConfiguration(
1099: PlexusConfiguration dominant, PlexusConfiguration recessive) {
1100: XmlPlexusConfiguration result = new XmlPlexusConfiguration(
1101: dominant.getName());
1102:
1103: String value = dominant.getValue(null);
1104:
1105: if (StringUtils.isEmpty(value) && (recessive != null)) {
1106: value = recessive.getValue(null);
1107: }
1108:
1109: if (StringUtils.isNotEmpty(value)) {
1110: result.setValue(value);
1111: }
1112:
1113: String[] attributeNames = dominant.getAttributeNames();
1114:
1115: for (int i = 0; i < attributeNames.length; i++) {
1116: String attributeValue = dominant.getAttribute(
1117: attributeNames[i], null);
1118:
1119: result.setAttribute(attributeNames[i], attributeValue);
1120: }
1121:
1122: if (recessive != null) {
1123: attributeNames = recessive.getAttributeNames();
1124:
1125: for (int i = 0; i < attributeNames.length; i++) {
1126: String attributeValue = recessive.getAttribute(
1127: attributeNames[i], null);
1128: // TODO: recessive seems to be dominant here?
1129: result.setAttribute(attributeNames[i], attributeValue);
1130: }
1131: }
1132:
1133: PlexusConfiguration[] children = dominant.getChildren();
1134:
1135: for (int i = 0; i < children.length; i++) {
1136: PlexusConfiguration childDom = children[i];
1137: PlexusConfiguration childRec = recessive == null ? null
1138: : recessive.getChild(childDom.getName(), false);
1139:
1140: if (childRec != null) {
1141: result.addChild(buildTopDownMergedConfiguration(
1142: childDom, childRec));
1143: } else { // FIXME: copy, or use reference?
1144: result.addChild(copyConfiguration(childDom));
1145: }
1146: }
1147:
1148: return result;
1149: }
1150:
1151: public static PlexusConfiguration copyConfiguration(
1152: PlexusConfiguration src) {
1153: // TODO: shouldn't be necessary
1154: XmlPlexusConfiguration dom = new XmlPlexusConfiguration(src
1155: .getName());
1156: dom.setValue(src.getValue(null));
1157:
1158: String[] attributeNames = src.getAttributeNames();
1159: for (int i = 0; i < attributeNames.length; i++) {
1160: String attributeName = attributeNames[i];
1161: dom.setAttribute(attributeName, src.getAttribute(
1162: attributeName, null));
1163: }
1164:
1165: PlexusConfiguration[] children = src.getChildren();
1166: for (int i = 0; i < children.length; i++) {
1167: dom.addChild(copyConfiguration(children[i]));
1168: }
1169:
1170: return dom;
1171: }
1172:
1173: // ----------------------------------------------------------------------
1174: // Mojo Parameter Handling
1175: // ----------------------------------------------------------------------
1176:
1177: private void populatePluginFields(Mojo plugin,
1178: MojoDescriptor mojoDescriptor,
1179: PlexusConfiguration configuration,
1180: PlexusContainer pluginContainer,
1181: ExpressionEvaluator expressionEvaluator)
1182: throws PluginConfigurationException {
1183: ComponentConfigurator configurator = null;
1184:
1185: ClassRealm pluginRealm = mojoDescriptor.getPluginDescriptor()
1186: .getClassRealm();
1187:
1188: try {
1189: String configuratorId = mojoDescriptor
1190: .getComponentConfigurator();
1191:
1192: // TODO: could the configuration be passed to lookup and the configurator known to plexus via the descriptor
1193: // so that this meethod could entirely be handled by a plexus lookup?
1194: if (StringUtils.isNotEmpty(configuratorId)) {
1195: configurator = (ComponentConfigurator) pluginContainer
1196: .lookup(ComponentConfigurator.ROLE,
1197: configuratorId, pluginRealm);
1198: } else {
1199: configurator = (ComponentConfigurator) pluginContainer
1200: .lookup(ComponentConfigurator.ROLE, "basic",
1201: pluginRealm);
1202: }
1203:
1204: ConfigurationListener listener = new DebugConfigurationListener(
1205: getLogger());
1206:
1207: getLogger().debug(
1208: "Configuring mojo '" + mojoDescriptor.getId()
1209: + "' -->");
1210:
1211: // This needs to be able to use methods
1212: configurator.configureComponent(plugin, configuration,
1213: expressionEvaluator, pluginRealm, listener);
1214:
1215: getLogger().debug("-- end configuration --");
1216: } catch (ComponentConfigurationException e) {
1217: throw new PluginConfigurationException(
1218: mojoDescriptor.getPluginDescriptor(),
1219: "Unable to parse the created DOM for plugin configuration",
1220: e);
1221: } catch (ComponentLookupException e) {
1222: throw new PluginConfigurationException(
1223: mojoDescriptor.getPluginDescriptor(),
1224: "Unable to retrieve component configurator for plugin configuration",
1225: e);
1226: } finally {
1227: if (configurator != null) {
1228: try {
1229: pluginContainer.release(configurator);
1230: } catch (ComponentLifecycleException e) {
1231: getLogger()
1232: .debug(
1233: "Failed to release plugin container - ignoring.");
1234: }
1235: }
1236: }
1237: }
1238:
1239: public static String createPluginParameterRequiredMessage(
1240: MojoDescriptor mojo, Parameter parameter, String expression) {
1241: StringBuffer message = new StringBuffer();
1242:
1243: message.append("The '");
1244: message.append(parameter.getName());
1245: message
1246: .append("' parameter is required for the execution of the ");
1247: message.append(mojo.getFullGoalName());
1248: message.append(" mojo and cannot be null.");
1249: if (expression != null) {
1250: message.append(" The retrieval expression was: ").append(
1251: expression);
1252: }
1253:
1254: return message.toString();
1255: }
1256:
1257: // ----------------------------------------------------------------------
1258: // LegacyLifecycle
1259: // ----------------------------------------------------------------------
1260:
1261: public void contextualize(Context context) throws ContextException {
1262: container = (PlexusContainer) context
1263: .get(PlexusConstants.PLEXUS_KEY);
1264:
1265: mojoLogger = new DefaultLog(container.getLoggerManager()
1266: .getLoggerForComponent(Mojo.ROLE));
1267: }
1268:
1269: // ----------------------------------------------------------------------
1270: // Artifact resolution
1271: // ----------------------------------------------------------------------
1272:
1273: private void resolveTransitiveDependencies(MavenSession context,
1274: ArtifactResolver artifactResolver, String scope,
1275: ArtifactFactory artifactFactory, MavenProject project)
1276: throws ArtifactResolutionException,
1277: ArtifactNotFoundException,
1278: InvalidDependencyVersionException {
1279: ArtifactFilter filter = new ScopeArtifactFilter(scope);
1280:
1281: // TODO: such a call in MavenMetadataSource too - packaging not really the intention of type
1282: Artifact artifact = artifactFactory.createBuildArtifact(project
1283: .getGroupId(), project.getArtifactId(), project
1284: .getVersion(), project.getPackaging());
1285:
1286: // TODO: we don't need to resolve over and over again, as long as we are sure that the parameters are the same
1287: // check this with yourkit as a hot spot.
1288: // Don't recreate if already created - for effeciency, and because clover plugin adds to it
1289: if (project.getDependencyArtifacts() == null) {
1290: project.setDependencyArtifacts(project.createArtifacts(
1291: artifactFactory, null, null));
1292: }
1293: ArtifactResolutionResult result = artifactResolver
1294: .resolveTransitively(project.getDependencyArtifacts(),
1295: artifact, Collections.EMPTY_MAP, context
1296: .getLocalRepository(), project
1297: .getRemoteArtifactRepositories(),
1298: artifactMetadataSource, filter);
1299:
1300: project.setArtifacts(result.getArtifacts());
1301: }
1302:
1303: // ----------------------------------------------------------------------
1304: // Artifact downloading
1305: // ----------------------------------------------------------------------
1306:
1307: private void downloadDependencies(MavenProject project,
1308: MavenSession context, ArtifactResolver artifactResolver)
1309: throws ArtifactResolutionException,
1310: ArtifactNotFoundException {
1311: ArtifactRepository localRepository = context
1312: .getLocalRepository();
1313: List remoteArtifactRepositories = project
1314: .getRemoteArtifactRepositories();
1315:
1316: for (Iterator it = project.getArtifacts().iterator(); it
1317: .hasNext();) {
1318: Artifact artifact = (Artifact) it.next();
1319:
1320: artifactResolver.resolve(artifact,
1321: remoteArtifactRepositories, localRepository);
1322: }
1323: }
1324:
1325: public Object getPluginComponent(Plugin plugin, String role,
1326: String roleHint) throws PluginManagerException,
1327: ComponentLookupException {
1328: ClassRealm pluginRealm = pluginCollector.getPluginDescriptor(
1329: plugin).getClassRealm();
1330:
1331: if (pluginRealm == null) {
1332: getLogger().warn(
1333: "getPluginComponent(" + plugin + ", " + role
1334: + "): descriptor is missing classRealm");
1335: pluginRealm = container.getLookupRealm();
1336: }
1337:
1338: return container.lookup(role, roleHint, pluginRealm);
1339: }
1340:
1341: public Map getPluginComponents(Plugin plugin, String role)
1342: throws ComponentLookupException, PluginManagerException {
1343: getLogger().debug(
1344: "Looking for plugin realm: " + plugin + " using: "
1345: + pluginCollector);
1346:
1347: ClassRealm pluginRealm = pluginCollector.getPluginDescriptor(
1348: plugin).getClassRealm();
1349:
1350: if (pluginRealm == null) {
1351: getLogger().warn(
1352: "getPluginComponent(" + plugin + ", " + role
1353: + "): descriptor is missing classRealm");
1354: pluginRealm = container.getLookupRealm();
1355: }
1356:
1357: return container.lookupMap(role, pluginRealm);
1358: }
1359:
1360: public static void checkPlexusUtils(
1361: ResolutionGroup resolutionGroup,
1362: ArtifactFactory artifactFactory) {
1363: // ----------------------------------------------------------------------------
1364: // If the plugin already declares a dependency on plexus-utils then we're all
1365: // set as the plugin author is aware of its use. If we don't have a dependency
1366: // on plexus-utils then we must protect users from stupid plugin authors who
1367: // did not declare a direct dependency on plexus-utils because the version
1368: // Maven uses is hidden from downstream use. We will also bump up any
1369: // anything below 1.1 to 1.1 as this mimics the behaviour in 2.0.5 where
1370: // plexus-utils 1.1 was being forced into use.
1371: // ----------------------------------------------------------------------------
1372:
1373: VersionRange vr = null;
1374:
1375: try {
1376: vr = VersionRange.createFromVersionSpec("[1.1,)");
1377: } catch (InvalidVersionSpecificationException e) {
1378: // Won't happen
1379: }
1380:
1381: boolean plexusUtilsPresent = false;
1382:
1383: for (Iterator i = resolutionGroup.getArtifacts().iterator(); i
1384: .hasNext();) {
1385: Artifact a = (Artifact) i.next();
1386:
1387: if (a.getArtifactId().equals("plexus-utils")
1388: && vr.containsVersion(new DefaultArtifactVersion(a
1389: .getVersion()))) {
1390: plexusUtilsPresent = true;
1391:
1392: break;
1393: }
1394: }
1395:
1396: if (!plexusUtilsPresent) {
1397: // We will add plexus-utils as every plugin was getting this anyway from Maven itself. We will set the
1398: // version to the latest version we know that works as of the 2.0.6 release. We set the scope to runtime
1399: // as this is what's implicitly happening in 2.0.6.
1400:
1401: resolutionGroup.getArtifacts().add(
1402: artifactFactory.createArtifact(
1403: "org.codehaus.plexus", "plexus-utils",
1404: "1.1", Artifact.SCOPE_RUNTIME, "jar"));
1405: }
1406: }
1407: }
|