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