View Javadoc

1   package org.apache.maven.plugin.eclipse.writers.wtp;
2   
3   import java.io.File;
4   import java.io.FileInputStream;
5   import java.io.FileNotFoundException;
6   import java.io.FileOutputStream;
7   import java.io.IOException;
8   import java.io.InputStreamReader;
9   import java.io.OutputStreamWriter;
10  import java.io.Reader;
11  import java.io.Writer;
12  
13  import org.apache.maven.artifact.repository.ArtifactRepository;
14  import org.apache.maven.plugin.MojoExecutionException;
15  import org.apache.maven.plugin.eclipse.Constants;
16  import org.apache.maven.plugin.eclipse.EclipseSourceDir;
17  import org.apache.maven.plugin.ide.IdeDependency;
18  import org.apache.maven.plugin.ide.IdeUtils;
19  import org.apache.maven.plugin.ide.JeeUtils;
20  import org.codehaus.plexus.util.FileUtils;
21  import org.codehaus.plexus.util.IOUtil;
22  import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
23  import org.codehaus.plexus.util.xml.XMLWriter;
24  import org.codehaus.plexus.util.xml.Xpp3Dom;
25  import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
26  import org.codehaus.plexus.util.xml.Xpp3DomWriter;
27  
28  /**
29   * This writer creates the application.xml and the .modulemaps files for RAD6 the the META-INF directory in the project
30   * root. this is where RAD6 requires the files to be. These will be independent of the real application.xml witch will
31   * be generated the stad. maven way.
32   * 
33   * @author <a href="mailto:nir@cfc.at">Richard van Nieuwenhoven</a>
34   */
35  public class EclipseWtpApplicationXMLWriter
36      extends AbstractWtpResourceWriter
37  {
38  
39      private static final String APPLICATION_XML_APPLICATION = "application";
40  
41      private static final String APPLICATION_XML_CONTEXT_ROOT = "context-root";
42  
43      private static final String APPLICATION_XML_DESCRIPTION = "description";
44  
45      private static final String APPLICATION_XML_DISPLAY_NAME = "display-name";
46  
47      private static final String APPLICATION_XML_FILENAME = "application.xml";
48  
49      private static final String APPLICATION_XML_MODULE = "module";
50  
51      private static final String APPLICATION_XML_WEB = "web";
52  
53      private static final String APPLICATION_XML_WEB_URI = "web-uri";
54  
55      private static final String HREF = "href";
56  
57      private static final String ID = "id";
58  
59      private static final String MODULEMAP_EARPROJECT_MAP = "modulemap:EARProjectMap";
60  
61      private static final String MODULEMAPS_APPLICATION_EJB_MODULE = "application:EjbModule";
62  
63      private static final String MODULEMAPS_APPLICATION_WEB_MODULE = "application:WebModule";
64  
65      private static final String MODULEMAPS_FILENAME = ".modulemaps";
66  
67      private static final String MODULEMAPS_MAPPINGS = "mappings";
68  
69      private static final String MODULEMAPS_PROJECT_NAME = "projectName";
70  
71      private static final String MODULEMAPS_UTILITY_JARMAPPINGS = "utilityJARMappings";
72  
73      private static final String URI = "uri";
74  
75      private static final String VERSION = "version";
76  
77      private static final String XMI_ID = "xmi:id";
78  
79      private static final String XMI_TYPE = "xmi:type";
80  
81      private static final String XMI_VERSION = "xmi:version";
82  
83      private static final String XMLNS = "xmlns";
84  
85      private static final String XMLNS_APPLICATION = "xmlns:application";
86  
87      private static final String XMLNS_MODULEMAP = "xmlns:modulemap";
88  
89      private static final String XMLNS_SCHEMA_LOCATION = "xmlns:schemaLocation";
90  
91      private static final String XSI_SCHEMA_LOCATION = "xsi:schemaLocation";
92  
93      private static final String XMLNS_XMI = "xmlns:xmi";
94  
95      private static final String XMLNS_XSI = "xmlns:xsi";
96  
97      private Xpp3Dom[] applicationXmlDomChildren;
98  
99      private Xpp3Dom[] modulemapsXmlDomChildren;
100 
101     private Xpp3Dom[] webModulesFromPoms;
102 
103     /**
104      * write the application.xml and the .modulemaps file to the META-INF directory.
105      * 
106      * @see AbstractWtpResourceWriter#write(EclipseSourceDir[], ArtifactRepository, File)
107      * @throws MojoExecutionException when writing the config files was not possible
108      */
109     public void write()
110         throws MojoExecutionException
111     {
112         String packaging = this.config.getProject().getPackaging();
113         if ( Constants.PROJECT_PACKAGING_EAR.equalsIgnoreCase( packaging ) )
114         {
115             File applicationXmlFile =
116                 new File( this.config.getEclipseProjectDirectory(), "target" + File.separator + "eclipseEar"
117                     + File.separator + "META-INF" + File.separator
118                     + EclipseWtpApplicationXMLWriter.APPLICATION_XML_FILENAME );
119             // create the directory structiure for eclipse deployment
120             applicationXmlFile.getParentFile().mkdirs();
121             // copy all deployment files to the eclipse deployment
122             copyApplicationFiles();
123             // delete any existing application.xml so that it will be
124             // overwritten.
125             applicationXmlFile.delete();
126 
127             Xpp3Dom applicationXmlDom = readXMLFile( applicationXmlFile );
128             if ( applicationXmlDom == null )
129             {
130                 applicationXmlDom = createNewApplicationXml();
131             }
132             this.applicationXmlDomChildren =
133                 applicationXmlDom.getChildren( EclipseWtpApplicationXMLWriter.APPLICATION_XML_MODULE );
134 
135             File modulemapsXmlFile =
136                 new File( this.config.getEclipseProjectDirectory(), "target" + File.separator + "eclipseEar"
137                     + File.separator + "META-INF" + File.separator + EclipseWtpApplicationXMLWriter.MODULEMAPS_FILENAME );
138             Xpp3Dom modulemapsXmlDom = readXMLFile( modulemapsXmlFile );
139             if ( modulemapsXmlDom == null )
140             {
141                 modulemapsXmlDom = createNewModulemaps();
142             }
143             this.modulemapsXmlDomChildren = modulemapsXmlDom.getChildren();
144 
145             this.webModulesFromPoms =
146                 IdeUtils.getPluginConfigurationDom( config.getProject(), JeeUtils.ARTIFACT_MAVEN_EAR_PLUGIN,
147                                                     new String[] { "modules", "webModule" } );
148 
149             IdeDependency[] deps = this.config.getDepsOrdered();
150             for ( int index = 0; index < deps.length; index++ )
151             {
152                 updateApplicationXml( applicationXmlDom, modulemapsXmlDom, deps[index] );
153             }
154 
155             removeUnusedEntries( applicationXmlDom, modulemapsXmlDom );
156 
157             writePrettyXmlFile( applicationXmlFile, applicationXmlDom );
158             writePrettyXmlFile( modulemapsXmlFile, modulemapsXmlDom );
159         }
160     }
161 
162     /**
163      * Copy all files from application directory to the target eclipseEar directory.
164      * 
165      * @throws MojoExecutionException wenn an error occures during file copieing
166      */
167     private void copyApplicationFiles()
168         throws MojoExecutionException
169     {
170         try
171         {
172             File applicationDirectory =
173                 new File( this.config.getEclipseProjectDirectory(), "src" + File.separator + "main" + File.separator
174                     + "application" );
175             File eclipseApplicationDirectory =
176                 new File( this.config.getEclipseProjectDirectory(), "target" + File.separator + "eclipseEar" );
177             copyDirectoryStructure( applicationDirectory, eclipseApplicationDirectory );
178         }
179         catch ( IOException e )
180         {
181             throw new MojoExecutionException( "could not copy files the the eclipseEar directory", e );
182         }
183     }
184 
185     /**
186      * Copies a entire directory structure without scm files. Note:
187      * <ul>
188      * <li>It will include empty directories.
189      * <li>The <code>sourceDirectory</code> must exists.
190      * </ul>
191      * 
192      * @param sourceDirectory
193      * @param destinationDirectory
194      * @throws IOException
195      */
196     public static void copyDirectoryStructure( File sourceDirectory, File destinationDirectory )
197         throws IOException
198     {
199         if ( !sourceDirectory.exists() )
200         {
201             return;
202         }
203 
204         File[] files = sourceDirectory.listFiles();
205 
206         String sourcePath = sourceDirectory.getAbsolutePath();
207 
208         for ( int i = 0; i < files.length; i++ )
209         {
210             File file = files[i];
211 
212             String dest = file.getAbsolutePath();
213 
214             dest = dest.substring( sourcePath.length() + 1 );
215 
216             File destination = new File( destinationDirectory, dest );
217 
218             if ( file.isFile() )
219             {
220                 destination = destination.getParentFile();
221 
222                 FileUtils.copyFileToDirectory( file, destination );
223             }
224             else if ( file.isDirectory() && !file.getName().equals( ".svn" ) && !file.getName().equals( "CVS" ) )
225             {
226                 if ( !destination.exists() && !destination.mkdirs() )
227                 {
228                     throw new IOException( "Could not create destination directory '" + destination.getAbsolutePath()
229                         + "'." );
230                 }
231 
232                 copyDirectoryStructure( file, destination );
233             }
234         }
235     }
236 
237     /**
238      * there is no existing application.xml file so create a new one.
239      * 
240      * @return the domtree representing the contents of application.xml
241      */
242     private Xpp3Dom createNewApplicationXml()
243     {
244         Xpp3Dom result = new Xpp3Dom( EclipseWtpApplicationXMLWriter.APPLICATION_XML_APPLICATION );
245         result.setAttribute( EclipseWtpApplicationXMLWriter.ID, "Application_ID" );
246         result.setAttribute( EclipseWtpApplicationXMLWriter.VERSION, "1.4" );
247         result.setAttribute( EclipseWtpApplicationXMLWriter.XMLNS, "http://java.sun.com/xml/ns/j2ee" );
248         result.setAttribute( EclipseWtpApplicationXMLWriter.XMLNS_XSI, "http://www.w3.org/2001/XMLSchema-instance" );
249 
250         // special case for development websphere's ....
251         String locationAttribute;
252         if ( this.config.getWorkspaceConfiguration().getWebsphereVersion() != null )
253         {
254             locationAttribute = EclipseWtpApplicationXMLWriter.XSI_SCHEMA_LOCATION;
255         }
256         else
257         {
258             locationAttribute = EclipseWtpApplicationXMLWriter.XMLNS_SCHEMA_LOCATION;
259         }
260         result.setAttribute( locationAttribute,
261                              "http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/application_1_4.xsd" );
262         result.addChild( new Xpp3Dom( EclipseWtpApplicationXMLWriter.APPLICATION_XML_DESCRIPTION ) );
263         Xpp3Dom name = new Xpp3Dom( EclipseWtpApplicationXMLWriter.APPLICATION_XML_DISPLAY_NAME );
264         name.setValue( this.config.getEclipseProjectName() );
265         result.addChild( name );
266         return result;
267     }
268 
269     /**
270      * there is no existing .modulemaps file so create a new one.
271      * 
272      * @return the domtree representing the contents of the .modulemaps file
273      */
274     private Xpp3Dom createNewModulemaps()
275     {
276         Xpp3Dom result = new Xpp3Dom( EclipseWtpApplicationXMLWriter.MODULEMAP_EARPROJECT_MAP );
277         result.setAttribute( EclipseWtpApplicationXMLWriter.XMI_VERSION, "2.0" );
278         result.setAttribute( EclipseWtpApplicationXMLWriter.XMLNS_XMI, "http://www.omg.org/XMI" );
279         result.setAttribute( EclipseWtpApplicationXMLWriter.XMLNS_APPLICATION, "application.xmi" );
280         result.setAttribute( EclipseWtpApplicationXMLWriter.XMLNS_MODULEMAP, "modulemap.xmi" );
281         result.setAttribute( EclipseWtpApplicationXMLWriter.XMI_ID, "EARProjectMap_" + System.identityHashCode( this ) );
282         return result;
283     }
284 
285     /**
286      * find an existing module entry in the application.xml file by looking up the id in the modulemaps file and then
287      * using that to locate the entry in the application.xml file.
288      * 
289      * @param applicationXmlDom application.xml dom tree
290      * @param mapping .modulemaps dom tree
291      * @return dom tree representing the module
292      */
293     private Xpp3Dom findModuleInApplicationXml( Xpp3Dom applicationXmlDom, Xpp3Dom mapping )
294     {
295         String id = getIdFromMapping( mapping );
296         Xpp3Dom[] children = applicationXmlDom.getChildren();
297         for ( int index = 0; index < children.length; index++ )
298         {
299             String childId = children[index].getAttribute( EclipseWtpApplicationXMLWriter.ID );
300             if ( childId != null && childId.equals( id ) )
301             {
302                 return children[index];
303             }
304         }
305         return null;
306     }
307 
308     /**
309      * find an artifact in the modulemaps dom tree, if it is missing create a new entry in the modulemaps dom tree.
310      * 
311      * @param dependency dependency to find
312      * @param modulemapXmlDom dom-tree of modulemaps
313      * @return dom-tree representing the artifact
314      */
315     private Xpp3Dom findOrCreateArtifact( IdeDependency dependency, Xpp3Dom modulemapXmlDom )
316     {
317         // first try to find it
318         Xpp3Dom[] children = modulemapXmlDom.getChildren();
319         for ( int index = 0; index < children.length; index++ )
320         {
321             if ( children[index].getAttribute( EclipseWtpApplicationXMLWriter.MODULEMAPS_PROJECT_NAME ).equals(
322                                                                                                                 dependency.getEclipseProjectName() ) )
323             {
324                 if ( ( dependency.getType().equals( Constants.PROJECT_PACKAGING_EJB ) || dependency.getType().equals(
325                                                                                                                       "ejb3" ) )
326                     && children[index].getName().equals( EclipseWtpApplicationXMLWriter.MODULEMAPS_MAPPINGS )
327                     && children[index].getChild( EclipseWtpApplicationXMLWriter.APPLICATION_XML_MODULE ).getAttribute(
328                                                                                                                        EclipseWtpApplicationXMLWriter.XMI_TYPE ).equals(
329                                                                                                                                                                          EclipseWtpApplicationXMLWriter.MODULEMAPS_APPLICATION_EJB_MODULE ) )
330                 {
331                     return children[index];
332                 }
333                 else if ( dependency.getType().equals( Constants.PROJECT_PACKAGING_WAR )
334                     && children[index].getName().equals( EclipseWtpApplicationXMLWriter.MODULEMAPS_MAPPINGS )
335                     && children[index].getChild( EclipseWtpApplicationXMLWriter.APPLICATION_XML_MODULE ).getAttribute(
336                                                                                                                        EclipseWtpApplicationXMLWriter.XMI_TYPE ).equals(
337                                                                                                                                                                          EclipseWtpApplicationXMLWriter.MODULEMAPS_APPLICATION_WEB_MODULE ) )
338                 {
339                     return children[index];
340                 }
341                 else if ( dependency.getType().equals( Constants.PROJECT_PACKAGING_JAR )
342                     && children[index].getName().equals( EclipseWtpApplicationXMLWriter.MODULEMAPS_UTILITY_JARMAPPINGS ) )
343                 {
344                     return children[index];
345                 }
346                 else
347                 {
348                     modulemapXmlDom.removeChild( index );
349                     break;
350                 }
351             }
352         }
353         // ok, its missing (or it changed type). create a new one based on its
354         // type
355         long id = System.identityHashCode( dependency );
356         if ( dependency.getType().equals( Constants.PROJECT_PACKAGING_EJB ) || dependency.getType().equals( "ejb3" ) )
357         {
358             Xpp3Dom mapping = new Xpp3Dom( EclipseWtpApplicationXMLWriter.MODULEMAPS_MAPPINGS );
359             mapping.setAttribute( EclipseWtpApplicationXMLWriter.XMI_ID, "ModuleMapping_" + id );
360             mapping.setAttribute( EclipseWtpApplicationXMLWriter.MODULEMAPS_PROJECT_NAME,
361                                   dependency.getEclipseProjectName() );
362             Xpp3Dom module = new Xpp3Dom( EclipseWtpApplicationXMLWriter.APPLICATION_XML_MODULE );
363             module.setAttribute( EclipseWtpApplicationXMLWriter.XMI_TYPE,
364                                  EclipseWtpApplicationXMLWriter.MODULEMAPS_APPLICATION_EJB_MODULE );
365             module.setAttribute( EclipseWtpApplicationXMLWriter.HREF, "META-INF/application.xml#EjbModule_" + id );
366             mapping.addChild( module );
367             modulemapXmlDom.addChild( mapping );
368             return mapping;
369         }
370         else if ( dependency.getType().equals( Constants.PROJECT_PACKAGING_WAR ) )
371         {
372             Xpp3Dom mapping = new Xpp3Dom( EclipseWtpApplicationXMLWriter.MODULEMAPS_MAPPINGS );
373             mapping.setAttribute( EclipseWtpApplicationXMLWriter.XMI_ID, "ModuleMapping_" + id );
374             mapping.setAttribute( EclipseWtpApplicationXMLWriter.MODULEMAPS_PROJECT_NAME,
375                                   dependency.getEclipseProjectName() );
376             Xpp3Dom module = new Xpp3Dom( EclipseWtpApplicationXMLWriter.APPLICATION_XML_MODULE );
377             module.setAttribute( EclipseWtpApplicationXMLWriter.XMI_TYPE,
378                                  EclipseWtpApplicationXMLWriter.MODULEMAPS_APPLICATION_WEB_MODULE );
379             module.setAttribute( EclipseWtpApplicationXMLWriter.HREF, "META-INF/application.xml#WebModule_" + id );
380             mapping.addChild( module );
381             modulemapXmlDom.addChild( mapping );
382             return mapping;
383         }
384         else
385         {
386             Xpp3Dom utilityJARMapping = new Xpp3Dom( EclipseWtpApplicationXMLWriter.MODULEMAPS_UTILITY_JARMAPPINGS );
387             utilityJARMapping.setAttribute( EclipseWtpApplicationXMLWriter.XMI_ID, "UtilityJARMapping_" + id );
388             utilityJARMapping.setAttribute( EclipseWtpApplicationXMLWriter.MODULEMAPS_PROJECT_NAME,
389                                             dependency.getEclipseProjectName() );
390             utilityJARMapping.setAttribute( EclipseWtpApplicationXMLWriter.URI, dependency.getEclipseProjectName()
391                 + ".jar" );
392             modulemapXmlDom.addChild( utilityJARMapping );
393             return utilityJARMapping;
394         }
395     }
396 
397     /**
398      * get the id from the href of a modulemap.
399      * 
400      * @param mapping the dom-tree of modulemaps
401      * @return module identifier
402      */
403     private String getIdFromMapping( Xpp3Dom mapping )
404     {
405         if ( mapping.getChildCount() < 1 )
406         {
407             return "";
408         }
409         String href = mapping.getChild( 0 ).getAttribute( EclipseWtpApplicationXMLWriter.HREF );
410         String id = href.substring( href.indexOf( '#' ) + 1 );
411         return id;
412     }
413 
414     /**
415      * read an xml file (application.xml or .modulemaps).
416      * 
417      * @param xmlFile an xmlfile
418      * @return dom-tree representing the file contents
419      */
420     private Xpp3Dom readXMLFile( File xmlFile )
421     {
422         try
423         {
424             Reader reader = new InputStreamReader( new FileInputStream( xmlFile ), "UTF-8" );
425             Xpp3Dom applicationXmlDom = Xpp3DomBuilder.build( reader );
426             return applicationXmlDom;
427         }
428         catch ( FileNotFoundException e )
429         {
430             return null;
431         }
432         catch ( Exception e )
433         {
434             this.log.error( "cantreadfile" + xmlFile.getAbsolutePath() );
435             // this will trigger creating a new file
436             return null;
437         }
438     }
439 
440     /**
441      * mark the domtree entry as handled (all not handled ones will be deleted).
442      * 
443      * @param xpp3Dom dom element to mark handled
444      */
445     private void handled( Xpp3Dom xpp3Dom )
446     {
447         for ( int index = 0; index < this.applicationXmlDomChildren.length; index++ )
448         {
449             if ( this.applicationXmlDomChildren[index] == xpp3Dom )
450             {
451                 this.applicationXmlDomChildren[index] = null;
452             }
453         }
454         for ( int index = 0; index < this.modulemapsXmlDomChildren.length; index++ )
455         {
456             if ( this.modulemapsXmlDomChildren[index] == xpp3Dom )
457             {
458                 this.modulemapsXmlDomChildren[index] = null;
459             }
460         }
461     }
462 
463     /**
464      * delete all unused entries from the dom-trees.
465      * 
466      * @param applicationXmlDom dom-tree of application.xml
467      * @param modulemapsXmlDom dom-tree of modulemaps
468      */
469     private void removeUnusedEntries( Xpp3Dom applicationXmlDom, Xpp3Dom modulemapsXmlDom )
470     {
471         for ( int index = 0; index < this.modulemapsXmlDomChildren.length; index++ )
472         {
473             if ( this.modulemapsXmlDomChildren[index] != null )
474             {
475                 Xpp3Dom[] newModulemapsXmlDomChildren = modulemapsXmlDom.getChildren();
476                 for ( int newIndex = 0; newIndex < newModulemapsXmlDomChildren.length; newIndex++ )
477                 {
478                     if ( newModulemapsXmlDomChildren[newIndex] == this.modulemapsXmlDomChildren[index] )
479                     {
480                         modulemapsXmlDom.removeChild( newIndex );
481                         break;
482                     }
483                 }
484             }
485         }
486         for ( int index = 0; index < this.applicationXmlDomChildren.length; index++ )
487         {
488             if ( this.applicationXmlDomChildren[index] != null )
489             {
490                 Xpp3Dom[] newApplicationXmlDomChildren = applicationXmlDom.getChildren();
491                 for ( int newIndex = 0; newIndex < newApplicationXmlDomChildren.length; newIndex++ )
492                 {
493                     if ( newApplicationXmlDomChildren[newIndex] == this.applicationXmlDomChildren[index] )
494                     {
495                         applicationXmlDom.removeChild( newIndex );
496                         break;
497                     }
498                 }
499             }
500         }
501     }
502 
503     /**
504      * update the application.xml and the .modulemaps file for a specified dependency.all WAR an EJB dependencies will
505      * go in both files all others only in the modulemaps files. Webapplications contextroots are corrected to the
506      * contextRoot specified in the pom.
507      * 
508      * @param applicationXmlDom dom-tree of application.xml
509      * @param modulemapXmlDom dom-tree of modulemaps
510      * @param dependency the eclipse dependency to handle
511      */
512     private void updateApplicationXml( Xpp3Dom applicationXmlDom, Xpp3Dom modulemapXmlDom, IdeDependency dependency )
513     {
514         if ( dependency.isTestDependency() || dependency.isProvided()
515             || dependency.isSystemScopedOutsideProject( this.config.getProject() ) )
516         {
517             return;
518         }
519         Xpp3Dom mapping = findOrCreateArtifact( dependency, modulemapXmlDom );
520         handled( mapping );
521         if ( dependency.getType().equals( Constants.PROJECT_PACKAGING_EJB ) || dependency.getType().equals( "ejb3" ) )
522         {
523             Xpp3Dom module = findModuleInApplicationXml( applicationXmlDom, mapping );
524             if ( module == null )
525             {
526                 module = new Xpp3Dom( EclipseWtpApplicationXMLWriter.APPLICATION_XML_MODULE );
527                 module.setAttribute( EclipseWtpApplicationXMLWriter.ID, getIdFromMapping( mapping ) );
528                 Xpp3Dom ejb = new Xpp3Dom( "ejb" );
529                 ejb.setValue( dependency.getEclipseProjectName() + ".jar" );
530                 module.addChild( ejb );
531                 applicationXmlDom.addChild( module );
532             }
533             else
534             {
535                 handled( module );
536                 module.getChild( "ejb" ).setValue( dependency.getEclipseProjectName() + ".jar" );
537             }
538         }
539         else if ( dependency.getType().equals( Constants.PROJECT_PACKAGING_WAR ) )
540         {
541             String contextRootInPom = getContextRootFor( dependency );
542             Xpp3Dom module = findModuleInApplicationXml( applicationXmlDom, mapping );
543             if ( module == null )
544             {
545                 module = new Xpp3Dom( EclipseWtpApplicationXMLWriter.APPLICATION_XML_MODULE );
546                 module.setAttribute( EclipseWtpApplicationXMLWriter.ID, getIdFromMapping( mapping ) );
547                 Xpp3Dom web = new Xpp3Dom( EclipseWtpApplicationXMLWriter.APPLICATION_XML_WEB );
548                 Xpp3Dom webUri = new Xpp3Dom( EclipseWtpApplicationXMLWriter.APPLICATION_XML_WEB_URI );
549                 webUri.setValue( dependency.getEclipseProjectName() + ".war" );
550                 Xpp3Dom contextRoot = new Xpp3Dom( EclipseWtpApplicationXMLWriter.APPLICATION_XML_CONTEXT_ROOT );
551                 contextRoot.setValue( contextRootInPom );
552                 web.addChild( webUri );
553                 web.addChild( contextRoot );
554                 module.addChild( web );
555                 applicationXmlDom.addChild( module );
556             }
557             else
558             {
559                 handled( module );
560                 module.getChild( EclipseWtpApplicationXMLWriter.APPLICATION_XML_WEB ).getChild(
561                                                                                                 EclipseWtpApplicationXMLWriter.APPLICATION_XML_WEB_URI ).setValue(
562                                                                                                                                                                    dependency.getEclipseProjectName()
563                                                                                                                                                                        + ".war" );
564                 module.getChild( EclipseWtpApplicationXMLWriter.APPLICATION_XML_WEB ).getChild(
565                                                                                                 EclipseWtpApplicationXMLWriter.APPLICATION_XML_CONTEXT_ROOT ).setValue(
566                                                                                                                                                                         contextRootInPom );
567             }
568         }
569     }
570 
571     /**
572      * Find the contextRoot specified in the pom and convert it into contectroot for the application.xml.
573      * 
574      * @param dependency the artifact to search
575      * @return string with the context root
576      */
577     private String getContextRootFor( IdeDependency dependency )
578     {
579         String artifactId = dependency.getArtifactId();
580         String groupId = dependency.getGroupId();
581         for ( int index = 0; index < this.webModulesFromPoms.length; index++ )
582         {
583             Xpp3Dom webGroupId = this.webModulesFromPoms[index].getChild( "groupId" );
584             Xpp3Dom webArtifactId = this.webModulesFromPoms[index].getChild( "artifactId" );
585             Xpp3Dom webContextRoot = this.webModulesFromPoms[index].getChild( "contextRoot" );
586 
587             if ( webContextRoot != null && webArtifactId != null && webArtifactId.getValue().equals( artifactId )
588                 && webGroupId != null && webGroupId.getValue().equals( groupId ) )
589             {
590                 return webContextRoot.getValue();
591             }
592         }
593         // no configuration found back to maven-ear-plugin default
594         return dependency.getArtifactId();
595     }
596 
597     /**
598      * write back a domtree to a xmlfile and use the pretty print for it so that it is human readable.
599      * 
600      * @param xmlFile file to write to
601      * @param xmlDomTree dom-tree to write
602      * @throws MojoExecutionException if the file could not be written
603      */
604     private void writePrettyXmlFile( File xmlFile, Xpp3Dom xmlDomTree )
605         throws MojoExecutionException
606     {
607         Xpp3Dom original = readXMLFile( xmlFile );
608         if ( original != null && original.equals( xmlDomTree ) )
609         {
610             this.log.info( "Rad6CleanMojo.unchanged" + xmlFile.getAbsolutePath() );
611             return;
612         }
613         Writer w = null;
614         xmlFile.getParentFile().mkdirs();
615         try
616         {
617             w = new OutputStreamWriter( new FileOutputStream( xmlFile ), "UTF-8" );
618         }
619         catch ( IOException ex )
620         {
621             throw new MojoExecutionException( "Rad6Plugin.erroropeningfile", ex ); //$NON-NLS-1$
622         }
623         XMLWriter writer = new PrettyPrintXMLWriter( w, "UTF-8", null );
624         Xpp3DomWriter.write( writer, xmlDomTree );
625         IOUtil.close( w );
626     }
627 
628 }