http://git-wip-us.apache.org/repos/asf/maven-aether/blob/1ec78d99/src/main/java/org/eclipse/aether/internal/ant/tasks/AbstractDistTask.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/eclipse/aether/internal/ant/tasks/AbstractDistTask.java b/src/main/java/org/eclipse/aether/internal/ant/tasks/AbstractDistTask.java new file mode 100644 index 0000000..215b6e6 --- /dev/null +++ b/src/main/java/org/eclipse/aether/internal/ant/tasks/AbstractDistTask.java @@ -0,0 +1,197 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Sonatype, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sonatype, Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.aether.internal.ant.tasks; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.maven.model.Model; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.Reference; +import org.eclipse.aether.artifact.DefaultArtifact; +import org.eclipse.aether.internal.ant.AntRepoSys; +import org.eclipse.aether.internal.ant.types.Artifact; +import org.eclipse.aether.internal.ant.types.Artifacts; +import org.eclipse.aether.internal.ant.types.Pom; +import org.eclipse.aether.RepositorySystemSession; + +/** + */ +public abstract class AbstractDistTask + extends Task +{ + + private Pom pom; + + private Artifacts artifacts; + + protected void validate() + { + getArtifacts().validate( this ); + + Map<String, File> duplicates = new HashMap<String, File>(); + for ( Artifact artifact : getArtifacts().getArtifacts() ) + { + String key = artifact.getType() + ':' + artifact.getClassifier(); + if ( "pom:".equals( key ) ) + { + throw new BuildException( "You must not specify an <artifact> with type=pom" + + ", please use the <pom> element instead." ); + } + else if ( duplicates.containsKey( key ) ) + { + throw new BuildException( "You must not specify two or more artifacts with the same type (" + + artifact.getType() + ") and classifier (" + artifact.getClassifier() + ")" ); + } + else + { + duplicates.put( key, artifact.getFile() ); + } + + validateArtifactGav( artifact ); + } + + Pom defaultPom = AntRepoSys.getInstance( getProject() ).getDefaultPom(); + if ( pom == null && defaultPom != null ) + { + log( "Using default POM (" + defaultPom.getCoords() + ")", Project.MSG_INFO ); + pom = defaultPom; + } + + if ( pom == null ) + { + throw new BuildException( "You must specify the <pom file=\"...\"> element" + + " to denote the descriptor for the artifacts" ); + } + if ( pom.getFile() == null ) + { + throw new BuildException( "You must specify a <pom> element that has the 'file' attribute set" ); + } + } + + private void validateArtifactGav( Artifact artifact ) + { + Pom artifactPom = artifact.getPom(); + if ( artifactPom != null ) + { + String gid; + String aid; + String version; + if ( artifactPom.getFile() != null ) + { + Model model = artifactPom.getModel( this ); + gid = model.getGroupId(); + aid = model.getArtifactId(); + version = model.getVersion(); + } + else + { + gid = artifactPom.getGroupId(); + aid = artifactPom.getArtifactId(); + version = artifactPom.getVersion(); + } + + Model model = getPom().getModel( this ); + + if ( ! ( model.getGroupId().equals( gid ) && model.getArtifactId().equals( aid ) && model.getVersion().equals( version )) ) + { + throw new BuildException( "Artifact references different pom than it would be installed with: " + + artifact.toString() ); + } + } + } + + protected List<org.eclipse.aether.artifact.Artifact> toArtifacts( RepositorySystemSession session ) + { + Model model = getPom().getModel( this ); + File pomFile = getPom().getFile(); + + List<org.eclipse.aether.artifact.Artifact> results = new ArrayList<org.eclipse.aether.artifact.Artifact>(); + + org.eclipse.aether.artifact.Artifact pomArtifact = + new DefaultArtifact( model.getGroupId(), model.getArtifactId(), "pom", model.getVersion() ).setFile( pomFile ); + results.add( pomArtifact ); + + for ( Artifact artifact : getArtifacts().getArtifacts() ) + { + org.eclipse.aether.artifact.Artifact buildArtifact = + new DefaultArtifact( model.getGroupId(), model.getArtifactId(), artifact.getClassifier(), + artifact.getType(), model.getVersion() ).setFile( artifact.getFile() ); + results.add( buildArtifact ); + } + + return results; + } + + protected Artifacts getArtifacts() + { + if ( artifacts == null ) + { + artifacts = new Artifacts(); + artifacts.setProject( getProject() ); + } + return artifacts; + } + + public void addArtifact( Artifact artifact ) + { + getArtifacts().addArtifact( artifact ); + } + + public void addArtifacts( Artifacts artifacts ) + { + getArtifacts().addArtifacts( artifacts ); + } + + public void setArtifactsRef( Reference ref ) + { + Artifacts artifacts = new Artifacts(); + artifacts.setProject( getProject() ); + artifacts.setRefid( ref ); + getArtifacts().addArtifacts( artifacts ); + } + + protected Pom getPom() + { + if ( pom == null ) + { + return AntRepoSys.getInstance( getProject() ).getDefaultPom(); + } + + return pom; + } + + public void addPom( Pom pom ) + { + if ( this.pom != null ) + { + throw new BuildException( "You must not specify multiple <pom> elements" ); + } + this.pom = pom; + } + + public void setPomRef( Reference ref ) + { + if ( this.pom != null ) + { + throw new BuildException( "You must not specify multiple <pom> elements" ); + } + pom = new Pom(); + pom.setProject( getProject() ); + pom.setRefid( ref ); + } + +}
http://git-wip-us.apache.org/repos/asf/maven-aether/blob/1ec78d99/src/main/java/org/eclipse/aether/internal/ant/tasks/AbstractResolvingTask.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/eclipse/aether/internal/ant/tasks/AbstractResolvingTask.java b/src/main/java/org/eclipse/aether/internal/ant/tasks/AbstractResolvingTask.java new file mode 100644 index 0000000..8590646 --- /dev/null +++ b/src/main/java/org/eclipse/aether/internal/ant/tasks/AbstractResolvingTask.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Sonatype, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sonatype, Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.aether.internal.ant.tasks; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.Reference; +import org.eclipse.aether.collection.CollectResult; +import org.eclipse.aether.internal.ant.AntRepoSys; +import org.eclipse.aether.internal.ant.types.Dependencies; +import org.eclipse.aether.internal.ant.types.LocalRepository; +import org.eclipse.aether.internal.ant.types.RemoteRepositories; +import org.eclipse.aether.internal.ant.types.RemoteRepository; + +public abstract class AbstractResolvingTask + extends Task +{ + + protected Dependencies dependencies; + + protected RemoteRepositories remoteRepositories; + + protected LocalRepository localRepository; + + public void addDependencies( Dependencies dependencies ) + { + if ( this.dependencies != null ) + { + throw new BuildException( "You must not specify multiple <dependencies> elements" ); + } + this.dependencies = dependencies; + } + + public void setDependenciesRef( Reference ref ) + { + if ( dependencies == null ) + { + dependencies = new Dependencies(); + dependencies.setProject( getProject() ); + } + dependencies.setRefid( ref ); + } + + public LocalRepository createLocalRepo() + { + if ( localRepository != null ) + { + throw new BuildException( "You must not specify multiple <localRepo> elements" ); + } + localRepository = new LocalRepository( this ); + return localRepository; + } + + private RemoteRepositories getRemoteRepos() + { + if ( remoteRepositories == null ) + { + remoteRepositories = new RemoteRepositories(); + remoteRepositories.setProject( getProject() ); + } + return remoteRepositories; + } + + public void addRemoteRepo( RemoteRepository repository ) + { + getRemoteRepos().addRemoterepo( repository ); + } + + public void addRemoteRepos( RemoteRepositories repositories ) + { + getRemoteRepos().addRemoterepos( repositories ); + } + + public void setRemoteReposRef( Reference ref ) + { + RemoteRepositories repos = new RemoteRepositories(); + repos.setProject( getProject() ); + repos.setRefid( ref ); + getRemoteRepos().addRemoterepos( repos ); + } + + protected CollectResult collectDependencies() + { + return AntRepoSys.getInstance( getProject() ).collectDependencies( this, dependencies, localRepository, + remoteRepositories ); + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/maven-aether/blob/1ec78d99/src/main/java/org/eclipse/aether/internal/ant/tasks/DependencyGraphLogger.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/eclipse/aether/internal/ant/tasks/DependencyGraphLogger.java b/src/main/java/org/eclipse/aether/internal/ant/tasks/DependencyGraphLogger.java new file mode 100644 index 0000000..0ebe593 --- /dev/null +++ b/src/main/java/org/eclipse/aether/internal/ant/tasks/DependencyGraphLogger.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Sonatype, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sonatype, Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.aether.internal.ant.tasks; + +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.graph.Dependency; +import org.eclipse.aether.graph.DependencyNode; +import org.eclipse.aether.graph.DependencyVisitor; +import org.eclipse.aether.util.graph.manager.DependencyManagerUtils; + +/** + */ +class DependencyGraphLogger + implements DependencyVisitor +{ + + private Task task; + + private String indent = ""; + + public DependencyGraphLogger( Task task ) + { + this.task = task; + } + + public boolean visitEnter( DependencyNode node ) + { + StringBuilder buffer = new StringBuilder( 128 ); + buffer.append( indent ); + Dependency dep = node.getDependency(); + if ( dep != null ) + { + Artifact art = dep.getArtifact(); + + buffer.append( art ); + buffer.append( ':' ).append( dep.getScope() ); + + String premanagedScope = DependencyManagerUtils.getPremanagedScope( node ); + if ( premanagedScope != null && !premanagedScope.equals( dep.getScope() ) ) + { + buffer.append( " (scope managed from " ).append( premanagedScope ).append( ")" ); + } + + String premanagedVersion = DependencyManagerUtils.getPremanagedVersion( node ); + if ( premanagedVersion != null && !premanagedVersion.equals( art.getVersion() ) ) + { + buffer.append( " (version managed from " ).append( premanagedVersion ).append( ")" ); + } + } + else + { + buffer.append( "Resolved Dependency Graph:" ); + } + + task.log( buffer.toString(), Project.MSG_VERBOSE ); + indent += " "; + return true; + } + + public boolean visitLeave( DependencyNode node ) + { + indent = indent.substring( 0, indent.length() - 3 ); + return true; + } + +} http://git-wip-us.apache.org/repos/asf/maven-aether/blob/1ec78d99/src/main/java/org/eclipse/aether/internal/ant/tasks/Deploy.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/eclipse/aether/internal/ant/tasks/Deploy.java b/src/main/java/org/eclipse/aether/internal/ant/tasks/Deploy.java new file mode 100644 index 0000000..fdf8a83 --- /dev/null +++ b/src/main/java/org/eclipse/aether/internal/ant/tasks/Deploy.java @@ -0,0 +1,120 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Sonatype, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sonatype, Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.aether.internal.ant.tasks; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.types.Reference; +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.deployment.DeployRequest; +import org.eclipse.aether.deployment.DeploymentException; +import org.eclipse.aether.internal.ant.AntRepoSys; +import org.eclipse.aether.internal.ant.types.RemoteRepository; +import org.eclipse.aether.internal.ant.util.ConverterUtils; + +/** + */ +public class Deploy + extends AbstractDistTask +{ + + private RemoteRepository repository; + + private RemoteRepository snapshotRepository; + + @Override + protected void validate() + { + super.validate(); + + if ( repository == null ) + { + throw new BuildException( "You must specify the <remoteRepo id=\"...\" url=\"...\"> element" + + " to denote the target repository for the deployment" ); + } + else + { + repository.validate( this ); + } + if ( snapshotRepository != null ) + { + snapshotRepository.validate( this ); + } + } + + public void addRemoteRepo( RemoteRepository repository ) + { + if ( this.repository != null ) + { + throw new BuildException( "You must not specify multiple <remoteRepo> elements" ); + } + this.repository = repository; + } + + public void setRemoteRepoRef( Reference ref ) + { + if ( repository == null ) + { + repository = new RemoteRepository(); + repository.setProject( getProject() ); + } + repository.setRefid( ref ); + } + + public void addSnapshotRepo( RemoteRepository snapshotRepository ) + { + if ( this.snapshotRepository != null ) + { + throw new BuildException( "You must not specify multiple <snapshotRepo> elements" ); + } + this.snapshotRepository = snapshotRepository; + } + + public void setSnapshotRepoRef( Reference ref ) + { + if ( snapshotRepository == null ) + { + snapshotRepository = new RemoteRepository(); + snapshotRepository.setProject( getProject() ); + } + snapshotRepository.setRefid( ref ); + } + + @Override + public void execute() + throws BuildException + { + validate(); + + AntRepoSys sys = AntRepoSys.getInstance( getProject() ); + + RepositorySystemSession session = sys.getSession( this, null ); + RepositorySystem system = sys.getSystem(); + + DeployRequest request = new DeployRequest(); + + request.setArtifacts( toArtifacts( session ) ); + + boolean snapshot = request.getArtifacts().iterator().next().isSnapshot(); + RemoteRepository distRepo = ( snapshot && snapshotRepository != null ) ? snapshotRepository : repository; + request.setRepository( ConverterUtils.toDistRepository( distRepo, session ) ); + + try + { + system.deploy( session, request ); + } + catch ( DeploymentException e ) + { + throw new BuildException( "Could not deploy artifacts: " + e.getMessage(), e ); + } + } + +} http://git-wip-us.apache.org/repos/asf/maven-aether/blob/1ec78d99/src/main/java/org/eclipse/aether/internal/ant/tasks/Install.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/eclipse/aether/internal/ant/tasks/Install.java b/src/main/java/org/eclipse/aether/internal/ant/tasks/Install.java new file mode 100644 index 0000000..2029c8a --- /dev/null +++ b/src/main/java/org/eclipse/aether/internal/ant/tasks/Install.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Sonatype, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sonatype, Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.aether.internal.ant.tasks; + +import org.apache.tools.ant.BuildException; +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.installation.InstallRequest; +import org.eclipse.aether.installation.InstallationException; +import org.eclipse.aether.internal.ant.AntRepoSys; + +/** + */ +public class Install + extends AbstractDistTask +{ + + @Override + public void execute() + throws BuildException + { + validate(); + + AntRepoSys sys = AntRepoSys.getInstance( getProject() ); + + RepositorySystemSession session = sys.getSession( this, null ); + RepositorySystem system = sys.getSystem(); + + InstallRequest request = new InstallRequest(); + request.setArtifacts( toArtifacts( session ) ); + + try + { + system.install( session, request ); + } + catch ( InstallationException e ) + { + throw new BuildException( "Could not install artifacts: " + e.getMessage(), e ); + } + } + +} http://git-wip-us.apache.org/repos/asf/maven-aether/blob/1ec78d99/src/main/java/org/eclipse/aether/internal/ant/tasks/Layout.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/eclipse/aether/internal/ant/tasks/Layout.java b/src/main/java/org/eclipse/aether/internal/ant/tasks/Layout.java new file mode 100644 index 0000000..40c106b --- /dev/null +++ b/src/main/java/org/eclipse/aether/internal/ant/tasks/Layout.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Sonatype, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sonatype, Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.aether.internal.ant.tasks; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.TreeSet; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.tools.ant.BuildException; +import org.eclipse.aether.artifact.Artifact; + +/** + */ +class Layout +{ + + public static final String GID = "{groupId}"; + + public static final String GID_DIRS = "{groupIdDirs}"; + + public static final String AID = "{artifactId}"; + + public static final String VER = "{version}"; + + public static final String BVER = "{baseVersion}"; + + public static final String EXT = "{extension}"; + + public static final String CLS = "{classifier}"; + + private String[] tokens; + + public Layout( String layout ) + throws BuildException + { + Collection<String> valid = new HashSet<String>( Arrays.asList( GID, GID_DIRS, AID, VER, BVER, EXT, CLS ) ); + List<String> tokens = new ArrayList<String>(); + Matcher m = Pattern.compile( "(\\{[^}]*\\})|([^{]+)" ).matcher( layout ); + while ( m.find() ) + { + if ( m.group( 1 ) != null && !valid.contains( m.group( 1 ) ) ) + { + throw new BuildException( "Invalid variable '" + m.group() + "' in layout, supported variables are " + + new TreeSet<String>( valid ) ); + } + tokens.add( m.group() ); + } + this.tokens = tokens.toArray( new String[tokens.size()] ); + } + + public String getPath( Artifact artifact ) + { + StringBuilder buffer = new StringBuilder( 128 ); + + for ( int i = 0; i < tokens.length; i++ ) + { + String token = tokens[i]; + if ( GID.equals( token ) ) + { + buffer.append( artifact.getGroupId() ); + } + else if ( GID_DIRS.equals( token ) ) + { + buffer.append( artifact.getGroupId().replace( '.', '/' ) ); + } + else if ( AID.equals( token ) ) + { + buffer.append( artifact.getArtifactId() ); + } + else if ( VER.equals( token ) ) + { + buffer.append( artifact.getVersion() ); + } + else if ( BVER.equals( token ) ) + { + buffer.append( artifact.getBaseVersion() ); + } + else if ( CLS.equals( token ) ) + { + if ( artifact.getClassifier().length() <= 0 ) + { + if ( i > 0 ) + { + String lt = tokens[i - 1]; + if ( lt.length() > 0 && "-_".indexOf( lt.charAt( lt.length() - 1 ) ) >= 0 ) + { + buffer.setLength( buffer.length() - 1 ); + } + } + } + else + { + buffer.append( artifact.getClassifier() ); + } + } + else if ( EXT.equals( token ) ) + { + buffer.append( artifact.getExtension() ); + } + else + { + buffer.append( token ); + } + } + + return buffer.toString(); + } + +} http://git-wip-us.apache.org/repos/asf/maven-aether/blob/1ec78d99/src/main/java/org/eclipse/aether/internal/ant/tasks/RefTask.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/eclipse/aether/internal/ant/tasks/RefTask.java b/src/main/java/org/eclipse/aether/internal/ant/tasks/RefTask.java new file mode 100644 index 0000000..843d814 --- /dev/null +++ b/src/main/java/org/eclipse/aether/internal/ant/tasks/RefTask.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Sonatype, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sonatype, Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.aether.internal.ant.tasks; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.ComponentHelper; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.Reference; + +/** + */ +public abstract class RefTask + extends Task +{ + + private Reference ref; + + public boolean isReference() + { + return ref != null; + } + + public void setRefid( final Reference ref ) + { + this.ref = ref; + } + + protected void checkAttributesAllowed() + { + if ( isReference() ) + { + throw tooManyAttributes(); + } + } + + protected void checkChildrenAllowed() + { + if ( isReference() ) + { + throw noChildrenAllowed(); + } + } + + protected BuildException tooManyAttributes() + { + return new BuildException( "You must not specify more than one " + "attribute when using refid" ); + } + + protected BuildException noChildrenAllowed() + { + return new BuildException( "You must not specify nested elements " + "when using refid" ); + } + + protected String getDataTypeName() + { + return ComponentHelper.getElementName( getProject(), this, true ); + } + + protected Object getCheckedRef() + { + return getCheckedRef( getClass(), getDataTypeName(), getProject() ); + } + + protected Object getCheckedRef( final Class<?> requiredClass, final String dataTypeName, final Project project ) + { + if ( project == null ) + { + throw new BuildException( "No Project specified" ); + } + Object o = ref.getReferencedObject( project ); + if ( !( requiredClass.isAssignableFrom( o.getClass() ) ) ) + { + log( "Class " + o.getClass() + " is not a subclass of " + requiredClass, Project.MSG_VERBOSE ); + String msg = ref.getRefId() + " doesn\'t denote a " + dataTypeName; + throw new BuildException( msg ); + } + return o; + } + +} http://git-wip-us.apache.org/repos/asf/maven-aether/blob/1ec78d99/src/main/java/org/eclipse/aether/internal/ant/tasks/Resolve.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/eclipse/aether/internal/ant/tasks/Resolve.java b/src/main/java/org/eclipse/aether/internal/ant/tasks/Resolve.java new file mode 100644 index 0000000..48fcaac --- /dev/null +++ b/src/main/java/org/eclipse/aether/internal/ant/tasks/Resolve.java @@ -0,0 +1,542 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Sonatype, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sonatype, Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.aether.internal.ant.tasks; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.ProjectComponent; +import org.apache.tools.ant.types.FileSet; +import org.apache.tools.ant.types.Reference; +import org.apache.tools.ant.util.FileUtils; +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.graph.DependencyFilter; +import org.eclipse.aether.graph.DependencyNode; +import org.eclipse.aether.internal.ant.AntRepoSys; +import org.eclipse.aether.internal.ant.Names; +import org.eclipse.aether.internal.ant.types.Dependencies; +import org.eclipse.aether.internal.ant.types.Pom; +import org.eclipse.aether.resolution.ArtifactRequest; +import org.eclipse.aether.resolution.ArtifactResolutionException; +import org.eclipse.aether.resolution.ArtifactResult; +import org.eclipse.aether.util.artifact.SubArtifact; +import org.eclipse.aether.util.filter.ScopeDependencyFilter; + +/** + */ +public class Resolve + extends AbstractResolvingTask +{ + + private List<ArtifactConsumer> consumers = new ArrayList<ArtifactConsumer>(); + + private boolean failOnMissingAttachments; + + public void setFailOnMissingAttachments( boolean failOnMissingAttachments ) + { + this.failOnMissingAttachments = failOnMissingAttachments; + } + + public Path createPath() + { + Path path = new Path(); + consumers.add( path ); + return path; + } + + public Files createFiles() + { + Files files = new Files(); + consumers.add( files ); + return files; + } + + public Props createProperties() + { + Props props = new Props(); + consumers.add( props ); + return props; + } + + private void validate() + { + for ( ArtifactConsumer consumer : consumers ) + { + consumer.validate(); + } + + Pom pom = AntRepoSys.getInstance( getProject() ).getDefaultPom(); + if ( dependencies == null && pom != null ) + { + log( "Using default pom for dependency resolution (" + pom.toString() + ")", Project.MSG_INFO ); + dependencies = new Dependencies(); + dependencies.setProject( getProject() ); + getProject().addReference( Names.ID_DEFAULT_POM, pom ); + dependencies.setPomRef( new Reference( getProject(), Names.ID_DEFAULT_POM ) ); + } + + if ( dependencies != null ) + { + dependencies.validate( this ); + } + else + { + throw new BuildException( "No <dependencies> set for resolution" ); + } + } + + @Override + public void execute() + throws BuildException + { + validate(); + + + AntRepoSys sys = AntRepoSys.getInstance( getProject() ); + + RepositorySystemSession session = sys.getSession( this, localRepository ); + RepositorySystem system = sys.getSystem(); + log( "Using local repository " + session.getLocalRepository(), Project.MSG_VERBOSE ); + + DependencyNode root = collectDependencies().getRoot(); + root.accept( new DependencyGraphLogger( this ) ); + + Map<String, Group> groups = new HashMap<String, Group>(); + for ( ArtifactConsumer consumer : consumers ) + { + String classifier = consumer.getClassifier(); + Group group = groups.get( classifier ); + if ( group == null ) + { + group = new Group( classifier ); + groups.put( classifier, group ); + } + group.add( consumer ); + } + + for ( Group group : groups.values() ) + { + group.createRequests( root ); + } + + log( "Resolving artifacts", Project.MSG_INFO ); + + for ( Group group : groups.values() ) + { + List<ArtifactResult> results; + try + { + results = system.resolveArtifacts( session, group.getRequests() ); + } + catch ( ArtifactResolutionException e ) + { + if ( !group.isAttachments() || failOnMissingAttachments ) + { + throw new BuildException( "Could not resolve artifacts: " + e.getMessage(), e ); + } + results = e.getResults(); + for ( ArtifactResult result : results ) + { + if ( result.isMissing() ) + { + log( "Ignoring missing attachment " + result.getRequest().getArtifact(), Project.MSG_VERBOSE ); + } + else if ( !result.isResolved() ) + { + throw new BuildException( "Could not resolve artifacts: " + e.getMessage(), e ); + } + } + } + + group.processResults( results ); + } + } + + public static abstract class ArtifactConsumer + extends ProjectComponent + { + + private DependencyFilter filter; + + public boolean accept( org.eclipse.aether.graph.DependencyNode node, List<DependencyNode> parents ) + { + return filter == null || filter.accept( node, parents ); + } + + public String getClassifier() + { + return null; + } + + public void validate() + { + + } + + public abstract void process( Artifact artifact ); + + public void setScopes( String scopes ) + { + if ( filter != null ) + { + throw new BuildException( "You must not specify both 'scopes' and 'classpath'" ); + } + + Collection<String> included = new HashSet<String>(); + Collection<String> excluded = new HashSet<String>(); + + String[] split = scopes.split( "[, ]" ); + for ( String scope : split ) + { + scope = scope.trim(); + Collection<String> dst; + if ( scope.startsWith( "-" ) || scope.startsWith( "!" ) ) + { + dst = excluded; + scope = scope.substring( 1 ); + } + else + { + dst = included; + } + if ( scope.length() > 0 ) + { + dst.add( scope ); + } + } + + filter = new ScopeDependencyFilter( included, excluded ); + } + + public void setClasspath( String classpath ) + { + if ( "compile".equals( classpath ) ) + { + setScopes( "provided,system,compile" ); + } + else if ( "runtime".equals( classpath ) ) + { + setScopes( "compile,runtime" ); + } + else if ( "test".equals( classpath ) ) + { + setScopes( "provided,system,compile,runtime,test" ); + } + else + { + throw new BuildException( "The classpath '" + classpath + "' is not defined" + + ", must be one of 'compile', 'runtime' or 'test'" ); + } + } + + } + + public class Path + extends ArtifactConsumer + { + + private String refid; + + private org.apache.tools.ant.types.Path path; + + public void setRefId( String refId ) + { + this.refid = refId; + } + + public void validate() + { + if ( refid == null ) + { + throw new BuildException( "You must specify the 'refid' for the path" ); + } + } + + public void process( Artifact artifact ) + { + if ( path == null ) + { + path = new org.apache.tools.ant.types.Path( getProject() ); + getProject().addReference( refid, path ); + } + path.setLocation( artifact.getFile() ); + } + + } + + public class Files + extends ArtifactConsumer + { + + private static final String DEFAULT_LAYOUT = Layout.GID_DIRS + "/" + Layout.AID + "/" + Layout.BVER + "/" + + Layout.AID + "-" + Layout.VER + "-" + Layout.CLS + "." + Layout.EXT; + + private String refid; + + private String classifier; + + private File dir; + + private Layout layout = new Layout( DEFAULT_LAYOUT ); + + private FileSet fileset; + + public void setRefId( String refId ) + { + this.refid = refId; + } + + public String getClassifier() + { + return classifier; + } + + public void setAttachments( String attachments ) + { + if ( "sources".equals( attachments ) ) + { + classifier = "*-sources"; + } + else if ( "javadoc".equals( attachments ) ) + { + classifier = "*-javadoc"; + } + else + { + throw new BuildException( "The attachment type '" + attachments + + "' is not defined, must be one of 'sources' or 'javadoc'" ); + } + } + + public void setDir( File dir ) + { + this.dir = dir; + } + + public void setLayout( String layout ) + { + this.layout = new Layout( layout ); + } + + public void validate() + { + if ( refid == null && dir == null ) + { + throw new BuildException( "You must either specify the 'refid' for the resource collection" + + " or a 'dir' to copy the files to" ); + } + } + + public void process( Artifact artifact ) + { + if ( dir != null ) + { + if ( refid != null && fileset == null ) + { + fileset = new FileSet(); + fileset.setProject( getProject() ); + fileset.setDir( dir ); + getProject().addReference( refid, fileset ); + } + + String path = layout.getPath( artifact ); + + if ( fileset != null ) + { + fileset.createInclude().setName( path ); + } + + File src = artifact.getFile(); + File dst = new File( dir, path ); + + if ( src.lastModified() != dst.lastModified() || src.length() != dst.length() ) + { + try + { + Resolve.this.log( "Copy " + src + " to " + dst, Project.MSG_VERBOSE ); + FileUtils.getFileUtils().copyFile( src, dst, null, true, true ); + } + catch ( IOException e ) + { + throw new BuildException( "Failed to copy artifact file " + src + " to " + dst + ": " + + e.getMessage(), e ); + } + } + else + { + Resolve.this.log( "Omit to copy " + src + " to " + dst + ", seems unchanged", Project.MSG_VERBOSE ); + } + } + } + + } + + public class Props + extends ArtifactConsumer + { + + private String prefix; + + private String classifier; + + public void setPrefix( String prefix ) + { + this.prefix = prefix; + } + + public String getClassifier() + { + return classifier; + } + + public void setAttachments( String attachments ) + { + if ( "sources".equals( attachments ) ) + { + classifier = "*-sources"; + } + else if ( "javadoc".equals( attachments ) ) + { + classifier = "*-javadoc"; + } + else + { + throw new BuildException( "The attachment type '" + attachments + + "' is not defined, must be one of 'sources' or 'javadoc'" ); + } + } + + public void process( Artifact artifact ) + { + StringBuilder buffer = new StringBuilder( 256 ); + if ( prefix != null && prefix.length() > 0 ) + { + buffer.append( prefix ); + if ( !prefix.endsWith( "." ) ) + { + buffer.append( '.' ); + } + } + buffer.append( artifact.getGroupId() ); + buffer.append( ':' ); + buffer.append( artifact.getArtifactId() ); + buffer.append( ':' ); + buffer.append( artifact.getExtension() ); + if ( artifact.getClassifier().length() > 0 ) + { + buffer.append( ':' ); + buffer.append( artifact.getClassifier() ); + } + + String path = artifact.getFile().getAbsolutePath(); + + getProject().setProperty( buffer.toString(), path ); + } + + } + + private static class Group + { + + private String classifier; + + private List<ArtifactConsumer> consumers = new ArrayList<ArtifactConsumer>(); + + private List<ArtifactRequest> requests = new ArrayList<ArtifactRequest>(); + + public Group( String classifier ) + { + this.classifier = classifier; + } + + public boolean isAttachments() + { + return classifier != null; + } + + public void add( ArtifactConsumer consumer ) + { + consumers.add( consumer ); + } + + public void createRequests( DependencyNode node ) + { + createRequests( node, new LinkedList<DependencyNode>() ); + } + + private void createRequests( DependencyNode node, LinkedList<DependencyNode> parents ) + { + if ( node.getDependency() != null ) + { + for ( ArtifactConsumer consumer : consumers ) + { + if ( consumer.accept( node, parents ) ) + { + ArtifactRequest request = new ArtifactRequest( node ); + if ( classifier != null ) + { + request.setArtifact( new SubArtifact( request.getArtifact(), classifier, "jar" ) ); + } + requests.add( request ); + break; + } + } + } + + parents.addFirst( node ); + + for ( DependencyNode child : node.getChildren() ) + { + createRequests( child, parents ); + } + + parents.removeFirst(); + } + + public List<ArtifactRequest> getRequests() + { + return requests; + } + + public void processResults( List<ArtifactResult> results ) + { + for ( ArtifactResult result : results ) + { + if ( !result.isResolved() ) + { + continue; + } + for ( ArtifactConsumer consumer : consumers ) + { + if ( consumer.accept( result.getRequest().getDependencyNode(), + Collections.<DependencyNode> emptyList() ) ) + { + consumer.process( result.getArtifact() ); + } + } + } + } + + } + +} http://git-wip-us.apache.org/repos/asf/maven-aether/blob/1ec78d99/src/main/java/org/eclipse/aether/internal/ant/types/Artifact.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/eclipse/aether/internal/ant/types/Artifact.java b/src/main/java/org/eclipse/aether/internal/ant/types/Artifact.java new file mode 100644 index 0000000..7c0baf2 --- /dev/null +++ b/src/main/java/org/eclipse/aether/internal/ant/types/Artifact.java @@ -0,0 +1,172 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Sonatype, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sonatype, Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.aether.internal.ant.types; + +import java.io.File; +import java.util.Collections; +import java.util.List; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.Reference; +import org.eclipse.aether.internal.ant.ProjectWorkspaceReader; +import org.eclipse.aether.internal.ant.tasks.RefTask; + +/** + */ +public class Artifact + extends RefTask + implements ArtifactContainer +{ + + private File file; + + private String type; + + private String classifier; + + private Pom pom; + + protected Artifact getRef() + { + return (Artifact) getCheckedRef(); + } + + public void validate( Task task ) + { + if ( isReference() ) + { + getRef().validate( task ); + } + else + { + if ( file == null ) + { + throw new BuildException( "You must specify the 'file' for the artifact" ); + } + else if ( !file.isFile() ) + { + throw new BuildException( "The artifact file " + file + " does not exist" ); + } + if ( type == null || type.length() <= 0 ) + { + throw new BuildException( "You must specify the 'type' for the artifact" ); + } + } + } + + public void setRefid( Reference ref ) + { + if ( file != null || type != null || classifier != null ) + { + throw tooManyAttributes(); + } + super.setRefid( ref ); + } + + public File getFile() + { + if ( isReference() ) + { + return getRef().getFile(); + } + return file; + } + + public void setFile( File file ) + { + checkAttributesAllowed(); + this.file = file; + + if ( file != null && type == null ) + { + String name = file.getName(); + int period = name.lastIndexOf( '.' ); + if ( period >= 0 ) + { + type = name.substring( period + 1 ); + } + } + } + + public String getType() + { + if ( isReference() ) + { + return getRef().getType(); + } + return ( type != null ) ? type : "jar"; + } + + public void setType( String type ) + { + checkAttributesAllowed(); + this.type = type; + } + + public String getClassifier() + { + if ( isReference() ) + { + return getRef().getClassifier(); + } + return ( classifier != null ) ? classifier : ""; + } + + public void setClassifier( String classifier ) + { + checkAttributesAllowed(); + this.classifier = classifier; + } + + public void setPomRef( Reference ref ) + { + checkAttributesAllowed(); + Pom pom = new Pom(); + pom.setProject( getProject() ); + pom.setRefid( ref ); + this.pom = pom; + } + + public void addPom( Pom pom ) + { + checkChildrenAllowed(); + this.pom = pom; + } + + public Pom getPom() + { + if ( isReference() ) + { + return getRef().getPom(); + } + return pom; + } + + public List<Artifact> getArtifacts() + { + return Collections.singletonList( this ); + } + + @Override + public void execute() + throws BuildException + { + ProjectWorkspaceReader.getInstance().addArtifact( this ); + } + + public String toString() + { + String pomRepr = getPom() != null ? "(" + getPom().toString() + ":)" : ""; + return String.format( pomRepr + "%s:%s", getType(), getClassifier() ); + } + +} http://git-wip-us.apache.org/repos/asf/maven-aether/blob/1ec78d99/src/main/java/org/eclipse/aether/internal/ant/types/ArtifactContainer.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/eclipse/aether/internal/ant/types/ArtifactContainer.java b/src/main/java/org/eclipse/aether/internal/ant/types/ArtifactContainer.java new file mode 100644 index 0000000..c266355 --- /dev/null +++ b/src/main/java/org/eclipse/aether/internal/ant/types/ArtifactContainer.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Sonatype, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sonatype, Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.aether.internal.ant.types; + +import java.util.List; + +import org.apache.tools.ant.Task; + +/** + */ +public interface ArtifactContainer +{ + + void validate( Task task ); + + List<Artifact> getArtifacts(); + +} http://git-wip-us.apache.org/repos/asf/maven-aether/blob/1ec78d99/src/main/java/org/eclipse/aether/internal/ant/types/Artifacts.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/eclipse/aether/internal/ant/types/Artifacts.java b/src/main/java/org/eclipse/aether/internal/ant/types/Artifacts.java new file mode 100644 index 0000000..3e3c563 --- /dev/null +++ b/src/main/java/org/eclipse/aether/internal/ant/types/Artifacts.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Sonatype, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sonatype, Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.aether.internal.ant.types; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.DataType; +import org.apache.tools.ant.types.Reference; + +/** + */ +public class Artifacts + extends DataType + implements ArtifactContainer +{ + + private List<ArtifactContainer> containers = new ArrayList<ArtifactContainer>(); + + protected Artifacts getRef() + { + return (Artifacts) getCheckedRef(); + } + + public void validate( Task task ) + { + if ( isReference() ) + { + getRef().validate( task ); + } + else + { + for ( ArtifactContainer container : containers ) + { + container.validate( task ); + } + } + } + + public void setRefid( Reference ref ) + { + if ( !containers.isEmpty() ) + { + throw noChildrenAllowed(); + } + super.setRefid( ref ); + } + + public void addArtifact( Artifact artifact ) + { + checkChildrenAllowed(); + containers.add( artifact ); + } + + public void addArtifacts( Artifacts artifacts ) + { + checkChildrenAllowed(); + if ( artifacts == this ) + { + throw circularReference(); + } + containers.add( artifacts ); + } + + public List<Artifact> getArtifacts() + { + if ( isReference() ) + { + return getRef().getArtifacts(); + } + List<Artifact> artifacts = new ArrayList<Artifact>(); + for ( ArtifactContainer container : containers ) + { + artifacts.addAll( container.getArtifacts() ); + } + return artifacts; + } + +} http://git-wip-us.apache.org/repos/asf/maven-aether/blob/1ec78d99/src/main/java/org/eclipse/aether/internal/ant/types/Authentication.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/eclipse/aether/internal/ant/types/Authentication.java b/src/main/java/org/eclipse/aether/internal/ant/types/Authentication.java new file mode 100644 index 0000000..5df2b3b --- /dev/null +++ b/src/main/java/org/eclipse/aether/internal/ant/types/Authentication.java @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Sonatype, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sonatype, Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.aether.internal.ant.types; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.tools.ant.Project; +import org.apache.tools.ant.types.DataType; +import org.apache.tools.ant.types.Reference; +import org.eclipse.aether.internal.ant.AntRepoSys; + +/** + */ +public class Authentication + extends DataType +{ + + private String username; + + private String password; + + private String privateKeyFile; + + private String passphrase; + + private List<String> servers = new ArrayList<String>(); + + @Override + public void setProject( Project project ) + { + super.setProject( project ); + + AntRepoSys.getInstance( project ).addAuthentication( this ); + } + + protected Authentication getRef() + { + return (Authentication) getCheckedRef(); + } + + public void setRefid( Reference ref ) + { + if ( username != null || password != null || privateKeyFile != null || passphrase != null ) + { + throw tooManyAttributes(); + } + super.setRefid( ref ); + } + + public String getUsername() + { + if ( isReference() ) + { + return getRef().getUsername(); + } + return username; + } + + public void setUsername( String username ) + { + checkAttributesAllowed(); + this.username = username; + } + + public String getPassword() + { + if ( isReference() ) + { + return getRef().getPassword(); + } + return password; + } + + public void setPassword( String password ) + { + checkAttributesAllowed(); + this.password = password; + } + + public String getPrivateKeyFile() + { + if ( isReference() ) + { + return getRef().getPrivateKeyFile(); + } + return privateKeyFile; + } + + public void setPrivateKeyFile( String privateKeyFile ) + { + checkAttributesAllowed(); + this.privateKeyFile = privateKeyFile; + } + + public String getPassphrase() + { + if ( isReference() ) + { + return getRef().getPassphrase(); + } + return passphrase; + } + + public void setPassphrase( String passphrase ) + { + checkAttributesAllowed(); + this.passphrase = passphrase; + } + + public List<String> getServers() + { + if ( isReference() ) + { + return getRef().getServers(); + } + return servers; + } + + public void setServers( String servers ) + { + checkAttributesAllowed(); + this.servers.clear(); + String[] split = servers.split( "[;:]" ); + for ( String server : split ) + { + server = server.trim(); + if ( server.length() > 0 ) + { + this.servers.add( server ); + } + } + } + +} http://git-wip-us.apache.org/repos/asf/maven-aether/blob/1ec78d99/src/main/java/org/eclipse/aether/internal/ant/types/Dependencies.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/eclipse/aether/internal/ant/types/Dependencies.java b/src/main/java/org/eclipse/aether/internal/ant/types/Dependencies.java new file mode 100644 index 0000000..70979cd --- /dev/null +++ b/src/main/java/org/eclipse/aether/internal/ant/types/Dependencies.java @@ -0,0 +1,188 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Sonatype, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sonatype, Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.aether.internal.ant.types; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.DataType; +import org.apache.tools.ant.types.Reference; + +/** + */ +public class Dependencies + extends DataType + implements DependencyContainer +{ + + private File file; + + private Pom pom; + + private List<DependencyContainer> containers = new ArrayList<DependencyContainer>(); + + private List<Exclusion> exclusions = new ArrayList<Exclusion>(); + + private boolean nestedDependencies; + + protected Dependencies getRef() + { + return (Dependencies) getCheckedRef(); + } + + public void validate( Task task ) + { + if ( isReference() ) + { + getRef().validate( task ); + } + else + { + if ( getPom() != null && getPom().getFile() == null ) + { + throw new BuildException( "A <pom> used for dependency resolution has to be backed by a pom.xml file" ); + } + Map<String, String> ids = new HashMap<String, String>(); + for ( DependencyContainer container : containers ) + { + container.validate( task ); + if ( container instanceof Dependency ) + { + Dependency dependency = (Dependency) container; + String id = dependency.getVersionlessKey(); + String collision = ids.put( id, dependency.getVersion() ); + if ( collision != null ) + { + throw new BuildException( "You must not declare multiple <dependency> elements" + + " with the same coordinates but got " + id + " -> " + collision + " vs " + + dependency.getVersion() ); + } + } + } + } + } + + public void setRefid( Reference ref ) + { + if ( pom != null || !exclusions.isEmpty() || !containers.isEmpty() ) + { + throw noChildrenAllowed(); + } + super.setRefid( ref ); + } + + public void setFile( File file ) + { + checkAttributesAllowed(); + this.file = file; + checkExternalSources(); + } + + public File getFile() + { + if ( isReference() ) + { + return getRef().getFile(); + } + return file; + } + + public void addPom( Pom pom ) + { + checkChildrenAllowed(); + if ( this.pom != null ) + { + throw new BuildException( "You must not specify multiple <pom> elements" ); + } + this.pom = pom; + checkExternalSources(); + } + + public Pom getPom() + { + if ( isReference() ) + { + return getRef().getPom(); + } + return pom; + } + + public void setPomRef( Reference ref ) + { + if ( pom == null ) + { + pom = new Pom(); + pom.setProject( getProject() ); + } + pom.setRefid( ref ); + checkExternalSources(); + } + + private void checkExternalSources() + { + if ( file != null && pom != null ) + { + throw new BuildException( "You must not specify both a text file and a POM to list dependencies" ); + } + if ( ( file != null || pom != null ) && nestedDependencies ) + { + throw new BuildException( "You must not specify both a file/POM and nested dependency collections" ); + } + } + + public void addDependency( Dependency dependency ) + { + checkChildrenAllowed(); + containers.add( dependency ); + } + + public void addDependencies( Dependencies dependencies ) + { + checkChildrenAllowed(); + if ( dependencies == this ) + { + throw circularReference(); + } + containers.add( dependencies ); + nestedDependencies = true; + checkExternalSources(); + } + + public List<DependencyContainer> getDependencyContainers() + { + if ( isReference() ) + { + return getRef().getDependencyContainers(); + } + return containers; + } + + public void addExclusion( Exclusion exclusion ) + { + checkChildrenAllowed(); + this.exclusions.add( exclusion ); + } + + public List<Exclusion> getExclusions() + { + if ( isReference() ) + { + return getRef().getExclusions(); + } + return exclusions; + } + +} http://git-wip-us.apache.org/repos/asf/maven-aether/blob/1ec78d99/src/main/java/org/eclipse/aether/internal/ant/types/Dependency.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/eclipse/aether/internal/ant/types/Dependency.java b/src/main/java/org/eclipse/aether/internal/ant/types/Dependency.java new file mode 100644 index 0000000..6026363 --- /dev/null +++ b/src/main/java/org/eclipse/aether/internal/ant/types/Dependency.java @@ -0,0 +1,320 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Sonatype, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sonatype, Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.aether.internal.ant.types; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.DataType; +import org.apache.tools.ant.types.Reference; + +/** + */ +public class Dependency + extends DataType + implements DependencyContainer +{ + + private String groupId; + + private String artifactId; + + private String version; + + private String classifier; + + private String type; + + private String scope; + + private File systemPath; + + private List<Exclusion> exclusions = new ArrayList<Exclusion>(); + + protected Dependency getRef() + { + return (Dependency) getCheckedRef(); + } + + public void validate( Task task ) + { + if ( isReference() ) + { + getRef().validate( task ); + } + else + { + if ( groupId == null || groupId.length() <= 0 ) + { + throw new BuildException( "You must specify the 'groupId' for a dependency" ); + } + if ( artifactId == null || artifactId.length() <= 0 ) + { + throw new BuildException( "You must specify the 'artifactId' for a dependency" ); + } + if ( version == null || version.length() <= 0 ) + { + throw new BuildException( "You must specify the 'version' for a dependency" ); + } + + if ( "system".equals( scope ) ) + { + if ( systemPath == null ) + { + throw new BuildException( "You must specify 'systemPath' for dependencies with scope=system" ); + } + } + else if ( systemPath != null ) + { + throw new BuildException( "You may only specify 'systemPath' for dependencies with scope=system" ); + } + + if ( scope != null && !"compile".equals( scope ) && !"provided".equals( scope ) && !"system".equals( scope ) + && !"runtime".equals( scope ) && !"test".equals( scope ) ) + { + task.log( "Unknown scope '" + scope + "' for dependency", Project.MSG_WARN ); + } + + for ( Exclusion exclusion : exclusions ) + { + exclusion.validate( task ); + } + } + } + + public void setRefid( Reference ref ) + { + if ( groupId != null || artifactId != null || type != null || classifier != null || version != null + || scope != null || systemPath != null ) + { + throw tooManyAttributes(); + } + if ( !exclusions.isEmpty() ) + { + throw noChildrenAllowed(); + } + super.setRefid( ref ); + } + + public String getGroupId() + { + if ( isReference() ) + { + return getRef().getGroupId(); + } + return groupId; + } + + public void setGroupId( String groupId ) + { + checkAttributesAllowed(); + if ( this.groupId != null ) + { + throw ambiguousCoords(); + } + this.groupId = groupId; + } + + public String getArtifactId() + { + if ( isReference() ) + { + return getRef().getArtifactId(); + } + return artifactId; + } + + public void setArtifactId( String artifactId ) + { + checkAttributesAllowed(); + if ( this.artifactId != null ) + { + throw ambiguousCoords(); + } + this.artifactId = artifactId; + } + + public String getVersion() + { + if ( isReference() ) + { + return getRef().getVersion(); + } + return version; + } + + public void setVersion( String version ) + { + checkAttributesAllowed(); + if ( this.version != null ) + { + throw ambiguousCoords(); + } + this.version = version; + } + + public String getClassifier() + { + if ( isReference() ) + { + return getRef().getClassifier(); + } + return classifier; + } + + public void setClassifier( String classifier ) + { + checkAttributesAllowed(); + if ( this.classifier != null ) + { + throw ambiguousCoords(); + } + this.classifier = classifier; + } + + public String getType() + { + if ( isReference() ) + { + return getRef().getType(); + } + return ( type != null ) ? type : "jar"; + } + + public void setType( String type ) + { + checkAttributesAllowed(); + if ( this.type != null ) + { + throw ambiguousCoords(); + } + this.type = type; + } + + public String getScope() + { + if ( isReference() ) + { + return getRef().getScope(); + } + return ( scope != null ) ? scope : "compile"; + } + + public void setScope( String scope ) + { + checkAttributesAllowed(); + if ( this.scope != null ) + { + throw ambiguousCoords(); + } + this.scope = scope; + } + + public void setCoords( String coords ) + { + checkAttributesAllowed(); + if ( groupId != null || artifactId != null || version != null || type != null || classifier != null + || scope != null ) + { + throw ambiguousCoords(); + } + Pattern p = Pattern.compile( "([^: ]+):([^: ]+):([^: ]+)((:([^: ]+)(:([^: ]+))?)?:([^: ]+))?" ); + Matcher m = p.matcher( coords ); + if ( !m.matches() ) + { + throw new BuildException( "Bad dependency coordinates '" + coords + + "', expected format is <groupId>:<artifactId>:<version>[[:<type>[:<classifier>]]:<scope>]" ); + } + groupId = m.group( 1 ); + artifactId = m.group( 2 ); + version = m.group( 3 ); + type = m.group( 6 ); + if ( type == null || type.length() <= 0 ) + { + type = "jar"; + } + classifier = m.group( 8 ); + if ( classifier == null ) + { + classifier = ""; + } + scope = m.group( 9 ); + } + + public void setSystemPath( File systemPath ) + { + checkAttributesAllowed(); + this.systemPath = systemPath; + } + + public File getSystemPath() + { + if ( isReference() ) + { + return getRef().getSystemPath(); + } + return systemPath; + } + + public String getVersionlessKey() + { + if ( isReference() ) + { + return getRef().getVersionlessKey(); + } + StringBuilder key = new StringBuilder( 128 ); + if ( groupId != null ) + { + key.append( groupId ); + } + key.append( ':' ); + if ( artifactId != null ) + { + key.append( artifactId ); + } + key.append( ':' ); + key.append( ( type != null ) ? type : "jar" ); + if ( classifier != null && classifier.length() > 0 ) + { + key.append( ':' ); + key.append( classifier ); + } + return key.toString(); + } + + public void addExclusion( Exclusion exclusion ) + { + checkChildrenAllowed(); + this.exclusions.add( exclusion ); + } + + public List<Exclusion> getExclusions() + { + if ( isReference() ) + { + return getRef().getExclusions(); + } + return exclusions; + } + + private BuildException ambiguousCoords() + { + return new BuildException( "You must not specify both 'coords' and " + + "('groupId', 'artifactId', 'version', 'extension', 'classifier', 'scope')" ); + } + +} http://git-wip-us.apache.org/repos/asf/maven-aether/blob/1ec78d99/src/main/java/org/eclipse/aether/internal/ant/types/DependencyContainer.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/eclipse/aether/internal/ant/types/DependencyContainer.java b/src/main/java/org/eclipse/aether/internal/ant/types/DependencyContainer.java new file mode 100644 index 0000000..e357d98 --- /dev/null +++ b/src/main/java/org/eclipse/aether/internal/ant/types/DependencyContainer.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2014 Sonatype, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sonatype, Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.aether.internal.ant.types; + +import org.apache.tools.ant.Task; + +/** + */ +public interface DependencyContainer +{ + + void validate( Task task ); + +} http://git-wip-us.apache.org/repos/asf/maven-aether/blob/1ec78d99/src/main/java/org/eclipse/aether/internal/ant/types/Exclusion.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/eclipse/aether/internal/ant/types/Exclusion.java b/src/main/java/org/eclipse/aether/internal/ant/types/Exclusion.java new file mode 100644 index 0000000..771bbf0 --- /dev/null +++ b/src/main/java/org/eclipse/aether/internal/ant/types/Exclusion.java @@ -0,0 +1,181 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Sonatype, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sonatype, Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.aether.internal.ant.types; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.DataType; +import org.apache.tools.ant.types.Reference; + +/** + */ +public class Exclusion + extends DataType +{ + + private static final String WILDCARD = "*"; + + private String groupId; + + private String artifactId; + + private String classifier; + + private String extension; + + protected Exclusion getRef() + { + return (Exclusion) getCheckedRef(); + } + + public void validate( Task task ) + { + if ( isReference() ) + { + getRef().validate( task ); + } + else + { + if ( groupId == null && artifactId == null && classifier == null && extension == null ) + { + throw new BuildException( "You must specify at least one of " + + "'groupId', 'artifactId', 'classifier' or 'extension'" ); + } + } + } + + public void setRefid( Reference ref ) + { + if ( groupId != null || artifactId != null || extension != null || classifier != null ) + { + throw tooManyAttributes(); + } + super.setRefid( ref ); + } + + public String getGroupId() + { + if ( isReference() ) + { + return getRef().getGroupId(); + } + return ( groupId != null ) ? groupId : WILDCARD; + } + + public void setGroupId( String groupId ) + { + checkAttributesAllowed(); + if ( this.groupId != null ) + { + throw ambiguousCoords(); + } + this.groupId = groupId; + } + + public String getArtifactId() + { + if ( isReference() ) + { + return getRef().getArtifactId(); + } + return ( artifactId != null ) ? artifactId : WILDCARD; + } + + public void setArtifactId( String artifactId ) + { + checkAttributesAllowed(); + if ( this.artifactId != null ) + { + throw ambiguousCoords(); + } + this.artifactId = artifactId; + } + + public String getClassifier() + { + if ( isReference() ) + { + return getRef().getClassifier(); + } + return ( classifier != null ) ? classifier : WILDCARD; + } + + public void setClassifier( String classifier ) + { + checkAttributesAllowed(); + if ( this.classifier != null ) + { + throw ambiguousCoords(); + } + this.classifier = classifier; + } + + public String getExtension() + { + if ( isReference() ) + { + return getRef().getExtension(); + } + return ( extension != null ) ? extension : WILDCARD; + } + + public void setExtension( String extension ) + { + checkAttributesAllowed(); + if ( this.extension != null ) + { + throw ambiguousCoords(); + } + this.extension = extension; + } + + public void setCoords( String coords ) + { + checkAttributesAllowed(); + if ( groupId != null || artifactId != null || extension != null || classifier != null ) + { + throw ambiguousCoords(); + } + Pattern p = Pattern.compile( "([^: ]+)(:([^: ]+)(:([^: ]+)(:([^: ]*))?)?)?" ); + Matcher m = p.matcher( coords ); + if ( !m.matches() ) + { + throw new BuildException( "Bad exclusion coordinates '" + coords + + "', expected format is <groupId>[:<artifactId>[:<extension>[:<classifier>]]]" ); + } + groupId = m.group( 1 ); + artifactId = m.group( 3 ); + if ( artifactId == null ) + { + artifactId = "*"; + } + extension = m.group( 5 ); + if ( extension == null ) + { + extension = "*"; + } + classifier = m.group( 7 ); + if ( classifier == null ) + { + classifier = "*"; + } + } + + private BuildException ambiguousCoords() + { + return new BuildException( "You must not specify both 'coords' and " + + "('groupId', 'artifactId', 'extension', 'classifier')" ); + } + +} http://git-wip-us.apache.org/repos/asf/maven-aether/blob/1ec78d99/src/main/java/org/eclipse/aether/internal/ant/types/LocalRepository.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/eclipse/aether/internal/ant/types/LocalRepository.java b/src/main/java/org/eclipse/aether/internal/ant/types/LocalRepository.java new file mode 100644 index 0000000..f78516b --- /dev/null +++ b/src/main/java/org/eclipse/aether/internal/ant/types/LocalRepository.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Sonatype, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sonatype, Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.aether.internal.ant.types; + +import java.io.File; + +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.DataType; +import org.apache.tools.ant.types.Reference; +import org.eclipse.aether.internal.ant.AntRepoSys; + +/** + */ +public class LocalRepository + extends DataType +{ + + private final Task task; + + private File dir; + + public LocalRepository() + { + this( null ); + } + + public LocalRepository( Task task ) + { + this.task = task; + } + + @Override + public void setProject( Project project ) + { + super.setProject( project ); + + if ( task == null ) + { + AntRepoSys.getInstance( project ).setLocalRepository( this ); + } + } + + protected LocalRepository getRef() + { + return (LocalRepository) getCheckedRef(); + } + + public void setRefid( Reference ref ) + { + if ( dir != null ) + { + throw tooManyAttributes(); + } + super.setRefid( ref ); + } + + public File getDir() + { + if ( isReference() ) + { + return getRef().getDir(); + } + return dir; + } + + public void setDir( File dir ) + { + checkAttributesAllowed(); + this.dir = dir; + } + +} http://git-wip-us.apache.org/repos/asf/maven-aether/blob/1ec78d99/src/main/java/org/eclipse/aether/internal/ant/types/Mirror.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/eclipse/aether/internal/ant/types/Mirror.java b/src/main/java/org/eclipse/aether/internal/ant/types/Mirror.java new file mode 100644 index 0000000..d9850d2 --- /dev/null +++ b/src/main/java/org/eclipse/aether/internal/ant/types/Mirror.java @@ -0,0 +1,145 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Sonatype, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sonatype, Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.aether.internal.ant.types; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.types.DataType; +import org.apache.tools.ant.types.Reference; +import org.eclipse.aether.internal.ant.AntRepoSys; + +/** + */ +public class Mirror + extends DataType +{ + + private String id; + + private String url; + + private String type; + + private String mirrorOf; + + private Authentication authentication; + + @Override + public void setProject( Project project ) + { + super.setProject( project ); + + AntRepoSys.getInstance( project ).addMirror( this ); + } + + protected Mirror getRef() + { + return (Mirror) getCheckedRef(); + } + + public void setRefid( Reference ref ) + { + if ( id != null || url != null || mirrorOf != null || type != null ) + { + throw tooManyAttributes(); + } + super.setRefid( ref ); + } + + public String getId() + { + if ( isReference() ) + { + return getRef().getId(); + } + return id; + } + + public void setId( String id ) + { + this.id = id; + } + + public String getUrl() + { + if ( isReference() ) + { + return getRef().getUrl(); + } + return url; + } + + public void setUrl( String url ) + { + checkAttributesAllowed(); + this.url = url; + } + + public String getType() + { + if ( isReference() ) + { + return getRef().getType(); + } + return ( type != null ) ? type : "default"; + } + + public void setType( String type ) + { + checkAttributesAllowed(); + this.type = type; + } + + public String getMirrorOf() + { + if ( isReference() ) + { + return getRef().getMirrorOf(); + } + return mirrorOf; + } + + public void setMirrorOf( String mirrorOf ) + { + checkAttributesAllowed(); + this.mirrorOf = mirrorOf; + } + + public void addAuthentication( Authentication authentication ) + { + checkChildrenAllowed(); + if ( this.authentication != null ) + { + throw new BuildException( "You must not specify multiple <authentication> elements" ); + } + this.authentication = authentication; + } + + public Authentication getAuthentication() + { + if ( isReference() ) + { + getRef().getAuthentication(); + } + return authentication; + } + + public void setAuthRef( Reference ref ) + { + if ( authentication == null ) + { + authentication = new Authentication(); + authentication.setProject( getProject() ); + } + authentication.setRefid( ref ); + } + +} http://git-wip-us.apache.org/repos/asf/maven-aether/blob/1ec78d99/src/main/java/org/eclipse/aether/internal/ant/types/ModelValueExtractor.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/eclipse/aether/internal/ant/types/ModelValueExtractor.java b/src/main/java/org/eclipse/aether/internal/ant/types/ModelValueExtractor.java new file mode 100644 index 0000000..e6331ec --- /dev/null +++ b/src/main/java/org/eclipse/aether/internal/ant/types/ModelValueExtractor.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2010, 2014 Sonatype, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sonatype, Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.aether.internal.ant.types; + +import org.apache.maven.model.Model; +import org.apache.tools.ant.Project; +import org.codehaus.plexus.interpolation.reflection.ReflectionValueExtractor; + +/** + */ +class ModelValueExtractor +{ + + private static final String PREFIX_PROPERTIES = "properties."; + + private final String prefix; + + private final Project project; + + private final Model model; + + public ModelValueExtractor( String prefix, Model model, Project project ) + { + if ( model == null ) + { + throw new IllegalArgumentException( "reference to Maven POM has not been specified" ); + } + if ( project == null ) + { + throw new IllegalArgumentException( "reference to Ant project has not been specified" ); + } + if ( prefix == null || prefix.length() <= 0 ) + { + prefix = "pom."; + } + else if ( !prefix.endsWith( "." ) ) + { + prefix += '.'; + } + this.prefix = prefix; + this.model = model; + this.project = project; + } + + public Project getProject() + { + return project; + } + + public boolean isApplicable( String expression ) + { + return expression.startsWith( prefix ); + } + + public Object getValue( String expression ) + { + if ( expression.startsWith( prefix ) ) + { + String expr = expression.substring( prefix.length() ); + try + { + if ( expr.startsWith( PREFIX_PROPERTIES ) ) + { + String key = expr.substring( PREFIX_PROPERTIES.length() ); + return model.getProperties().getProperty( key ); + } + + return ReflectionValueExtractor.evaluate( expr, model, false ); + } + catch ( Exception e ) + { + project.log( "Could not retrieve '" + expression + "' from POM: " + e.getMessage(), e, Project.MSG_WARN ); + return null; + } + } + else + { + return null; + } + } + +}