001package org.apache.maven;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.io.File;
023import java.util.Arrays;
024import java.util.List;
025import java.util.Properties;
026
027import org.apache.maven.artifact.Artifact;
028import org.apache.maven.artifact.InvalidRepositoryException;
029import org.apache.maven.artifact.repository.ArtifactRepository;
030import org.apache.maven.execution.DefaultMavenExecutionRequest;
031import org.apache.maven.execution.DefaultMavenExecutionResult;
032import org.apache.maven.execution.MavenExecutionRequest;
033import org.apache.maven.execution.MavenSession;
034import org.apache.maven.model.Build;
035import org.apache.maven.model.Dependency;
036import org.apache.maven.model.Exclusion;
037import org.apache.maven.model.Model;
038import org.apache.maven.model.Plugin;
039import org.apache.maven.model.Repository;
040import org.apache.maven.model.RepositoryPolicy;
041import org.apache.maven.project.DefaultProjectBuildingRequest;
042import org.apache.maven.project.MavenProject;
043import org.apache.maven.project.ProjectBuildingRequest;
044import org.apache.maven.repository.RepositorySystem;
045import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
046import org.codehaus.plexus.ContainerConfiguration;
047import org.codehaus.plexus.PlexusTestCase;
048import org.codehaus.plexus.component.annotations.Requirement;
049import org.codehaus.plexus.util.FileUtils;
050import org.eclipse.aether.DefaultRepositorySystemSession;
051import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory;
052import org.eclipse.aether.repository.LocalRepository;
053
054public abstract class AbstractCoreMavenComponentTestCase
055    extends PlexusTestCase
056{
057    @Requirement
058    protected RepositorySystem repositorySystem;
059
060    @Requirement
061    protected org.apache.maven.project.ProjectBuilder projectBuilder;
062
063    protected void setUp()
064        throws Exception
065    {
066        repositorySystem = lookup( RepositorySystem.class );
067        projectBuilder = lookup( org.apache.maven.project.ProjectBuilder.class );
068    }
069
070    @Override
071    protected void tearDown()
072        throws Exception
073    {
074        repositorySystem = null;
075        projectBuilder = null;
076        super.tearDown();
077    }
078
079    abstract protected String getProjectsDirectory();
080
081    protected File getProject( String name )
082        throws Exception
083    {
084        File source = new File( new File( getBasedir(), getProjectsDirectory() ), name );
085        File target = new File( new File( getBasedir(), "target" ), name );
086        FileUtils.copyDirectoryStructureIfModified( source, target );
087        return new File( target, "pom.xml" );
088    }
089
090    /**
091     * We need to customize the standard Plexus container with the plugin discovery listener which
092     * is what looks for the META-INF/maven/plugin.xml resources that enter the system when a Maven
093     * plugin is loaded.
094     * 
095     * We also need to customize the Plexus container with a standard plugin discovery listener
096     * which is the MavenPluginCollector. When a Maven plugin is discovered the MavenPluginCollector
097     * collects the plugin descriptors which are found.
098     */
099    protected void customizeContainerConfiguration( ContainerConfiguration containerConfiguration )
100    {
101        containerConfiguration.setAutoWiring( true );
102    }
103
104    protected MavenExecutionRequest createMavenExecutionRequest( File pom )
105        throws Exception
106    {        
107        MavenExecutionRequest request = new DefaultMavenExecutionRequest()
108            .setPom( pom )
109            .setProjectPresent( true )
110            .setShowErrors( true )
111            .setPluginGroups( Arrays.asList( "org.apache.maven.plugins" ) )
112            .setLocalRepository( getLocalRepository() )
113            .setRemoteRepositories( getRemoteRepositories() )
114            .setPluginArtifactRepositories( getPluginArtifactRepositories() )
115            .setGoals( Arrays.asList( "package" ) );
116
117        return request;
118    }
119
120    // layer the creation of a project builder configuration with a request, but this will need to be
121    // a Maven subclass because we don't want to couple maven to the project builder which we need to
122    // separate.
123    protected MavenSession createMavenSession( File pom )
124        throws Exception        
125    {
126        return createMavenSession( pom, new Properties() );
127    }
128    
129    protected MavenSession createMavenSession( File pom, Properties executionProperties )
130        throws Exception
131    {
132        MavenExecutionRequest request = createMavenExecutionRequest( pom );
133        
134        ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest()
135            .setLocalRepository( request.getLocalRepository() )
136            .setRemoteRepositories( request.getRemoteRepositories() )
137            .setPluginArtifactRepositories( request.getPluginArtifactRepositories() )
138            .setSystemProperties( executionProperties );
139
140        MavenProject project = null;
141
142        if ( pom != null )
143        {
144            project = projectBuilder.build( pom, configuration ).getProject();
145        }
146        else
147        {
148            project = createStubMavenProject();
149            project.setRemoteArtifactRepositories( request.getRemoteRepositories() );
150            project.setPluginArtifactRepositories( request.getPluginArtifactRepositories() );
151        }
152
153        initRepoSession( configuration );
154
155        MavenSession session =
156            new MavenSession( getContainer(), configuration.getRepositorySession(), request,
157                              new DefaultMavenExecutionResult() );
158        session.setProjects( Arrays.asList( project ) );
159
160        return session;
161    }
162
163    protected void initRepoSession( ProjectBuildingRequest request )
164        throws Exception
165    {
166        File localRepoDir = new File( request.getLocalRepository().getBasedir() );
167        LocalRepository localRepo = new LocalRepository( localRepoDir );
168        DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
169        session.setLocalRepositoryManager( new SimpleLocalRepositoryManagerFactory().newInstance( session, localRepo ) );
170        request.setRepositorySession( session );
171    }
172
173    protected MavenProject createStubMavenProject()
174    {
175        Model model = new Model();
176        model.setGroupId( "org.apache.maven.test" );
177        model.setArtifactId( "maven-test" );
178        model.setVersion( "1.0" );
179        return new MavenProject( model );
180    }
181    
182    protected List<ArtifactRepository> getRemoteRepositories()
183        throws InvalidRepositoryException
184    {
185        File repoDir = new File( getBasedir(), "src/test/remote-repo" ).getAbsoluteFile();
186
187        RepositoryPolicy policy = new RepositoryPolicy();
188        policy.setEnabled( true );
189        policy.setChecksumPolicy( "ignore" );
190        policy.setUpdatePolicy( "always" );
191
192        Repository repository = new Repository();
193        repository.setId( RepositorySystem.DEFAULT_REMOTE_REPO_ID );
194        repository.setUrl( "file://" + repoDir.toURI().getPath() );
195        repository.setReleases( policy );
196        repository.setSnapshots( policy );
197
198        return Arrays.asList( repositorySystem.buildArtifactRepository( repository ) );
199    }
200
201    protected List<ArtifactRepository> getPluginArtifactRepositories()
202        throws InvalidRepositoryException
203    {
204        return getRemoteRepositories();
205    }
206
207    protected ArtifactRepository getLocalRepository()
208        throws InvalidRepositoryException
209    {
210        File repoDir = new File( getBasedir(), "target/local-repo" ).getAbsoluteFile();
211
212        return repositorySystem.createLocalRepository( repoDir );
213    }
214    
215    protected class ProjectBuilder
216    {
217        private MavenProject project;
218
219        public ProjectBuilder( MavenProject project )
220        {
221            this.project = project;
222        }
223
224        public ProjectBuilder( String groupId, String artifactId, String version )
225        {
226            Model model = new Model();
227            model.setModelVersion( "4.0.0" );
228            model.setGroupId( groupId );
229            model.setArtifactId( artifactId );
230            model.setVersion( version );  
231            model.setBuild(  new Build() );
232            project = new MavenProject( model );            
233        }
234        
235        public ProjectBuilder setGroupId( String groupId )
236        {
237            project.setGroupId( groupId );
238            return this;
239        }
240
241        public ProjectBuilder setArtifactId( String artifactId )
242        {
243            project.setArtifactId( artifactId );
244            return this;
245        }
246        
247        public ProjectBuilder setVersion( String version )
248        {
249            project.setVersion( version );
250            return this;
251        }
252        
253        // Dependencies
254        //
255        public ProjectBuilder addDependency( String groupId, String artifactId, String version, String scope )
256        {
257            return addDependency( groupId, artifactId, version, scope, (Exclusion)null );
258        }
259        
260        public ProjectBuilder addDependency( String groupId, String artifactId, String version, String scope, Exclusion exclusion )
261        {
262            return addDependency( groupId, artifactId, version, scope, null, exclusion );            
263        }
264
265        public ProjectBuilder addDependency( String groupId, String artifactId, String version, String scope, String systemPath )
266        {
267            return addDependency( groupId, artifactId, version, scope, systemPath, null );         
268        }
269        
270        public ProjectBuilder addDependency( String groupId, String artifactId, String version, String scope, String systemPath, Exclusion exclusion )
271        {
272            Dependency d = new Dependency();
273            d.setGroupId( groupId );
274            d.setArtifactId( artifactId );
275            d.setVersion( version );
276            d.setScope( scope );
277            
278            if ( systemPath != null && scope.equals(  Artifact.SCOPE_SYSTEM ) )
279            {
280                d.setSystemPath( systemPath );
281            }
282            
283            if ( exclusion != null )
284            {
285                d.addExclusion( exclusion );
286            }
287            
288            project.getDependencies().add( d );
289            
290            return this;
291        }
292        
293        // Plugins
294        //
295        public ProjectBuilder addPlugin( Plugin plugin )
296        {
297            project.getBuildPlugins().add( plugin );            
298            return this;
299        }
300        
301        public MavenProject get()
302        {
303            return project;
304        }        
305    }    
306    
307    protected class PluginBuilder
308    {
309        private Plugin plugin;
310        
311        public PluginBuilder( String groupId, String artifactId, String version )
312        {
313            plugin = new Plugin();
314            plugin.setGroupId( groupId );
315            plugin.setArtifactId( artifactId );
316            plugin.setVersion( version );                         
317        }
318                
319        // Dependencies
320        //
321        public PluginBuilder addDependency( String groupId, String artifactId, String version, String scope, Exclusion exclusion )
322        {
323            return addDependency( groupId, artifactId, version, scope, exclusion );            
324        }
325
326        public PluginBuilder addDependency( String groupId, String artifactId, String version, String scope, String systemPath )
327        {
328            return addDependency( groupId, artifactId, version, scope, systemPath, null );         
329        }
330        
331        public PluginBuilder addDependency( String groupId, String artifactId, String version, String scope, String systemPath, Exclusion exclusion )
332        {
333            Dependency d = new Dependency();
334            d.setGroupId( groupId );
335            d.setArtifactId( artifactId );
336            d.setVersion( version );
337            d.setScope( scope );
338            
339            if ( systemPath != null && scope.equals(  Artifact.SCOPE_SYSTEM ) )
340            {
341                d.setSystemPath( systemPath );
342            }
343            
344            if ( exclusion != null )
345            {
346                d.addExclusion( exclusion );
347            }
348            
349            plugin.getDependencies().add( d );
350            
351            return this;
352        }
353                
354        public Plugin get()
355        {
356            return plugin;
357        }        
358    }        
359}