1   package org.apache.maven.plugin.idea;
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  import org.apache.maven.artifact.Artifact;
23  import org.apache.maven.artifact.factory.ArtifactFactory;
24  import org.apache.maven.artifact.manager.WagonManager;
25  import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
26  import org.apache.maven.artifact.repository.ArtifactRepository;
27  import org.apache.maven.artifact.resolver.ArtifactResolver;
28  import org.apache.maven.model.Resource;
29  import org.apache.maven.plugin.MojoExecutionException;
30  import org.apache.maven.plugin.logging.Log;
31  import org.apache.maven.project.MavenProject;
32  import org.apache.maven.wagon.ResourceDoesNotExistException;
33  import org.apache.maven.wagon.TransferFailedException;
34  import org.codehaus.plexus.util.StringUtils;
35  import org.dom4j.Document;
36  import org.dom4j.DocumentException;
37  import org.dom4j.Element;
38  
39  import java.io.File;
40  import java.io.IOException;
41  import java.util.ArrayList;
42  import java.util.Collections;
43  import java.util.HashMap;
44  import java.util.HashSet;
45  import java.util.Iterator;
46  import java.util.List;
47  import java.util.Map;
48  import java.util.Set;
49  import java.util.regex.Matcher;
50  import java.util.regex.Pattern;
51  
52  
53  
54  
55  
56  
57  
58  
59  public class IdeaModuleMojo
60      extends AbstractIdeaMojo
61  {
62      
63  
64  
65  
66  
67  
68  
69      private List reactorProjects;
70  
71      
72  
73  
74      private WagonManager wagonManager;
75  
76      
77  
78  
79  
80  
81      private boolean linkModules;
82  
83      
84  
85  
86  
87  
88      private String deploymentDescriptorFile;
89  
90      
91  
92  
93  
94  
95      private boolean useFullNames;
96  
97      
98  
99  
100 
101 
102     private boolean downloadSources;
103 
104     
105 
106 
107 
108 
109     private boolean downloadJavadocs;
110 
111     
112 
113 
114 
115 
116     private String sourceClassifier;
117 
118     
119 
120 
121 
122 
123     private String javadocClassifier;
124 
125     
126 
127 
128 
129 
130 
131 
132 
133 
134 
135 
136 
137 
138 
139 
140 
141 
142 
143 
144     private Library[] libraries;
145 
146     
147 
148 
149 
150 
151 
152     private String exclude;
153 
154     
155 
156 
157 
158 
159 
160     private boolean dependenciesAsLibraries;
161 
162     
163 
164 
165 
166 
167 
168 
169     private static Map attemptedDownloads = new HashMap();
170 
171     
172 
173 
174 
175 
176     private boolean ideaPlugin;
177 
178     
179 
180 
181 
182 
183 
184 
185 
186     private String ideaVersion;
187 
188     private Set macros;
189 
190     public void initParam( MavenProject project, ArtifactFactory artifactFactory, ArtifactRepository localRepo,
191                            ArtifactResolver artifactResolver, ArtifactMetadataSource artifactMetadataSource, Log log,
192                            boolean overwrite, MavenProject executedProject, List reactorProjects,
193                            WagonManager wagonManager, boolean linkModules, boolean useFullNames,
194                            boolean downloadSources, String sourceClassifier, boolean downloadJavadocs,
195                            String javadocClassifier, Library[] libraries, Set macros, String exclude,
196                            boolean useShortDependencyNames, String deploymentDescriptorFile, boolean ideaPlugin,
197                            String ideaVersion )
198     {
199         super.initParam( project, artifactFactory, localRepo, artifactResolver, artifactMetadataSource, log,
200                          overwrite );
201 
202         this.reactorProjects = reactorProjects;
203 
204         this.wagonManager = wagonManager;
205 
206         this.linkModules = linkModules;
207 
208         this.useFullNames = useFullNames;
209 
210         this.downloadSources = downloadSources;
211 
212         this.sourceClassifier = sourceClassifier;
213 
214         this.downloadJavadocs = downloadJavadocs;
215 
216         this.javadocClassifier = javadocClassifier;
217 
218         this.libraries = libraries;
219 
220         this.macros = macros;
221 
222         this.exclude = exclude;
223 
224         this.dependenciesAsLibraries = useShortDependencyNames;
225 
226         this.deploymentDescriptorFile = deploymentDescriptorFile;
227 
228         this.ideaPlugin = ideaPlugin;
229 
230         this.ideaVersion = ideaVersion;
231     }
232 
233     
234 
235 
236 
237 
238 
239     public void execute()
240         throws MojoExecutionException
241     {
242         try
243         {
244             doDependencyResolution( executedProject, localRepo );
245         }
246         catch ( Exception e )
247         {
248             throw new MojoExecutionException( "Unable to build project dependencies.", e );
249         }
250 
251         rewriteModule();
252     }
253 
254     public void rewriteModule()
255         throws MojoExecutionException
256     {
257         File moduleFile = new File( executedProject.getBasedir(), executedProject.getArtifactId() + ".iml" );
258         try
259         {
260             Document document = readXmlDocument( moduleFile, "module.xml" );
261 
262             Element module = document.getRootElement();
263 
264             
265             
266             if ( "war".equals( executedProject.getPackaging() ) )
267             {
268                 addWebModule( module );
269             }
270             else if ( "ejb".equals( executedProject.getPackaging() ) )
271             {
272                 addEjbModule( module );
273             }
274             else if ( "ear".equals( executedProject.getPackaging() ) )
275             {
276                 addEarModule( module );
277             }
278             else if ( ideaPlugin )
279             {
280                 addPluginModule( module );
281             }
282 
283             Element component = findComponent( module, "NewModuleRootManager" );
284             Element output = findElement( component, "output" );
285             output.addAttribute( "url", getModuleFileUrl( executedProject.getBuild().getOutputDirectory() ) );
286 
287             Element outputTest = findElement( component, "output-test" );
288             outputTest.addAttribute( "url", getModuleFileUrl( executedProject.getBuild().getTestOutputDirectory() ) );
289 
290             Element content = findElement( component, "content" );
291 
292             removeOldElements( content, "sourceFolder" );
293 
294             for ( Iterator i = executedProject.getCompileSourceRoots().iterator(); i.hasNext(); )
295             {
296                 String directory = (String) i.next();
297                 addSourceFolder( content, directory, false );
298             }
299             for ( Iterator i = executedProject.getTestCompileSourceRoots().iterator(); i.hasNext(); )
300             {
301                 String directory = (String) i.next();
302                 addSourceFolder( content, directory, true );
303             }
304 
305             for ( Iterator i = executedProject.getBuild().getResources().iterator(); i.hasNext(); )
306             {
307                 Resource resource = (Resource) i.next();
308                 String directory = resource.getDirectory();
309                 if ( resource.getTargetPath() == null && !resource.isFiltering() )
310                 {
311                     addSourceFolder( content, directory, false );
312                 }
313                 else
314                 {
315                     getLog().info(
316                         "Not adding resource directory as it has an incompatible target path or filtering: "
317                             + directory );
318                 }
319             }
320 
321             for ( Iterator i = executedProject.getBuild().getTestResources().iterator(); i.hasNext(); )
322             {
323                 Resource resource = (Resource) i.next();
324                 String directory = resource.getDirectory();
325                 if ( resource.getTargetPath() == null && !resource.isFiltering() )
326                 {
327                     addSourceFolder( content, directory, true );
328                 }
329                 else
330                 {
331                     getLog().info(
332                         "Not adding test resource directory as it has an incompatible target path or filtering: "
333                             + directory );
334                 }
335             }
336 
337             removeOldElements( content, "excludeFolder" );
338 
339             
340             File target = new File( executedProject.getBuild().getDirectory() );
341             File classes = new File( executedProject.getBuild().getOutputDirectory() );
342             File testClasses = new File( executedProject.getBuild().getTestOutputDirectory() );
343 
344             List sourceFolders = content.elements( "sourceFolder" );
345 
346             List filteredExcludes = new ArrayList();
347             filteredExcludes.addAll( getExcludedDirectories( target, filteredExcludes, sourceFolders ) );
348             filteredExcludes.addAll( getExcludedDirectories( classes, filteredExcludes, sourceFolders ) );
349             filteredExcludes.addAll( getExcludedDirectories( testClasses, filteredExcludes, sourceFolders ) );
350 
351             if ( exclude != null )
352             {
353                 String[] dirs = exclude.split( "[,\\s]+" );
354                 for ( int i = 0; i < dirs.length; i++ )
355                 {
356                     File excludedDir = new File( executedProject.getBasedir(), dirs[i] );
357                     filteredExcludes.addAll( getExcludedDirectories( excludedDir, filteredExcludes, sourceFolders ) );
358                 }
359             }
360 
361             
362             
363             
364             
365             
366             ArrayList actuallyExcluded = new ArrayList();
367             Collections.sort( filteredExcludes );
368             for ( Iterator i = filteredExcludes.iterator(); i.hasNext(); )
369             {
370                 String dirToExclude = i.next().toString();
371                 String dirToExcludeTemp = dirToExclude.replace( '\\', '/' );
372                 boolean addExclude = true;
373                 for ( Iterator iterator = actuallyExcluded.iterator(); iterator.hasNext(); )
374                 {
375                     String dir = iterator.next().toString();
376                     String dirTemp = dir.replace( '\\', '/' );
377                     if ( dirToExcludeTemp.startsWith( dirTemp + "/" ) )
378                     {
379                         addExclude = false;
380                         break;
381                     }
382                     else if ( dir.startsWith( dirToExcludeTemp + "/" ) )
383                     {
384                         actuallyExcluded.remove( dir );
385                     }
386                 }
387 
388                 if ( addExclude )
389                 {
390                     actuallyExcluded.add( dirToExclude );
391                     addExcludeFolder( content, dirToExclude );
392                 }
393             }
394 
395             
396             String outputModuleUrl = getModuleFileUrl( executedProject.getBuild().getOutputDirectory() );
397             String testOutputModuleUrl = getModuleFileUrl( executedProject.getBuild().getTestOutputDirectory() );
398             for ( Iterator i = content.elements( "sourceFolder" ).iterator(); i.hasNext(); )
399             {
400                 Element sourceFolder = (Element) i.next();
401                 String sourceUrl = sourceFolder.attributeValue( "url" ).replace( '\\', '/' );
402                 if ( sourceUrl.startsWith( outputModuleUrl + "/" ) || sourceUrl.startsWith( testOutputModuleUrl ) )
403                 {
404                     component.remove( component.element( "exclude-output" ) );
405                     break;
406                 }
407             }
408 
409             rewriteDependencies( component );
410 
411             writeXmlDocument( moduleFile, document );
412         }
413         catch ( DocumentException e )
414         {
415             throw new MojoExecutionException( "Error parsing existing IML file " + moduleFile.getAbsolutePath(), e );
416         }
417         catch ( IOException e )
418         {
419             throw new MojoExecutionException( "Error parsing existing IML file " + moduleFile.getAbsolutePath(), e );
420         }
421     }
422 
423     private void rewriteDependencies( Element component )
424     {
425         Map modulesByName = new HashMap();
426         Map modulesByUrl = new HashMap();
427         Set unusedModules = new HashSet();
428         for ( Iterator children = component.elementIterator( "orderEntry" ); children.hasNext(); )
429         {
430             Element orderEntry = (Element) children.next();
431 
432             String type = orderEntry.attributeValue( "type" );
433             if ( "module".equals( type ) )
434             {
435                 modulesByName.put( orderEntry.attributeValue( "module-name" ), orderEntry );
436             }
437             else if ( "module-library".equals( type ) )
438             {
439                 
440                 unusedModules.add( orderEntry );
441 
442                 Element lib = orderEntry.element( "library" );
443                 String name = lib.attributeValue( "name" );
444                 if ( name != null )
445                 {
446                     modulesByName.put( name, orderEntry );
447                 }
448                 else
449                 {
450                     Element classesChild = lib.element( "CLASSES" );
451                     if ( classesChild != null )
452                     {
453                         Element rootChild = classesChild.element( "root" );
454                         if ( rootChild != null )
455                         {
456                             String url = rootChild.attributeValue( "url" );
457                             if ( url != null )
458                             {
459                                 
460                                 modulesByUrl.put( url.toLowerCase(), orderEntry );
461                             }
462                         }
463                     }
464                 }
465             }
466         }
467 
468         List testClasspathElements = executedProject.getTestArtifacts();
469         for ( Iterator i = testClasspathElements.iterator(); i.hasNext(); )
470         {
471             Artifact a = (Artifact) i.next();
472 
473             Library library = findLibrary( a );
474             if ( library != null && library.isExclude() )
475             {
476                 continue;
477             }
478 
479             String moduleName;
480             if ( useFullNames )
481             {
482                 moduleName = a.getGroupId() + ':' + a.getArtifactId() + ':' + a.getType() + ':' + a.getVersion();
483             }
484             else
485             {
486                 moduleName = a.getArtifactId();
487             }
488 
489             Element dep = (Element) modulesByName.get( moduleName );
490 
491             if ( dep == null )
492             {
493                 
494                 dep = (Element) modulesByUrl.get( getLibraryUrl( a ).toLowerCase() );
495             }
496 
497             if ( dep != null )
498             {
499                 unusedModules.remove( dep );
500             }
501             else
502             {
503                 dep = createElement( component, "orderEntry" );
504             }
505 
506             boolean isIdeaModule = false;
507             if ( linkModules )
508             {
509                 isIdeaModule = isReactorProject( a.getGroupId(), a.getArtifactId() );
510 
511                 if ( isIdeaModule )
512                 {
513                     dep.addAttribute( "type", "module" );
514                     dep.addAttribute( "module-name", moduleName );
515                 }
516             }
517 
518             if ( a.getFile() != null && !isIdeaModule )
519             {
520                 dep.addAttribute( "type", "module-library" );
521 
522                 Element lib = dep.element( "library" );
523 
524                 if ( lib == null )
525                 {
526                     lib = createElement( dep, "library" );
527                 }
528 
529                 if ( dependenciesAsLibraries )
530                 {
531                     lib.addAttribute( "name", moduleName );
532                 }
533 
534                 
535                 removeOldElements( lib, "CLASSES" );
536                 Element classes = createElement( lib, "CLASSES" );
537                 if ( library != null && library.getSplitClasses().length > 0 )
538                 {
539                     lib.addAttribute( "name", moduleName );
540                     String[] libraryClasses = library.getSplitClasses();
541                     for ( int k = 0; k < libraryClasses.length; k++ )
542                     {
543                         String classpath = libraryClasses[k];
544                         extractMacro( classpath );
545                         Element classEl = createElement( classes, "root" );
546                         classEl.addAttribute( "url", classpath );
547                     }
548                 }
549                 else
550                 {
551                     createElement( classes, "root" ).addAttribute( "url", getLibraryUrl( a ) );
552                 }
553 
554                 if ( library != null && library.getSplitSources().length > 0 )
555                 {
556                     removeOldElements( lib, "SOURCES" );
557                     Element sourcesElement = createElement( lib, "SOURCES" );
558                     String[] sources = library.getSplitSources();
559                     for ( int k = 0; k < sources.length; k++ )
560                     {
561                         String source = sources[k];
562                         extractMacro( source );
563                         Element sourceEl = createElement( sourcesElement, "root" );
564                         sourceEl.addAttribute( "url", source );
565                     }
566                 }
567                 else if ( downloadSources )
568                 {
569                     resolveClassifier( createOrGetElement( lib, "SOURCES" ), a, sourceClassifier );
570                 }
571 
572                 if ( library != null && library.getSplitJavadocs().length > 0 )
573                 {
574                     removeOldElements( lib, "JAVADOC" );
575                     Element javadocsElement = createElement( lib, "JAVADOC" );
576                     String[] javadocs = library.getSplitJavadocs();
577                     for ( int k = 0; k < javadocs.length; k++ )
578                     {
579                         String javadoc = javadocs[k];
580                         extractMacro( javadoc );
581                         Element sourceEl = createElement( javadocsElement, "root" );
582                         sourceEl.addAttribute( "url", javadoc );
583                     }
584                 }
585                 else if ( downloadJavadocs )
586                 {
587                     resolveClassifier( createOrGetElement( lib, "JAVADOC" ), a, javadocClassifier );
588                 }
589             }
590         }
591 
592         for ( Iterator i = unusedModules.iterator(); i.hasNext(); )
593         {
594             Element orderEntry = (Element) i.next();
595 
596             component.remove( orderEntry );
597         }
598     }
599 
600     private Element createOrGetElement( Element lib, String name )
601     {
602         Element el = lib.element( name );
603 
604         if ( el == null )
605         {
606             el = createElement( lib, name );
607         }
608         return el;
609     }
610 
611     private void addEarModule( Element module )
612     {
613         module.addAttribute( "type", "J2EE_APPLICATION_MODULE" );
614         Element component = findComponent( module, "ApplicationModuleProperties" );
615         addDeploymentDescriptor( component, "application.xml", "1.3",
616                                  executedProject.getBuild().getDirectory() + "/application.xml" );
617     }
618 
619     private void addEjbModule( Element module )
620     {
621         String ejbVersion = getPluginSetting( "maven-ejb-plugin", "ejbVersion", "2.x" );
622 
623         module.addAttribute( "type", "J2EE_EJB_MODULE" );
624 
625         String explodedDir = executedProject.getBuild().getDirectory() + "/" + executedProject.getArtifactId();
626 
627         Element component = findComponent( module, "EjbModuleBuildComponent" );
628 
629         Element setting = findSetting( component, "EXPLODED_URL" );
630         setting.addAttribute( "value", getModuleFileUrl( explodedDir ) );
631 
632         component = findComponent( module, "EjbModuleProperties" );
633         Element deployDescElement =
634             addDeploymentDescriptor( component, "ejb-jar.xml", ejbVersion, "src/main/resources/META-INF/ejb-jar.xml" );
635         deployDescElement.addAttribute( "optional", ejbVersion.startsWith( "3" ) + "" );
636 
637         removeOldElements( component, "containerElement" );
638         List artifacts = executedProject.getTestArtifacts();
639         for ( Iterator i = artifacts.iterator(); i.hasNext(); )
640         {
641             Artifact artifact = (Artifact) i.next();
642 
643             Element containerElement = createElement( component, "containerElement" );
644 
645             if ( linkModules && isReactorProject( artifact.getGroupId(), artifact.getArtifactId() ) )
646             {
647                 containerElement.addAttribute( "type", "module" );
648                 containerElement.addAttribute( "name", artifact.getArtifactId() );
649                 Element methodAttribute = createElement( containerElement, "attribute" );
650                 methodAttribute.addAttribute( "name", "method" );
651                 methodAttribute.addAttribute( "value", "6" );
652                 Element uriAttribute = createElement( containerElement, "attribute" );
653                 uriAttribute.addAttribute( "name", "URI" );
654                 uriAttribute.addAttribute( "value", "/lib/" + artifact.getArtifactId() + ".jar" );
655             }
656             else if ( artifact.getFile() != null )
657             {
658                 containerElement.addAttribute( "type", "library" );
659                 containerElement.addAttribute( "level", "module" );
660 
661                 
662                 if ( StringUtils.isEmpty( ideaVersion ) || !ideaVersion.startsWith( "6" ) )
663                 {
664                     containerElement.addAttribute( "name", artifact.getArtifactId() );
665                 }
666 
667                 Element methodAttribute = createElement( containerElement, "attribute" );
668                 methodAttribute.addAttribute( "name", "method" );
669                 methodAttribute.addAttribute( "value", "2" );
670                 Element uriAttribute = createElement( containerElement, "attribute" );
671                 uriAttribute.addAttribute( "name", "URI" );
672                 uriAttribute.addAttribute( "value", "/lib/" + artifact.getFile().getName() );
673                 Element urlElement = createElement( containerElement, "url" );
674                 urlElement.setText( getLibraryUrl( artifact ) );
675             }
676         }
677     }
678 
679     private void extractMacro( String path )
680     {
681         if ( macros != null )
682         {
683             Pattern p = Pattern.compile( ".*\\$([^\\$]+)\\$.*" );
684             Matcher matcher = p.matcher( path );
685             while ( matcher.find() )
686             {
687                 String macro = matcher.group( 1 );
688                 macros.add( macro );
689             }
690         }
691     }
692 
693     private Library findLibrary( Artifact a )
694     {
695         if ( libraries != null )
696         {
697             for ( int j = 0; j < libraries.length; j++ )
698             {
699                 Library library = libraries[j];
700                 if ( a.getArtifactId().equals( library.getName() ) )
701                 {
702                     return library;
703                 }
704             }
705         }
706 
707         return null;
708     }
709 
710     private List getExcludedDirectories( File target, List excludeList, List sourceFolders )
711     {
712         List foundFolders = new ArrayList();
713 
714         int totalDirs = 0, excludedDirs = 0;
715 
716         if ( target.exists() && !excludeList.contains( target.getAbsolutePath() ) )
717         {
718             File[] files = target.listFiles();
719 
720             for ( int i = 0; i < files.length; i++ )
721             {
722                 File file = files[i];
723                 if ( file.isDirectory() && !excludeList.contains( file.getAbsolutePath() ) )
724                 {
725                     totalDirs++;
726 
727                     String absolutePath = file.getAbsolutePath();
728                     String url = getModuleFileUrl( absolutePath );
729 
730                     boolean addToExclude = true;
731                     for ( Iterator sources = sourceFolders.iterator(); sources.hasNext(); )
732                     {
733                         String source = ( (Element) sources.next() ).attributeValue( "url" );
734                         if ( source.equals( url ) )
735                         {
736                             addToExclude = false;
737                             break;
738                         }
739                         else if ( source.indexOf( url ) == 0 )
740                         {
741                             foundFolders.addAll(
742                                 getExcludedDirectories( new File( absolutePath ), excludeList, sourceFolders ) );
743                             addToExclude = false;
744                             break;
745                         }
746                     }
747                     if ( addToExclude )
748                     {
749                         excludedDirs++;
750                         foundFolders.add( absolutePath );
751                     }
752                 }
753             }
754 
755             
756             if ( totalDirs > 0 && totalDirs == excludedDirs )
757             {
758                 foundFolders.clear();
759 
760                 foundFolders.add( target.getAbsolutePath() );
761             }
762         }
763         else if ( !target.exists() )
764         {
765             
766             foundFolders.add( target.getAbsolutePath() );
767         }
768 
769         return foundFolders;
770     }
771 
772     
773 
774 
775 
776 
777     private void addWebModule( Element module )
778     {
779         
780         
781         
782 
783         String warWebapp = executedProject.getBuild().getDirectory() + "/" + executedProject.getArtifactId();
784         String warSrc = getPluginSetting( "maven-war-plugin", "warSourceDirectory", "src/main/webapp" );
785         String webXml = warSrc + "/WEB-INF/web.xml";
786 
787         module.addAttribute( "type", "J2EE_WEB_MODULE" );
788 
789         Element component = findComponent( module, "WebModuleBuildComponent" );
790         Element setting = findSetting( component, "EXPLODED_URL" );
791         setting.addAttribute( "value", getModuleFileUrl( warWebapp ) );
792 
793         component = findComponent( module, "WebModuleProperties" );
794 
795         removeOldElements( component, "containerElement" );
796         List artifacts = executedProject.getTestArtifacts();
797         for ( Iterator i = artifacts.iterator(); i.hasNext(); )
798         {
799             Artifact artifact = (Artifact) i.next();
800 
801             Element containerElement = createElement( component, "containerElement" );
802 
803             if ( linkModules && isReactorProject( artifact.getGroupId(), artifact.getArtifactId() ) )
804             {
805                 containerElement.addAttribute( "type", "module" );
806                 containerElement.addAttribute( "name", artifact.getArtifactId() );
807                 Element methodAttribute = createElement( containerElement, "attribute" );
808                 methodAttribute.addAttribute( "name", "method" );
809                 methodAttribute.addAttribute( "value", "5" );
810                 Element uriAttribute = createElement( containerElement, "attribute" );
811                 uriAttribute.addAttribute( "name", "URI" );
812                 uriAttribute.addAttribute( "value", "/WEB-INF/lib/" + artifact.getArtifactId() + "-"
813                     + artifact.getVersion() + ".jar" );
814             }
815             else if ( artifact.getFile() != null )
816             {
817                 containerElement.addAttribute( "type", "library" );
818                 containerElement.addAttribute( "level", "module" );
819                 Element methodAttribute = createElement( containerElement, "attribute" );
820                 methodAttribute.addAttribute( "name", "method" );
821                 if ( Artifact.SCOPE_PROVIDED.equalsIgnoreCase( artifact.getScope() )
822                     || Artifact.SCOPE_SYSTEM.equalsIgnoreCase( artifact.getScope() )
823                     || Artifact.SCOPE_TEST.equalsIgnoreCase( artifact.getScope() ) )
824                 {
825                     
826                     methodAttribute.addAttribute( "value", "0" );
827                 }
828                 else
829                 {
830                     methodAttribute.addAttribute( "value", "1" ); 
831                 }
832                 Element uriAttribute = createElement( containerElement, "attribute" );
833                 uriAttribute.addAttribute( "name", "URI" );
834                 uriAttribute.addAttribute( "value", "/WEB-INF/lib/" + artifact.getFile().getName() );
835                 Element url = createElement( containerElement, "url" );
836                 url.setText( getLibraryUrl( artifact ) );
837             }
838         }
839 
840         addDeploymentDescriptor( component, "web.xml", "2.3", webXml );
841 
842         Element element = findElement( component, "webroots" );
843         removeOldElements( element, "root" );
844 
845         element = createElement( element, "root" );
846         element.addAttribute( "relative", "/" );
847         element.addAttribute( "url", getModuleFileUrl( warSrc ) );
848     }
849 
850     private void addPluginModule( Element module )
851     {
852         module.addAttribute( "type", "PLUGIN_MODULE" );
853 
854         
855         Element pluginDevElement = createElement( module, "component" );
856         pluginDevElement.addAttribute( "name", "DevKit.ModuleBuildProperties" );
857         pluginDevElement.addAttribute( "url", getModuleFileUrl( "src/main/resources/META-INF/plugin.xml" ) );
858     }
859 
860     
861 
862 
863 
864 
865 
866 
867     private String getModuleFileUrl( File basedir, String path )
868     {
869         return "file://$MODULE_DIR$/" + toRelative( basedir.getAbsolutePath(), path );
870     }
871 
872     private String getModuleFileUrl( String file )
873     {
874         return getModuleFileUrl( executedProject.getBasedir(), file );
875     }
876 
877     
878 
879 
880 
881 
882 
883 
884     private void addSourceFolder( Element content, String directory, boolean isTest )
885     {
886         if ( !StringUtils.isEmpty( directory ) && new File( directory ).isDirectory() )
887         {
888             Element sourceFolder = createElement( content, "sourceFolder" );
889             sourceFolder.addAttribute( "url", getModuleFileUrl( directory ) );
890             sourceFolder.addAttribute( "isTestSource", Boolean.toString( isTest ) );
891         }
892     }
893 
894     private void addExcludeFolder( Element content, String directory )
895     {
896         Element excludeFolder = createElement( content, "excludeFolder" );
897         excludeFolder.addAttribute( "url", getModuleFileUrl( directory ) );
898     }
899 
900     private boolean isReactorProject( String groupId, String artifactId )
901     {
902         if ( reactorProjects != null )
903         {
904             for ( Iterator j = reactorProjects.iterator(); j.hasNext(); )
905             {
906                 MavenProject p = (MavenProject) j.next();
907                 if ( p.getGroupId().equals( groupId ) && p.getArtifactId().equals( artifactId ) )
908                 {
909                     return true;
910                 }
911             }
912         }
913         return false;
914     }
915 
916     private void resolveClassifier( Element element, Artifact a, String classifier )
917     {
918         String id = a.getId() + '-' + classifier;
919 
920         String path;
921         if ( attemptedDownloads.containsKey( id ) )
922         {
923             getLog().debug( id + " was already downloaded." );
924             path = (String) attemptedDownloads.get( id );
925         }
926         else
927         {
928             getLog().debug( id + " was not attempted to be downloaded yet: trying..." );
929             path = resolveClassifiedArtifact( a, classifier );
930             attemptedDownloads.put( id, path );
931         }
932 
933         if ( path != null )
934         {
935             String jarPath = "jar://" + path + "!/";
936             getLog().debug( "Setting " + classifier + " for " + id + " to " + jarPath );
937             removeOldElements( element, "root" );
938             createElement( element, "root" ).addAttribute( "url", jarPath );
939         }
940     }
941 
942     private String resolveClassifiedArtifact( Artifact artifact, String classifier )
943     {
944         String basePath = artifact.getFile().getAbsolutePath().replace( '\\', '/' );
945         int delIndex = basePath.indexOf( ".jar" );
946         if ( delIndex < 0 )
947         {
948             return null;
949         }
950 
951         List remoteRepos = executedProject.getRemoteArtifactRepositories();
952         try
953         {
954             Artifact classifiedArtifact = artifactFactory.createArtifactWithClassifier( artifact.getGroupId(),
955                                                                                         artifact.getArtifactId(),
956                                                                                         artifact.getVersion(),
957                                                                                         artifact.getType(),
958                                                                                         classifier );
959             String dstFilename = basePath.substring( 0, delIndex ) + '-' + classifier + ".jar";
960             File dstFile = new File( dstFilename );
961             classifiedArtifact.setFile( dstFile );
962             
963             
964             if ( !dstFile.exists() )
965             {
966                 wagonManager.getArtifact( classifiedArtifact, remoteRepos );
967             }
968             return dstFile.getAbsolutePath().replace( '\\', '/' );
969         }
970         catch ( TransferFailedException e )
971         {
972             getLog().debug( e );
973             return null;
974         }
975         catch ( ResourceDoesNotExistException e )
976         {
977             getLog().debug( e );
978             return null;
979         }
980     }
981 
982     
983 
984 
985 
986 
987 
988 
989     private Element findSetting( Element component, String name )
990     {
991         return findElement( component, "setting", name );
992     }
993 
994     private String getLibraryUrl( Artifact artifact )
995     {
996         return "jar://" + convertDriveLetter( artifact.getFile().getAbsolutePath() ).replace( '\\', '/' ) + "!/";
997     }
998 
999     private Element addDeploymentDescriptor( Element component, String name, String version, String file )
1000     {
1001         Element deploymentDescriptor = findElement( component, "deploymentDescriptor" );
1002 
1003         if ( deploymentDescriptor.attributeValue( "version" ) == null )
1004         {
1005             deploymentDescriptor.addAttribute( "version", version );
1006         }
1007 
1008         if ( deploymentDescriptor.attributeValue( "name" ) == null )
1009         {
1010             deploymentDescriptor.addAttribute( "name", name );
1011         }
1012 
1013         deploymentDescriptor.addAttribute( "optional", "false" );
1014 
1015         if ( deploymentDescriptorFile == null )
1016         {
1017             deploymentDescriptorFile = file;
1018         }
1019 
1020         deploymentDescriptor.addAttribute( "url", getModuleFileUrl( deploymentDescriptorFile ) );
1021 
1022         return deploymentDescriptor;
1023     }
1024 }