diff --git a/maven-artifact/src/main/java/org/apache/maven/artifact/Artifact.java b/maven-artifact/src/main/java/org/apache/maven/artifact/Artifact.java index c4fb0717c8..d413108b4c 100644 --- a/maven-artifact/src/main/java/org/apache/maven/artifact/Artifact.java +++ b/maven-artifact/src/main/java/org/apache/maven/artifact/Artifact.java @@ -90,4 +90,8 @@ public interface Artifact void updateVersion( String version, ArtifactRepository localRepository ) throws ArtifactMetadataRetrievalException; + + String getDownloadUrl(); + + void setDownloadUrl( String downloadUrl ); } \ No newline at end of file diff --git a/maven-artifact/src/main/java/org/apache/maven/artifact/DefaultArtifact.java b/maven-artifact/src/main/java/org/apache/maven/artifact/DefaultArtifact.java index 92c7af3aff..0579209663 100644 --- a/maven-artifact/src/main/java/org/apache/maven/artifact/DefaultArtifact.java +++ b/maven-artifact/src/main/java/org/apache/maven/artifact/DefaultArtifact.java @@ -56,6 +56,8 @@ public class DefaultArtifact private ArtifactRepository repository; + private String downloadUrl; + /** * !!! WARNING !!! Never put in the POM. It is for mojo use * only. Classifier is for specifying derived artifacts, like ejb-client. @@ -310,4 +312,14 @@ public class DefaultArtifact throw new ArtifactMetadataRetrievalException( "Error reading local metadata", e ); } } + + public String getDownloadUrl() + { + return downloadUrl; + } + + public void setDownloadUrl( String downloadUrl ) + { + this.downloadUrl = downloadUrl; + } } diff --git a/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/ArtifactResolutionException.java b/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/ArtifactResolutionException.java index da9ed0dcb9..90356d0a81 100644 --- a/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/ArtifactResolutionException.java +++ b/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/ArtifactResolutionException.java @@ -37,36 +37,37 @@ public class ArtifactResolutionException private String type; + private String downloadUrl; + private List remoteRepositories; public ArtifactResolutionException( String message, String groupId, String artifactId, String version, String type, - List remoteRepositories, Throwable t ) + List remoteRepositories, String downloadUrl, Throwable t ) { - super( constructMessage( message, groupId, artifactId, version, type, remoteRepositories ), t ); + super( constructMessage( message, groupId, artifactId, version, type, remoteRepositories, downloadUrl ), t ); this.groupId = groupId; this.artifactId = artifactId; this.type = type; this.version = version; this.remoteRepositories = remoteRepositories; + this.downloadUrl = downloadUrl; } private static final String LS = System.getProperty( "line.separator" ); private static String constructMessage( String message, String groupId, String artifactId, String version, - String type, List remoteRepositories ) + String type, List remoteRepositories, String downloadUrl ) { StringBuffer sb = new StringBuffer(); sb.append( message ); sb.append( LS ); - sb.append( LS ); - sb.append( groupId + ":" + artifactId + ":" + version + ":" + type ); + sb.append( " " + groupId + ":" + artifactId + ":" + version + ":" + type ); sb.append( LS ); sb.append( LS ); sb.append( "from the specified remote repositories:" ); - sb.append( LS ); - sb.append( LS ); + sb.append( LS + " " ); for ( Iterator i = remoteRepositories.iterator(); i.hasNext(); ) { @@ -79,13 +80,36 @@ public class ArtifactResolutionException } } + // TODO: don't show this section for metadata + sb.append( LS ); + sb.append( LS ); + sb.append( "Try downloading the file manually" ); + if ( downloadUrl != null ) + { + sb.append( " from " ); + sb.append( LS ); + sb.append( " " + downloadUrl ); + } + sb.append( LS ); + sb.append( "and install it using the command: " ); + sb.append( LS ); + sb.append( " m2 install:install-file -DgroupId=" ); + sb.append( groupId ); + sb.append( " -DartifactId=" ); + sb.append( artifactId ); + sb.append( " -Dversion=" ); + sb.append( version ); + sb.append( " -Dpackaging=" ); + sb.append( type ); + sb.append( " -Dfile=/path/to/file" ); + return sb.toString(); } public ArtifactResolutionException( String message, Artifact artifact, List remoteRepositories, Throwable t ) { this( message, artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion(), artifact.getType(), - remoteRepositories, t ); + remoteRepositories, artifact.getDownloadUrl(), t ); } public ArtifactResolutionException( String message, Throwable cause ) @@ -117,4 +141,9 @@ public class ArtifactResolutionException { return remoteRepositories; } + + public String getDownloadUrl() + { + return downloadUrl; + } } diff --git a/maven-core/src/main/java/org/apache/maven/plugin/PluginNotFoundException.java b/maven-core/src/main/java/org/apache/maven/plugin/PluginNotFoundException.java index 07331432cb..05a3aa1d11 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/PluginNotFoundException.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/PluginNotFoundException.java @@ -30,6 +30,6 @@ public class PluginNotFoundException public PluginNotFoundException( ArtifactResolutionException e ) { super( "Mojo could not be found - check that the goal name is correct", e.getGroupId(), e.getArtifactId(), - e.getVersion(), "maven-plugin", e.getRemoteRepositories(), e ); + e.getVersion(), "maven-plugin", e.getRemoteRepositories(), e.getDownloadUrl(), e ); } } diff --git a/maven-model/maven.mdo b/maven-model/maven.mdo index 5694d5e5be..85b58ad0c5 100644 --- a/maven-model/maven.mdo +++ b/maven-model/maven.mdo @@ -1298,6 +1298,15 @@ Site + + downloadUrl + 4.0.0+ + url. + ]]> + String + @@ -1324,7 +1333,7 @@ distribution - 3.0.0 + 3.0.0+ diff --git a/maven-plugins/maven-install-plugin/src/main/java/org/apache/maven/plugin/install/AbstractInstallMojo.java b/maven-plugins/maven-install-plugin/src/main/java/org/apache/maven/plugin/install/AbstractInstallMojo.java new file mode 100644 index 0000000000..75399b3923 --- /dev/null +++ b/maven-plugins/maven-install-plugin/src/main/java/org/apache/maven/plugin/install/AbstractInstallMojo.java @@ -0,0 +1,45 @@ +package org.apache.maven.plugin.install; + +/* + * Copyright 2001-2005 The Apache Software Foundation. + * + * 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. + */ + +import org.apache.maven.artifact.installer.ArtifactInstaller; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.plugin.AbstractMojo; + +/** + * Common fields for installation mojos. + * + * @author Brett Porter + * @version $Id$ + */ +public abstract class AbstractInstallMojo + extends AbstractMojo +{ + /** + * @parameter expression="${component.org.apache.maven.artifact.installer.ArtifactInstaller}" + * @required + * @readonly + */ + protected ArtifactInstaller installer; + + /** + * @parameter expression="${localRepository}" + * @required + * @readonly + */ + protected ArtifactRepository localRepository; +} diff --git a/maven-plugins/maven-install-plugin/src/main/java/org/apache/maven/plugin/install/InstallFileMojo.java b/maven-plugins/maven-install-plugin/src/main/java/org/apache/maven/plugin/install/InstallFileMojo.java new file mode 100644 index 0000000000..91516d242a --- /dev/null +++ b/maven-plugins/maven-install-plugin/src/main/java/org/apache/maven/plugin/install/InstallFileMojo.java @@ -0,0 +1,86 @@ +package org.apache.maven.plugin.install; + +/* + * Copyright 2001-2005 The Apache Software Foundation. + * + * 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. + */ + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.DefaultArtifact; +import org.apache.maven.artifact.installer.ArtifactInstallationException; +import org.apache.maven.plugin.MojoExecutionException; + +import java.io.File; + +/** + * Installs a file in local repository. + * + * @author Brett Porter + * @version $Id$ + * @goal install-file + */ +public class InstallFileMojo + extends AbstractInstallMojo +{ + /** + * @parameter expression="${groupId}" + * @required + * @readonly + */ + protected String groupId; + + /** + * @parameter expression="${artifactId}" + * @required + * @readonly + */ + protected String artifactId; + + /** + * @parameter expression="${version}" + * @required + * @readonly + */ + protected String version; + + /** + * @parameter expression="${packaging}" + * @required + * @readonly + */ + protected String packaging; + + /** + * @parameter expression="${file}" + * @required + * @readonly + */ + private File file; + + public void execute() + throws MojoExecutionException + { + Artifact artifact = new DefaultArtifact( groupId, artifactId, version, packaging ); + + try + { + installer.install( file, artifact, localRepository ); + } + catch ( ArtifactInstallationException e ) + { + // TODO: install exception that does not give a trace + throw new MojoExecutionException( "Error installing artifact", e ); + } + } +} diff --git a/maven-plugins/maven-install-plugin/src/main/java/org/apache/maven/plugin/install/InstallMojo.java b/maven-plugins/maven-install-plugin/src/main/java/org/apache/maven/plugin/install/InstallMojo.java index b8f4dd2d0f..f97a9a7727 100644 --- a/maven-plugins/maven-install-plugin/src/main/java/org/apache/maven/plugin/install/InstallMojo.java +++ b/maven-plugins/maven-install-plugin/src/main/java/org/apache/maven/plugin/install/InstallMojo.java @@ -29,49 +29,48 @@ import org.apache.maven.project.artifact.ProjectArtifactMetadata; import java.io.File; /** + * Installs project's main artifact in local repository. * @author Emmanuel Venisse * @version $Id$ * @goal install - * @description installs project's main artifact in local repository */ public class InstallMojo - extends AbstractMojo + extends AbstractInstallMojo { - /** * @parameter expression="${project.groupId}" * @required * @readonly */ - private String groupId; + protected String groupId; /** * @parameter expression="${project.artifactId}" * @required * @readonly */ - private String artifactId; + protected String artifactId; /** * @parameter expression="${project.version}" * @required * @readonly */ - private String version; + protected String version; /** * @parameter expression="${project.packaging}" * @required * @readonly */ - private String packaging; + protected String packaging; /** - * @parameter expression="${project.file.parentFile}" + * @parameter expression="${basedir}" * @required * @readonly */ - private File parentDir; + private File basedir; /** * @parameter expression="${project.build.directory}" @@ -86,27 +85,13 @@ public class InstallMojo */ private String finalName; - /** - * @parameter expression="${component.org.apache.maven.artifact.installer.ArtifactInstaller}" - * @required - * @readonly - */ - private ArtifactInstaller installer; - - /** - * @parameter expression="${localRepository}" - * @required - * @readonly - */ - private ArtifactRepository localRepository; - public void execute() throws MojoExecutionException { Artifact artifact = new DefaultArtifact( groupId, artifactId, version, packaging ); boolean isPomArtifact = "pom".equals( packaging ); - File pom = new File( parentDir, "pom.xml" ); + File pom = new File( basedir, "pom.xml" ); if ( !isPomArtifact ) { ArtifactMetadata metadata = new ProjectArtifactMetadata( artifact, pom ); diff --git a/maven-project/src/main/java/org/apache/maven/project/DefaultMavenProjectBuilder.java b/maven-project/src/main/java/org/apache/maven/project/DefaultMavenProjectBuilder.java index 2be934a211..96e4d1c110 100644 --- a/maven-project/src/main/java/org/apache/maven/project/DefaultMavenProjectBuilder.java +++ b/maven-project/src/main/java/org/apache/maven/project/DefaultMavenProjectBuilder.java @@ -170,7 +170,6 @@ public class DefaultMavenProjectBuilder ArtifactRepository localRepository ) throws ProjectBuildingException, ArtifactResolutionException { - Model model = findModelFromRepository( artifact, remoteArtifactRepositories, localRepository ); return build( "Artifact [" + artifact.getId() + "]", model, localRepository ); @@ -191,6 +190,23 @@ public class DefaultMavenProjectBuilder File file = artifact.getFile(); model = readModel( file ); } + + // TODO: this is gross. Would like to give it the whole model, but maven-artifact shouldn't depend on that + // Can a maven-core implementation of the Artifact interface store it, and be used in the exceptions? + String downloadUrl = null; + if ( model.getDistributionManagement() != null ) + { + downloadUrl = model.getDistributionManagement().getDownloadUrl(); + } + if ( downloadUrl != null ) + { + artifact.setDownloadUrl( downloadUrl ); + } + else + { + artifact.setDownloadUrl( model.getUrl() ); + } + return model; } diff --git a/maven-project/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java b/maven-project/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java index 33d2b06e98..c3f7f5cc6b 100644 --- a/maven-project/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java +++ b/maven-project/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java @@ -77,7 +77,7 @@ public class MavenMetadataSource throws ArtifactMetadataRetrievalException, ArtifactResolutionException { // TODO: only metadata is really needed - resolve as metadata - artifact = artifactFactory.createArtifact( artifact.getGroupId(), artifact.getArtifactId(), + Artifact pomArtifact = artifactFactory.createArtifact( artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion(), artifact.getScope(), "pom" ); List dependencies = null; @@ -88,9 +88,10 @@ public class MavenMetadataSource { try { - MavenProject p = mavenProjectBuilder.buildFromRepository( artifact, remoteRepositories, + MavenProject p = mavenProjectBuilder.buildFromRepository( pomArtifact, remoteRepositories, localRepository ); dependencies = p.getDependencies(); + artifact.setDownloadUrl( pomArtifact.getDownloadUrl() ); } catch ( ProjectBuildingException e ) { @@ -103,14 +104,14 @@ public class MavenMetadataSource // need to be able to not have a project builder // TODO: remove - which then makes this a very thin wrapper around a project builder - is it needed? - artifactResolver.resolve( artifact, remoteRepositories, localRepository ); + artifactResolver.resolve( pomArtifact, remoteRepositories, localRepository ); FileReader reader = null; try { // String path = localRepository.pathOfMetadata( new ProjectArtifactMetadata( artifact, null ) ); // File file = new File( localRepository.getBasedir(), path ); - File file = artifact.getFile(); + File file = pomArtifact.getFile(); reader = new FileReader( file ); Model model = this.reader.read( reader ); dependencies = model.getDependencies();