1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.plugin.eclipse.it;
20  
21  import java.io.File;
22  import java.io.FileNotFoundException;
23  import java.io.FileReader;
24  import java.io.IOException;
25  import java.util.ArrayList;
26  import java.util.List;
27  import java.util.Properties;
28  
29  import org.apache.maven.plugin.MojoExecutionException;
30  import org.apache.maven.plugin.eclipse.TempEclipseWorkspace;
31  import org.codehaus.plexus.util.xml.Xpp3Dom;
32  import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
33  import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
34  
35  /**
36   * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
37   * @author <a href="mailto:fgiust@apache.org">Fabrizio Giustina</a>
38   * @version $Id: EclipsePluginIT.java 779829 2009-05-29 03:41:15Z baerrach $
39   */
40  public class EclipsePluginIT
41      extends AbstractEclipsePluginIT
42  {
43      protected void setUp()
44          throws Exception
45      {
46          super.setUp();
47      }
48  
49      /**
50       * Assumes that unit tests (ReadWorkspaceLocationsTest) have been run so that .location files have been created
51       * correctly.
52       */
53      public void testDynamicWorkspaceLookup()
54          throws Exception
55      {
56          File basedir = new File(TempEclipseWorkspace.getFixtureEclipseDynamicWorkspace().workspaceLocation, "project-Z");
57          testProject( basedir );
58      }
59  
60      public void testProject01()
61          throws Exception
62      {
63          testProject( "project-01" );
64      }
65  
66      public void testProject02()
67          throws Exception
68      {
69          testProject( "project-02" );
70      }
71  
72      public void testProject03()
73          throws Exception
74      {
75          testProject( "project-03" );
76      }
77  
78      public void testProject04()
79          throws Exception
80      {
81          testProject( "project-04" );
82      }
83  
84      public void testProject05()
85          throws Exception
86      {
87          testProject( "project-05" );
88      }
89  
90      public void testProject06()
91          throws Exception
92      {
93          testProject( "project-06" );
94      }
95  
96      /**
97       * @throws Exception
98       */
99      public void testProject07()
100         throws Exception
101     {
102         // Fails because of MECLIPSE-367
103         testProject( "project-07" );
104     }
105 
106     public void testProject08()
107         throws Exception
108     {
109         testProject( "project-08" );
110     }
111 
112     /**
113      * Tests with <code>outputDirectory</code> and <code>outputDir</code>
114      * 
115      * @throws Exception
116      */
117     public void testProject09()
118         throws Exception
119     {
120         testProject( "project-09" );
121     }
122 
123     public void testProject10()
124         throws Exception
125     {
126         testProject( "project-10" );
127     }
128 
129     public void testProject11()
130         throws Exception
131     {
132         testProject( "project-11" );
133     }
134 
135     /**
136      * Ear packaging
137      * 
138      * @throws Exception any exception thrown during test
139      */
140     public void testProject12()
141         throws Exception
142     {
143         testProject( "project-12" );
144     }
145 
146     /**
147      * Dependency range - MECLIPSE-96
148      * 
149      * @throws Exception any exception thrown during test
150      */
151     public void testProject13()
152         throws Exception
153     {
154         testProject( "project-13" );
155     }
156 
157     /**
158      * Additional natures and builders - MECLIPSE-64
159      * 
160      * @throws Exception any exception thrown during test
161      */
162     public void testProject14()
163         throws Exception
164     {
165         testProject( "project-14" );
166     }
167 
168     /**
169      * <code>outputDirectory</code> parameter - MECLIPSE-11
170      * 
171      * @throws Exception any exception thrown during test
172      */
173     public void testProject15()
174         throws Exception
175     {
176         Properties props = new Properties();
177         props.put( "outputDirectory", "bin" );
178         testProject( "project-15", props, "clean", "eclipse" );
179     }
180 
181     /**
182      * UTF8 encoding - MECLIPSE-56
183      * 
184      * @throws Exception any exception thrown during test
185      */
186     public void testProject16()
187         throws Exception
188     {
189         // failing with maven < 2.0.8 due to MNG-2025
190         testProject( "project-16" );
191     }
192 
193     /**
194      * ISO-8859-15 encoding - MECLIPSE-56
195      * 
196      * @throws Exception any exception thrown during test
197      */
198     public void testProject17()
199         throws Exception
200     {
201         // failing with maven < 2.0.8 due to MNG-2025
202         testProject( "project-17" );
203     }
204 
205     /**
206      * relative location of system dependencies - MECLIPSE-89
207      * 
208      * @throws Exception any exception thrown during test
209      */
210     public void testProject18()
211         throws Exception
212     {
213         testProject( "project-18" );
214     }
215 
216     /**
217      * Resource targetPath is relative to the project's output directory - MECLIPSE-77
218      * 
219      * @throws Exception any exception thrown during test
220      */
221     public void testProject19()
222         throws Exception
223     {
224         testProject( "project-19" );
225     }
226 
227     /**
228      * WTP 1.5 changes in wtpmodules.
229      * 
230      * @throws Exception any exception thrown during test
231      */
232     public void testProject20()
233         throws Exception
234     {
235         testProject( "project-20" );
236     }
237 
238     /**
239      * PDE support.
240      * 
241      * @throws Exception any exception thrown during test
242      */
243     public void testProject21()
244         throws Exception
245     {
246         testProject( "project-21" );
247     }
248 
249     /**
250      * PDE support using eclipse-plugin packaging.
251      * 
252      * @throws Exception any exception thrown during test
253      */
254     public void testProject22()
255         throws Exception
256     {
257         testProject( "project-22" );
258     }
259 
260     /**
261      * Additional config files using "additionalConfig" property.
262      * 
263      * @throws Exception any exception thrown during test
264      */
265     public void testProject23()
266         throws Exception
267     {
268         testProject( "project-23" );
269     }
270 
271     /**
272      * Test rewriting of OSGI manifest files.
273      * 
274      * @throws Exception any exception thrown during test
275      */
276     public void testProject24()
277         throws Exception
278     {
279         testProject( "project-24" );
280     }
281 
282     /**
283      * Test source exclude/include.
284      * 
285      * @throws Exception any exception thrown during test
286      */
287     public void testProject25()
288         throws Exception
289     {
290         testProject( "project-25" );
291     }
292 
293     /**
294      * Test different compiler settings for test sources.
295      * 
296      * @throws Exception any exception thrown during test
297      */
298     public void testProject26()
299         throws Exception
300     {
301         testProject( "project-26" );
302     }
303 
304     /**
305      * Test additional project facets specified.
306      * 
307      * @throws Exception any exception thrown during test
308      */
309     public void testProject27()
310         throws Exception
311     {
312         testProject( "project-27" );
313     }
314 
315     /**
316      * MECLIPSE-241 : Compiler settings from parent project aren't used in wtp facet.
317      * 
318      * @throws Exception any exception thrown during test
319      */
320     public void testProject28()
321         throws Exception
322     {
323         testProject( "project-28/module-1" );
324     }
325 
326     /**
327      * MECLIPSE-198 : EJB version is not resloved
328      * 
329      * @throws Exception any exception thrown during test
330      */
331     public void testProject29()
332         throws Exception
333     {
334         testProject( "project-29" );
335     }
336 
337     /**
338      * MECLIPSE-108 : .wtpmodules with version 2.4 for javax.servlet:servlet-api:2.3
339      * 
340      * @throws Exception any exception thrown during test
341      */
342     public void testProject30()
343         throws Exception
344     {
345         testProject( "project-30" );
346     }
347 
348     /**
349      * MECLIPSE-185 : plugin doesn't fail when dependencies are missing
350      * 
351      * @throws Exception any exception thrown during test
352      */
353     public void testProject31()
354         throws Exception
355     {
356         try
357         {
358             testProject( "project-31" );
359 
360             // TODO: disabling this test for now. See comments in MECLIPSE-185 - Bfox
361             // fail("Expected to receive a MojoExecutionException");
362         }
363         catch ( MojoExecutionException e )
364         {
365             // expected exception here
366         }
367     }
368 
369     /**
370      * MECLIPSE-109 : .component wb-resource source path incorrect for ear packaging
371      * 
372      * @throws Exception any exception thrown during test
373      */
374     public void testProject32()
375         throws Exception
376     {
377         testProject( "project-32" );
378     }
379 
380     /**
381      * MECLIPSE-287 : dependencies with and without classifiers. MECLIPSE-151 : test jar source attachments.
382      * MECLIPSE-367 : Dependency to artifact with classifier tests not distinguished from the regular artifact
383      * 
384      * @throws Exception any exception thrown during test
385      */
386     public void testProject33()
387         throws Exception
388     {
389         testProject( "project-33" );
390     }
391 
392     public void testProject34()
393         throws Exception
394     {
395         testProject( "project-34" );
396     }
397 
398     public void testProject35()
399         throws Exception
400     {
401         testProject( "project-35" );
402 
403         File basedir = getTestFile( "target/test-classes/projects/project-35" );
404 
405         checkContextRoot( basedir, "multymodule-war", "multymodule-ear", "/somethingVeryDifferent" );
406 
407         FileReader reader =
408             new FileReader( new File( basedir, "multymodule-war/.settings/org.eclipse.wst.common.component" ) );
409         Xpp3Dom warComponent = Xpp3DomBuilder.build( reader );
410         Xpp3Dom[] dependentModules = warComponent.getChild( "wb-module" ).getChildren( "dependent-module" );
411         assertEquals( 2, dependentModules.length );
412         for ( int index = 0; index < dependentModules.length; index++ )
413         {
414             assertEquals( "/WEB-INF/lib", dependentModules[index].getAttribute( "deploy-path" ) );
415         }
416 
417         reader = new FileReader( new File( basedir, "multymodule-ear/.settings/org.eclipse.wst.common.component" ) );
418         Xpp3Dom earComponent = Xpp3DomBuilder.build( reader );
419         dependentModules = earComponent.getChild( "wb-module" ).getChildren( "dependent-module" );
420         assertEquals( 2, dependentModules.length );
421         for ( int index = 0; index < dependentModules.length; index++ )
422         {
423             if ( dependentModules[index].getAttribute( "archiveName" ).endsWith( "war" ) )
424             {
425                 assertEquals( "/", dependentModules[index].getAttribute( "deploy-path" ) );
426                 assertTrue( !dependentModules[index].getAttribute( "archiveName" ).startsWith( ".." ) );
427             }
428             else
429             {
430                 assertEquals( "lib", dependentModules[index].getAttribute( "deploy-path" ) );
431                 assertTrue( dependentModules[index].getAttribute( "archiveName" ).startsWith( ".." ) );
432             }
433         }
434     }
435 
436     public void testProject36()
437         throws Exception
438     {
439         // Install artefacts
440         File basedir = getTestFile( "target/test-classes/projects/project-36" );
441         File pom = new File( basedir, "pom.xml" );
442         List goals = new ArrayList();
443         goals.add( "install" );
444         executeMaven( pom, new Properties(), goals );
445         // Test
446         testProject( "project-36" );
447     }
448 
449     public void testProject37()
450         throws Exception
451     {
452         testProject( "project-37" );
453     }
454 
455     /**
456      * MECLIPSE-56 : problem with encoding of non-ascii characters in pom.xml
457      */
458     public void testMECLIPSE_56_encoding()
459         throws Exception
460     {
461         testProject( "MECLIPSE-56_encoding" );
462     }
463 
464     public void testProject38()
465         throws Exception
466     {
467         testProject( "project-38" );
468     }
469 
470     public void testProject39()
471         throws Exception
472     {
473         checkJRESettingsWithEclipseWorkspace( "project-39", TempEclipseWorkspace.getFixtureEclipseWithDefault13(),
474                                               "", null );
475         checkJRESettingsWithEclipseWorkspace( "project-39", TempEclipseWorkspace.getFixtureEclipseWithDefault15(),
476                                               "J2SE-1.3", null );
477         checkJRESettingsWithEclipseWorkspace( "project-39", TempEclipseWorkspace.getFixtureEclipseWorkspaceWithRad7Default14(),
478                                               "J2SE-1.3", null );
479     }
480 
481     public void testProject40()
482         throws Exception
483     {
484         String jre131 = new java.io.File( "target/test-classes/eclipse/dummyJDK/1.3.1/bin/javac" ).getCanonicalPath();
485         checkJRESettingsWithEclipseWorkspace( "project-40", TempEclipseWorkspace.getFixtureEclipseWithDefault13(),
486                                               "JVM 1.3.1", jre131 );
487         checkJRESettingsWithEclipseWorkspace( "project-40", TempEclipseWorkspace.getFixtureEclipseWithDefault15(),
488                                               "JVM 1.3.1", jre131 );
489         checkJRESettingsWithEclipseWorkspace( "project-40", TempEclipseWorkspace.getFixtureEclipseWorkspaceWithRad7Default14(), "",
490                                               jre131 );
491     }
492 
493     public void testProject41()
494         throws Exception
495     {
496         TempEclipseWorkspace rad7 = TempEclipseWorkspace.getFixtureEclipseWorkspaceWithRad7Default14();
497         Properties properties = new Properties();
498         properties.setProperty( "eclipse.workspace", rad7.workspaceLocation.getCanonicalPath() );
499         testProject( "project-41", properties, "clean", "eclipse" );
500 
501     }
502 
503     public void testProject42()
504         throws Exception
505     {
506         TempEclipseWorkspace rad7 = TempEclipseWorkspace.getFixtureEclipseWorkspaceWithRad7Default14();
507         Properties properties = new Properties();
508         properties.setProperty( "eclipse.workspace", rad7.workspaceLocation.getCanonicalPath() );
509         testProject( "project-42", properties, "clean", "eclipse" );
510 
511     }
512 
513     /**
514      * [MECLIPSE-79]
515      * 
516      * @since 2.5
517      * @throws Exception
518      */
519     public void testProject43()
520         throws Exception
521     {
522         testProject( "project-43" );
523     }
524 
525     /**
526      * [MECLIPSE-219]
527      * 
528      * @since 2.5
529      * @throws Exception
530      */
531     public void testProject44()
532         throws Exception
533     {
534         testProject( "project-44" );
535     }
536 
537     /**
538      * [MECLIPSE-379] When downloading sources and javadocs dependency classifier is not respected.
539      * 
540      * @since 2.5
541      * @throws Exception
542      */
543     public void testProject45()
544         throws Exception
545     {
546         testProject( "project-45" );
547     }
548     
549     /**
550      * Test not available marker file is created for sources/javadocs.
551      * biz.aQute:bndlib:0.0.145 does not have sources or javadocs.
552      * 
553      * @throws Exception
554      */
555     public void testProject46()
556         throws Exception
557     {
558         testProject( "project-46" );
559         assertNotAvailableMarkerFileExists( "biz.aQute", "bndlib", "0.0.145", null, "sources" );
560         assertNotAvailableMarkerFileExists( "biz.aQute", "bndlib", "0.0.145", null, "javadoc" );
561     }
562     
563     /**
564      * Test not available marker file is created for sources/javadocs.
565      * commons-lang:commons-lang:1.0 does not have sources but does have javadocs.
566      * 
567      * @throws Exception
568      */
569     public void testProject47()
570         throws Exception
571     {
572         testProject( "project-47" );
573         assertNotAvailableMarkerFileExists( "commons-lang", "commons-lang", "1.0", null, "sources" );
574         assertNotAvailableMarkerFileDoesNotExist( "commons-lang", "commons-lang", "1.0", null, "javadoc" );
575     }
576     
577     /**
578      * Test not available marker file is created for sources/javadocs.
579      * does-not-exist:does-not-exist:666 doesn't exist so no markers should be created.
580      * 
581      * @throws Exception
582      */
583     public void testProject48()
584         throws Exception
585     {
586         testProject( "project-48" );
587         assertNotAvailableMarkerFileDoesNotExist( "does-not-exist", "does-not-exist", "666", null, "sources" );
588         assertNotAvailableMarkerFileDoesNotExist( "does-not-exist", "does-not-exist", "666", null, "javadoc" );
589     }    
590 
591     /**
592      * Test forceRecheck
593      * 
594      * @throws Exception
595      */
596     public void testProject49()
597         throws Exception
598     {
599         File notAvailableMarkerFile =
600             getNotAvailableMarkerFile( "commons-lang", "commons-lang", "2.4", null, "sources" );
601         notAvailableMarkerFile.getParentFile().mkdirs();
602         notAvailableMarkerFile.createNewFile();
603         getNotAvailableMarkerFile( "commons-lang", "commons-lang", "2.4", null, "javadoc" ).createNewFile();
604 
605         testProject( "project-49" );
606         assertNotAvailableMarkerFileDoesNotExist( "commons-lang", "commons-lang", "2.4", null, "sources" );
607         assertNotAvailableMarkerFileDoesNotExist( "commons-lang", "commons-lang", "2.4", null, "javadoc" );
608     }   
609 
610 
611     /**
612      * [MECLIPSE-415] settings are stored in wrong directory if project is not in the workspace.
613      * 
614      * @throws Exception
615      */
616     public void testProject50MECLIPSE415()
617         throws Exception
618     {
619         testProject( "project-50-MECLIPSE-415" );
620     }    
621 
622     /**
623      * [MECLIPSE-415] settings are stored in wrong directory if project is not in the workspace.
624      * 
625      * @throws Exception
626      */
627     public void testProject51MECLIPSE415()
628         throws Exception
629     {
630         testProject( "project-51-MECLIPSE-415" );
631     }    
632     
633     /**
634      * [MECLIPSE-104] Add the ability to specify source exclusions
635      * 
636      * @throws Exception
637      */
638     public void testProject52MECLIPSE104()
639         throws Exception
640     {
641         testProject( "project-52-MECLIPSE-104" );
642     }
643     
644     /**
645      * [MECLIPSE-551] Source directory and resource directory are the same
646      * 
647      * @throws Exception
648      */
649     public void testProject53MECLIPS551()
650         throws Exception
651     {
652         testProject( "project-53-MECLIPSE-551" );
653     }
654 
655     public void testJeeSimple()
656         throws Exception
657     {
658         // Install artefacts
659         File basedir = getTestFile( "target/test-classes/projects/j2ee-simple" );
660         File pom = new File( basedir, "pom.xml" );
661         List goals = new ArrayList();
662         goals.add( "install" );
663         executeMaven( pom, new Properties(), goals );
664         // Test project
665         testProject( "j2ee-simple" );
666         checkContextRoot( basedir, "servlets/servlet", "ear", "servlet" );
667 
668     }
669 
670     private void checkContextRoot( File basedir, String warModule, String earModule, String expectedContextRoot )
671         throws FileNotFoundException, XmlPullParserException, IOException
672     {
673         FileReader reader =
674             new FileReader( new File( basedir, warModule + "/.settings/org.eclipse.wst.common.component" ) );
675         Xpp3Dom warComponent = Xpp3DomBuilder.build( reader );
676         Xpp3Dom[] properties = warComponent.getChild( "wb-module" ).getChildren( "property" );
677         boolean contextRootAvaliable = false;
678         for ( int index = 0; index < properties.length; index++ )
679         {
680             if ( properties[index].getAttribute( "name" ).equals( "context-root" ) )
681             {
682                 assertEquals( "Context root detection in org.eclipse.wst.common.component", expectedContextRoot,
683                               properties[index].getAttribute( "value" ) );
684                 contextRootAvaliable = true;
685             }
686         }
687         assertTrue( "there must be a context root here", contextRootAvaliable );
688 
689         reader = new FileReader( new File( basedir, earModule + "/target/eclipseEar/META-INF/application.xml" ) );
690         Xpp3Dom generatedApplicationXML = Xpp3DomBuilder.build( reader );
691 
692         Xpp3Dom[] modules = generatedApplicationXML.getChildren( "module" );
693         for ( int index = 0; index < modules.length; index++ )
694         {
695             if ( modules[index].getChild( "web" ) != null )
696             {
697                 assertEquals( "Context root detection in target/eclipseEar/META-INF/application.xml",
698                               expectedContextRoot,
699                               modules[index].getChild( "web" ).getChild( "context-root" ).getValue() );
700             }
701         }
702     }
703 
704     private void checkJRESettingsWithEclipseWorkspace( String project, TempEclipseWorkspace workspace,
705                                                        String expectedJRE, String jreExec )
706         throws Exception
707     {
708         Properties properties = new Properties();
709         properties.setProperty( "eclipse.workspace", workspace.workspaceLocation.getCanonicalPath() );
710         if ( jreExec != null )
711         {
712             properties.setProperty( "maven.compiler.executable", jreExec );
713         }
714         testProject( project, properties, "clean", "eclipse" );
715 
716         Xpp3Dom classpath =
717             Xpp3DomBuilder.build( new FileReader( getTestFile( "target/test-classes/projects/" + project
718                 + "/.classpath" ) ) );
719 
720         boolean foundDirectCompileAsProject = false;
721         String foundJRE = "";
722 
723         Xpp3Dom[] classpathentries = classpath.getChildren( "classpathentry" );
724         for ( int index = 0; index < classpathentries.length; index++ )
725         {
726             if ( "/direct-compile".equals( classpathentries[index].getAttribute( "path" ) ) )
727             {
728                 foundDirectCompileAsProject = true;
729             }
730             String path = classpathentries[index].getAttribute( "path" );
731             if ( "con".equals( classpathentries[index].getAttribute( "kind" ) ) && path.lastIndexOf( '/' ) > 0 )
732             {
733                 foundJRE = path.substring( path.lastIndexOf( '/' ) + 1 );
734             }
735         }
736         assertTrue( foundDirectCompileAsProject );
737         assertEquals( expectedJRE, foundJRE );
738     }
739 
740 }