001package org.apache.maven.script.ant;
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.ByteArrayOutputStream;
023import java.io.File;
024import java.io.IOException;
025import java.io.InputStreamReader;
026import java.io.PrintStream;
027import java.io.Reader;
028import java.net.URISyntaxException;
029import java.net.URL;
030import java.util.ArrayList;
031import java.util.Collections;
032import java.util.HashMap;
033import java.util.List;
034import java.util.Map;
035import junit.framework.TestCase;
036import org.apache.maven.artifact.Artifact;
037import org.apache.maven.execution.MavenSession;
038import org.apache.maven.model.Build;
039import org.apache.maven.model.Model;
040import org.apache.maven.plugin.MojoExecution;
041import org.apache.maven.plugin.MojoExecutionException;
042import org.apache.maven.plugin.descriptor.MojoDescriptor;
043import org.apache.maven.plugin.descriptor.PluginDescriptor;
044import org.apache.maven.plugin.descriptor.PluginDescriptorBuilder;
045import org.apache.maven.project.MavenProject;
046import org.apache.maven.project.path.PathTranslator;
047import org.apache.tools.ant.BuildEvent;
048import org.apache.tools.ant.BuildListener;
049import org.codehaus.plexus.archiver.ArchiverException;
050import org.codehaus.plexus.archiver.jar.JarArchiver;
051import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
052import org.codehaus.plexus.component.factory.ComponentInstantiationException;
053import org.codehaus.plexus.component.factory.ant.AntScriptInvoker;
054import org.codehaus.plexus.component.repository.ComponentRequirement;
055import org.codehaus.plexus.configuration.PlexusConfigurationException;
056import org.codehaus.plexus.logging.Logger;
057import org.codehaus.plexus.logging.console.ConsoleLogger;
058import org.codehaus.plexus.util.IOUtil;
059import static org.easymock.EasyMock.createMock;
060import static org.easymock.EasyMock.expect;
061import static org.easymock.EasyMock.replay;
062import static org.easymock.EasyMock.verify;
063
064public class AntMojoWrapperTest
065    extends TestCase
066{
067
068    public void test2xStylePlugin()
069        throws PlexusConfigurationException, IOException, ComponentInstantiationException, MojoExecutionException,
070        ComponentConfigurationException, ArchiverException, URISyntaxException
071    {
072        String pluginXml = "META-INF/maven/plugin-2.1.xml";
073
074        List<String> messages = run( pluginXml, true );
075
076        assertPresence( messages, "Unpacked Ant build scripts (in Maven build directory).", false );
077        assertPresence( messages, "Maven parameter expression evaluator for Ant properties.", false );
078        assertPresence( messages, "Maven standard project-based classpath references.", false );
079        assertPresence( messages, "Maven standard plugin-based classpath references.", false );
080        assertPresence( messages,
081                        "Maven project, session, mojo-execution, or path-translation parameter information is", false );
082        assertPresence( messages, "maven-script-ant < 2.1.0, or used maven-plugin-tools-ant < 2.2 during release",
083                        false );
084
085        assertPresence( messages, "path-is-missing", false );
086    }
087
088    public void test20StylePlugin()
089        throws PlexusConfigurationException, IOException, ComponentInstantiationException, MojoExecutionException,
090        ComponentConfigurationException, ArchiverException, URISyntaxException
091    {
092        String pluginXml = "META-INF/maven/plugin-2.0.xml";
093
094        List<String> messages = run( pluginXml, false );
095
096        assertPresence( messages, "Unpacked Ant build scripts (in Maven build directory).", true );
097        assertPresence( messages, "Maven parameter expression evaluator for Ant properties.", true );
098        assertPresence( messages, "Maven standard project-based classpath references.", true );
099        assertPresence( messages, "Maven standard plugin-based classpath references.", true );
100        assertPresence( messages,
101                        "Maven project, session, mojo-execution, or path-translation parameter information is", true );
102        assertPresence( messages, "maven-script-ant < 2.1.0, or used maven-plugin-tools-ant < 2.2 during release", true );
103
104        assertPresence( messages, "path-is-missing", true );
105    }
106
107    private void assertPresence( List<String> messages, String test, boolean shouldBePresent )
108    {
109        for ( String message : messages )
110        {
111            if ( message.contains( test ) )
112            {
113                if ( !shouldBePresent )
114                {
115                    fail( "Test string: '" + test + "' was found in output, but SHOULD NOT BE THERE." );
116                }
117                return;
118            }
119        }
120
121        if ( shouldBePresent )
122        {
123            fail( "Test string: '" + test + "' was NOT found in output, but SHOULD BE THERE." );
124        }
125    }
126
127    private List<String> run( String pluginXml, boolean includeImplied )
128        throws PlexusConfigurationException, IOException, ComponentInstantiationException, MojoExecutionException,
129        ComponentConfigurationException, ArchiverException, URISyntaxException
130    {
131        StackTraceElement stack = new Throwable().getStackTrace()[1];
132        System.out.println( "\n\nRunning: " + stack.getMethodName() + "\n\n" );
133
134        URL resource = Thread.currentThread().getContextClassLoader().getResource( pluginXml );
135
136        if ( resource == null )
137        {
138            fail( "plugin descriptor not found: '" + pluginXml + "'." );
139        }
140
141        Reader reader = null;
142        PluginDescriptor pd;
143        try
144        {
145            reader = new InputStreamReader( resource.openStream() );
146            pd = new PluginDescriptorBuilder().build( reader, pluginXml );
147            reader.close();
148            reader = null;
149        }
150        finally
151        {
152            IOUtil.close( reader );
153        }
154
155        Map<String, Object> config = new HashMap<String, Object>();
156        config.put( "basedir", new File( "." ).getAbsoluteFile() );
157        config.put( "messageLevel", "info" );
158
159        MojoDescriptor md = pd.getMojo( "test" );
160
161        AntMojoWrapper wrapper =
162            new AntMojoWrapper( new AntScriptInvoker( md, Thread.currentThread().getContextClassLoader() ) );
163
164        wrapper.enableLogging( new ConsoleLogger( Logger.LEVEL_DEBUG, "test" ) );
165
166        Artifact artifact = createMock( Artifact.class );
167        PathTranslator pt = createMock( PathTranslator.class );
168
169        if ( includeImplied )
170        {
171            // TODO As of JDK 7, replace with Paths.get( resource.toURI() ).toFile()
172            File pluginXmlFile = new File( resource.toURI() );
173
174            File jarFile = File.createTempFile( "AntMojoWrapperTest.", ".test.jar" );
175            jarFile.deleteOnExit();
176
177            JarArchiver archiver = new JarArchiver();
178            archiver.enableLogging( new ConsoleLogger( Logger.LEVEL_ERROR, "archiver" ) );
179            archiver.setDestFile( jarFile );
180            archiver.addFile( pluginXmlFile, pluginXml );
181            archiver.createArchive();
182
183            expect( artifact.getFile() ).andReturn( jarFile ).anyTimes();
184            expect( artifact.getGroupId() ).andReturn( "groupId" ).anyTimes();
185            expect( artifact.getArtifactId() ).andReturn( "artifactId" ).anyTimes();
186            expect( artifact.getVersion() ).andReturn( "1" ).anyTimes();
187            expect( artifact.getId() ).andReturn( "groupId:artifactId:jar:1" ).anyTimes();
188            expect( artifact.getClassifier() ).andReturn( null ).anyTimes();
189
190            Model model = new Model();
191
192            Build build = new Build();
193            build.setDirectory( "target" );
194
195            model.setBuild( build );
196
197            MavenProject project = new MavenProject( model );
198            project.setFile( new File( "pom.xml" ).getAbsoluteFile() );
199
200            replay( artifact, pt );
201
202            pd.setPluginArtifact( artifact );
203            pd.setArtifacts( Collections.singletonList( artifact ) );
204
205            config.put( "project", project );
206            config.put( "session", new MavenSession( null, null, null, null, null, null, null, null, null, null ) );
207            config.put( "mojoExecution", new MojoExecution( md ) );
208
209            ComponentRequirement cr = new ComponentRequirement();
210            cr.setRole( PathTranslator.class.getName() );
211
212            wrapper.addComponentRequirement( cr, pt );
213        }
214
215        wrapper.setComponentConfiguration( config );
216
217        TestBuildListener tbl = new TestBuildListener();
218        wrapper.getAntProject().addBuildListener( tbl );
219        
220        PrintStream oldOut = System.out;
221        
222        ByteArrayOutputStream baos = new ByteArrayOutputStream();
223        try
224        {
225            System.setOut( new PrintStream( baos ) );
226
227            wrapper.execute();
228        }
229        finally
230        {
231            System.setOut( oldOut );
232        }
233
234        System.out.println( "\n\n" + stack.getMethodName() + " executed; verifying...\n\n" );
235
236        if ( includeImplied )
237        {
238            verify( artifact, pt );
239        }
240
241        List<String> messages = new ArrayList<String>();
242        if ( !tbl.messages.isEmpty() )
243        {
244            messages.addAll( tbl.messages );
245        }
246        
247        messages.add( new String( baos.toByteArray() ) );
248        
249        return messages;
250    }
251
252    private static final class TestBuildListener
253        implements BuildListener
254    {
255        private List<String> messages = new ArrayList<String>();
256
257        public void buildFinished( BuildEvent arg0 )
258        {
259        }
260
261        public void buildStarted( BuildEvent arg0 )
262        {
263        }
264
265        public void messageLogged( BuildEvent event )
266        {
267            messages.add( event.getMessage() );
268        }
269
270        public void targetFinished( BuildEvent arg0 )
271        {
272        }
273
274        public void targetStarted( BuildEvent arg0 )
275        {
276        }
277
278        public void taskFinished( BuildEvent arg0 )
279        {
280        }
281
282        public void taskStarted( BuildEvent arg0 )
283        {
284        }
285    };
286
287}