View Javadoc

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.ide;
20  
21  import java.io.File;
22  import java.io.IOException;
23  import java.util.ArrayList;
24  import java.util.Iterator;
25  import java.util.List;
26  
27  import org.apache.maven.artifact.Artifact;
28  import org.apache.maven.artifact.factory.ArtifactFactory;
29  import org.apache.maven.artifact.repository.ArtifactRepository;
30  import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
31  import org.apache.maven.artifact.resolver.ArtifactResolutionException;
32  import org.apache.maven.artifact.resolver.ArtifactResolver;
33  import org.apache.maven.artifact.versioning.ArtifactVersion;
34  import org.apache.maven.artifact.versioning.VersionRange;
35  import org.apache.maven.model.Dependency;
36  import org.apache.maven.model.Plugin;
37  import org.apache.maven.model.PluginExecution;
38  import org.apache.maven.plugin.MojoExecutionException;
39  import org.apache.maven.plugin.eclipse.Messages;
40  import org.apache.maven.plugin.logging.Log;
41  import org.apache.maven.project.MavenProject;
42  import org.codehaus.plexus.util.FileUtils;
43  import org.codehaus.plexus.util.StringUtils;
44  import org.codehaus.plexus.util.xml.Xpp3Dom;
45  
46  /**
47   * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
48   * @author <a href="mailto:fgiust@users.sourceforge.net">Fabrizio Giustina</a>
49   * @version $Id: IdeUtils.java 1174465 2011-09-23 00:35:53Z baerrach $
50   */
51  public class IdeUtils
52  {
53      public static final String JAVA_1_1 = "1.1";
54  
55      public static final String JAVA_1_2 = "1.2";
56  
57      public static final String JAVA_1_3 = "1.3";
58  
59      public static final String JAVA_1_4 = "1.4";
60  
61      public static final String JAVA_5_0 = "5.0";
62  
63      public static final String JAVA_6_0 = "6.0";
64  
65      public static final String PROJECT_NAME_DEFAULT_TEMPLATE = "[artifactId]";
66  
67      public static final String PROJECT_NAME_WITH_VERSION_TEMPLATE = "[artifactId]-[version]";
68  
69      public static final String PROJECT_NAME_WITH_GROUP_TEMPLATE = "[groupId].[artifactId]";
70  
71      public static final String PROJECT_NAME_WITH_GROUP_AND_VERSION_TEMPLATE = "[groupId].[artifactId]-[version]";
72  
73      /**
74       * compiler plugin id.
75       */
76      private static final String ARTIFACT_MAVEN_COMPILER_PLUGIN = "maven-compiler-plugin"; //$NON-NLS-1$
77  
78      /**
79       * 'source' property for maven-compiler-plugin.
80       */
81      private static final String PROPERTY_SOURCE = "source"; //$NON-NLS-1$
82  
83      /**
84       * 'encoding' property for maven-compiler-plugin.
85       */
86      private static final String PROPERTY_ENCODING = "encoding"; //$NON-NLS-1$
87  
88      /**
89       * 'target' property for maven-compiler-plugin.
90       */
91      private static final String PROPERTY_TARGET = "target"; //$NON-NLS-1$
92  
93      /**
94       * The suffix used to mark a file as not available.
95       */
96      public static final String NOT_AVAILABLE_MARKER_FILE_SUFFIX = "-not-available";
97  
98      /**
99       * Delete a file, handling log messages and exceptions
100      *
101      * @param f File to be deleted
102      * @throws MojoExecutionException only if a file exists and can't be deleted
103      */
104     public static void delete( File f, Log log )
105         throws MojoExecutionException
106     {
107         if ( f.isDirectory() )
108         {
109             log.info( Messages.getString( "EclipseCleanMojo.deletingDirectory", f.getName() ) ); //$NON-NLS-1$
110         }
111         else
112         {
113             log.info( Messages.getString( "EclipseCleanMojo.deletingFile", f.getName() ) ); //$NON-NLS-1$
114         }
115 
116         if ( f.exists() )
117         {
118             if ( !f.delete() )
119             {
120                 try
121                 {
122                     FileUtils.forceDelete( f );
123                 }
124                 catch ( IOException e )
125                 {
126                     throw new MojoExecutionException( Messages.getString( "EclipseCleanMojo.failedtodelete", //$NON-NLS-1$
127                                                                           new Object[] { f.getName(),
128                                                                               f.getAbsolutePath() } ) );
129                 }
130             }
131         }
132         else
133         {
134             log.debug( Messages.getString( "EclipseCleanMojo.nofilefound", f.getName() ) ); //$NON-NLS-1$
135         }
136     }
137 
138     public static String getCanonicalPath( File file )
139         throws MojoExecutionException
140     {
141         try
142         {
143             return file.getCanonicalPath();
144         }
145         catch ( IOException e )
146         {
147             throw new MojoExecutionException( Messages.getString( "EclipsePlugin.cantcanonicalize", file //$NON-NLS-1$
148             .getAbsolutePath() ), e );
149         }
150     }
151 
152     /**
153      * Returns a compiler plugin settings, considering also settings altered in plugin executions .
154      *
155      * @param project maven project
156      * @return option value (may be null)
157      */
158     public static String getCompilerPluginSetting( MavenProject project, String optionName )
159     {
160         String value = findCompilerPluginSettingInPlugins( project.getModel().getBuild().getPlugins(), optionName );
161         if ( value == null && project.getModel().getBuild().getPluginManagement() != null )
162         {
163             value =
164                 findCompilerPluginSettingInPlugins( project.getModel().getBuild().getPluginManagement().getPlugins(),
165                                                     optionName );
166         }
167         return value;
168     }
169 
170     /**
171      * Returns the source version configured for the compiler plugin. Returns the minimum version required to compile
172      * both standard and test sources, if settings are different.
173      *
174      * @param project maven project
175      * @return java source version
176      */
177     public static String getCompilerSourceVersion( MavenProject project )
178     {
179         return IdeUtils.getCompilerPluginSetting( project, PROPERTY_SOURCE );
180     }
181 
182     /**
183      * Returns the source encoding configured for the compiler plugin. Returns the minimum version required to compile
184      * both standard and test sources, if settings are different.
185      *
186      * @param project maven project
187      * @return java source version
188      */
189     public static String getCompilerSourceEncoding( MavenProject project )
190     {
191         String value = IdeUtils.getCompilerPluginSetting( project, PROPERTY_ENCODING );
192 		if ( value == null )
193         {
194             project.getProperties().getProperty( "project.build.sourceEncoding" );
195         }
196 		return value;
197     }
198 
199     /**
200      * Returns the target version configured for the compiler plugin. Returns the minimum version required to compile
201      * both standard and test sources, if settings are different.
202      *
203      * @param project maven project
204      * @return java target version
205      */
206     public static String getCompilerTargetVersion( MavenProject project )
207     {
208         return IdeUtils.getCompilerPluginSetting( project, PROPERTY_TARGET );
209     }
210 
211     // /**
212     // * Extracts the version of the first matching dependency in the given list.
213     // *
214     // * @param artifactIds artifact names to compare against for extracting version
215     // * @param dependencies Collection of dependencies for our project
216     // * @param len expected length of the version sub-string
217     // * @return
218     // */
219     // public static String getDependencyVersion( String[] artifactIds, List dependencies, int len )
220     // {
221     // for ( int j = 0; j < artifactIds.length; j++ )
222     // {
223     // String id = artifactIds[j];
224     // for ( Iterator itr = dependencies.iterator(); itr.hasNext(); )
225     // {
226     // Dependency dependency = (Dependency) itr.next();
227     // if ( id.equals( dependency.getArtifactId() ) )
228     // {
229     // return StringUtils.substring( dependency.getVersion(), 0, len );
230     // }
231     // }
232     // }
233     // return null;
234     // }
235 
236     /**
237      * Extracts the version of the first matching artifact in the given list.
238      * <p>
239      * The {@code len} parameter indicated what to to return:
240      * <ul>
241      *   <li><strong>1</strong> indicated <code>major</code> version</li>
242      *   <li><strong>3</strong> indicated <code>major dot minor</code> version</li>
243      *   <li><strong>5 and above</strong> indicates <code>major dot minor dot incremental</code> version
244      * </ul>
245      * 
246      * @param artifactIds artifact names to compare against for extracting version
247      * @param artifacts Set of artifacts for our project
248      * @param len expected length of the version sub-string
249      * @return
250      */
251     public static String getArtifactVersion( String[] artifactIds, List dependencies, int len )
252     {
253         String version = null;
254         ArtifactVersion artifactVersion = getArtifactVersion( artifactIds, dependencies );
255         if ( artifactVersion != null )
256         {
257             StringBuffer versionBuffer = new StringBuffer();
258             if( len >= 1 )
259             {
260                 versionBuffer.append( artifactVersion.getMajorVersion() );
261             }
262             if( len >= 2 )
263             {
264                 versionBuffer.append( '.' );
265             }            
266             if( len >= 3 )
267             {
268                 versionBuffer.append( artifactVersion.getMinorVersion() );
269             }
270             if( len >= 4 )
271             {
272                 versionBuffer.append( '.' );
273             }            
274             if( len >= 5 )
275             {
276                 versionBuffer.append( artifactVersion.getIncrementalVersion() );
277             }
278             version = versionBuffer.toString();
279         }
280         return version;
281     }
282     
283     /**
284      * 
285      * @param artifactIds an array of artifactIds, should not be <code>null</code>
286      * @param dependencies a list of {@link Dependency}-objects, should not be <code>null</code>
287      * @return the resolved ArtifactVersion, otherwise <code>null</code>
288      */
289     public static ArtifactVersion getArtifactVersion( String[] artifactIds, List /*<Dependency>*/ dependencies )
290     {
291         for ( int j = 0; j < artifactIds.length; j++ )
292         {
293             String id = artifactIds[j];
294             Iterator depIter = dependencies.iterator();
295             while ( depIter.hasNext() )
296             {
297                 Dependency dep = (Dependency) depIter.next();
298                 if ( id.equals( dep.getArtifactId() ) )
299                 {
300                     return VersionRange.createFromVersion( dep.getVersion() ).getRecommendedVersion();
301                 }
302 
303             }
304         }
305         return null;
306     }
307 
308     /**
309      * Search for a configuration setting of an other plugin for a configuration setting.
310      *
311      * @todo there should be a better way to do this
312      * @param project the current maven project to get the configuration from.
313      * @param pluginId the group id and artifact id of the plugin to search for
314      * @param optionName the option to get from the configuration
315      * @param defaultValue the default value if the configuration was not found
316      * @return the value of the option configured in the plugin configuration
317      */
318     public static String getPluginSetting( MavenProject project, String pluginId, String optionName, String defaultValue )
319     {
320         Xpp3Dom dom = getPluginConfigurationDom( project, pluginId );
321         if ( dom != null && dom.getChild( optionName ) != null )
322         {
323             return dom.getChild( optionName ).getValue();
324         }
325         return defaultValue;
326     }
327 
328     /**
329      * Search for the configuration Xpp3 dom of an other plugin.
330      *
331      * @todo there should be a better way to do this
332      * @param project the current maven project to get the configuration from.
333      * @param pluginId the group id and artifact id of the plugin to search for
334      * @return the value of the option configured in the plugin configuration
335      */
336     public static Xpp3Dom getPluginConfigurationDom( MavenProject project, String pluginId )
337     {
338 
339         Plugin plugin = (org.apache.maven.model.Plugin) project.getBuild().getPluginsAsMap().get( pluginId );
340         if ( plugin != null )
341         {
342             // TODO: This may cause ClassCastExceptions eventually, if the dom impls differ.
343             return (Xpp3Dom) plugin.getConfiguration();
344         }
345         return null;
346     }
347 
348     /**
349      * Search for the configuration Xpp3 dom of an other plugin.
350      *
351      * @todo there should be a better way to do this
352      * @param project the current maven project to get the configuration from.
353      * @param artifactId the artifact id of the plugin to search for
354      * @return the value of the option configured in the plugin configuration
355      */
356     public static Xpp3Dom[] getPluginConfigurationDom( MavenProject project, String artifactId,
357                                                        String[] subConfiguration )
358     {
359         ArrayList configurationDomList = new ArrayList();
360         Xpp3Dom configuration = getPluginConfigurationDom( project, artifactId );
361         if ( configuration != null )
362         {
363             configurationDomList.add( configuration );
364             for ( int index = 0; !configurationDomList.isEmpty() && subConfiguration != null
365                 && index < subConfiguration.length; index++ )
366             {
367                 ArrayList newConfigurationDomList = new ArrayList();
368                 for ( Iterator childElement = configurationDomList.iterator(); childElement.hasNext(); )
369                 {
370                     Xpp3Dom child = (Xpp3Dom) childElement.next();
371                     Xpp3Dom[] deeperChild = child.getChildren( subConfiguration[index] );
372                     for ( int deeperIndex = 0; deeperIndex < deeperChild.length; deeperIndex++ )
373                     {
374                         if ( deeperChild[deeperIndex] != null )
375                         {
376                             newConfigurationDomList.add( deeperChild[deeperIndex] );
377                         }
378                     }
379                 }
380                 configurationDomList = newConfigurationDomList;
381             }
382         }
383         return (Xpp3Dom[]) configurationDomList.toArray( new Xpp3Dom[configurationDomList.size()] );
384     }
385 
386     /**
387      * Calculate the project name template from the specified value <code>projectNameTemplate</code>,
388      * <code>addVersionToProjectName</code> and <code>addGroupIdToProjectName</code>
389      * <p>
390      * Note: if projectNameTemplate is not null then that value will be used regardless of the values for
391      * addVersionToProjectName or addGroupIdToProjectName and a warning will be issued.
392      *
393      * @param projectNameTemplate the current projectNameTemplate, if available
394      * @param addVersionToProjectName whether to include Version in the project name
395      * @param addGroupIdToProjectName whether to include GroupId in the project name.
396      * @return the project name template.
397      */
398     public static String calculateProjectNameTemplate( String projectNameTemplate, boolean addVersionToProjectName,
399                                                        boolean addGroupIdToProjectName, Log log )
400     {
401         if ( projectNameTemplate != null )
402         {
403             if ( addVersionToProjectName || addGroupIdToProjectName )
404             {
405                 log.warn( "projectNameTemplate definition overrides "
406                     + "addVersionToProjectName or addGroupIdToProjectName" );
407             }
408             return projectNameTemplate;
409         }
410         else if ( addVersionToProjectName && addGroupIdToProjectName )
411         {
412             return IdeUtils.PROJECT_NAME_WITH_GROUP_AND_VERSION_TEMPLATE;
413         }
414         else if ( addVersionToProjectName )
415         {
416             return IdeUtils.PROJECT_NAME_WITH_VERSION_TEMPLATE;
417         }
418         else if ( addGroupIdToProjectName )
419         {
420             return IdeUtils.PROJECT_NAME_WITH_GROUP_TEMPLATE;
421         }
422         return IdeUtils.PROJECT_NAME_DEFAULT_TEMPLATE;
423     }
424 
425     /**
426      * Use {@link IdeDependency#getEclipseProjectName()} instead.
427      */
428     protected static String getProjectName( String template, IdeDependency dep )
429     {
430         return getProjectName( template, dep.getGroupId(), dep.getArtifactId(), dep.getVersion() );
431     }
432 
433     /**
434      * Use the project name template to create an eclipse project.
435      *
436      * @param template Template for the project name
437      * @param artifact the artifact to create the project name for
438      * @return the created ide project name
439      */
440     public static String getProjectName( String template, Artifact artifact )
441     {
442         return getProjectName( template, artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion() );
443     }
444 
445     public static String getProjectName( String template, MavenProject project )
446     {
447         return getProjectName( template, project.getGroupId(), project.getArtifactId(), project.getVersion() );
448     }
449 
450     public static String getProjectName( MavenProject project, boolean addVersionToProjectName )
451     {
452         return getProjectName( addVersionToProjectName ? PROJECT_NAME_WITH_VERSION_TEMPLATE
453                         : PROJECT_NAME_DEFAULT_TEMPLATE, project );
454     }
455 
456     /**
457      * @param artifact the artifact
458      * @return the not-available marker file for the specified artifact
459      */
460     public static File getNotAvailableMarkerFile( ArtifactRepository localRepository, Artifact artifact )
461     {
462         return new File( localRepository.getBasedir(), localRepository.pathOf( artifact )
463             + NOT_AVAILABLE_MARKER_FILE_SUFFIX );
464     }
465 
466     /**
467      * Wrapper around {@link ArtifactResolver#resolve(Artifact, List, ArtifactRepository)}
468      *
469      * @param artifactResolver see {@link ArtifactResolver#resolve(Artifact, List, ArtifactRepository)}
470      * @param artifact see {@link ArtifactResolver#resolve(Artifact, List, ArtifactRepository)}
471      * @param remoteRepos see {@link ArtifactResolver#resolve(Artifact, List, ArtifactRepository)}
472      * @param localRepository see {@link ArtifactResolver#resolve(Artifact, List, ArtifactRepository)}
473      * @param log Logger
474      * @return the artifact, resolved if possible.
475      */
476     public static Artifact resolveArtifact( ArtifactResolver artifactResolver, Artifact artifact, List remoteRepos,
477                                             ArtifactRepository localRepository, Log log )
478 
479     {
480         try
481         {
482             artifactResolver.resolve( artifact, remoteRepos, localRepository );
483         }
484         catch ( ArtifactNotFoundException e )
485         {
486             // ignore, the jar has not been found
487 
488             /*
489              * This method gets called with no remote repositories to avoid remote trips (which would ideally be
490              * realized by means of a per-request offline flag), the set of available remote repos can however affect
491              * the resolution from the local repo as well, in particular in Maven 3. So double check whether the local
492              * file is really not present.
493              */
494             if ( artifact.getFile() != null && artifact.getFile().isFile() )
495             {
496                 artifact.setResolved( true );
497             }
498         }
499         catch ( ArtifactResolutionException e )
500         {
501             String message =
502                 Messages.getString( "IdeUtils.errorresolving", new Object[] { artifact.getClassifier(),
503                     artifact.getId(), e.getMessage() } );
504 
505             log.warn( message );
506         }
507 
508         return artifact;
509     }
510 
511     /**
512      * Wrap {@link ArtifactFactory#createArtifactWithClassifier} so that the type and classifier are set correctly for
513      * "sources" and "javadoc".
514      *
515      * @param groupId see {@link ArtifactFactory#createArtifactWithClassifier}
516      * @param artifactId see {@link ArtifactFactory#createArtifactWithClassifier}
517      * @param version see {@link ArtifactFactory#createArtifactWithClassifier}
518      * @param depClassifier see {@link ArtifactFactory#createArtifactWithClassifier}
519      * @param inClassifier either "sources" of "javadoc"
520      * @param artifactFactory see {@link ArtifactFactory#createArtifactWithClassifier}
521      * @return see {@link ArtifactFactory#createArtifactWithClassifier}
522      * @see ArtifactFactory#createArtifactWithClassifier
523      */
524     public static Artifact createArtifactWithClassifier( String groupId, String artifactId, String version,
525                                                          String depClassifier, String inClassifier,
526                                                          ArtifactFactory artifactFactory )
527     {
528         String type = null;
529 
530         // the "sources" classifier maps to the "java-source" type
531         if ( "sources".equals( inClassifier ) )
532         {
533             type = "java-source";
534         }
535         else
536         {
537             type = inClassifier;
538         }
539 
540         String finalClassifier = null;
541         if ( depClassifier == null )
542         {
543             finalClassifier = inClassifier;
544         }
545         else if ( "sources".equals( inClassifier ) && "tests".equals( depClassifier ) )
546         {
547             // MECLIPSE-151 - if the dependency is a test, get the correct classifier for it. (ignore for javadocs)
548             finalClassifier = "test-sources";
549         }
550         else
551         {
552             finalClassifier = depClassifier + "-" + inClassifier;
553         }
554 
555         return artifactFactory.createArtifactWithClassifier( groupId, artifactId, version, type, finalClassifier );
556     }
557 
558     public static String resolveJavaVersion( MavenProject project )
559     {
560         String version = IdeUtils.getCompilerTargetVersion( project );
561         if ( version == null )
562         {
563             version = IdeUtils.getCompilerSourceVersion( project );
564         }
565 
566         if ( "1.5".equals( version ) ) //$NON-NLS-1$
567         {
568             version = IdeUtils.JAVA_5_0;// see MECLIPSE-47 eclipse only accept 5.0 as a valid version
569         }
570         else if ( "1.6".equals( version ) ) //$NON-NLS-1$
571         {
572             version = IdeUtils.JAVA_6_0;
573         }
574         else if ( version != null && version.length() == 1 )
575         {
576             version = version + ".0";// 5->5.0 6->6.0 7->7.0 //$NON-NLS-1$
577         }
578 
579         return version == null ? IdeUtils.JAVA_1_4 : version;
580     }
581 
582     public static String toRelativeAndFixSeparator( File basedir, File fileToAdd, boolean replaceSlashesWithDashes )
583         throws MojoExecutionException
584     {
585         if ( !fileToAdd.isAbsolute() )
586         {
587             fileToAdd = new File( basedir, fileToAdd.getPath() );
588         }
589 
590         String basedirPath = getCanonicalPath( basedir );
591         String absolutePath = getCanonicalPath( fileToAdd );
592 
593         String relative = null;
594 
595         if ( absolutePath.equals( basedirPath ) )
596         {
597             relative = "."; //$NON-NLS-1$
598         }
599         else if ( absolutePath.startsWith( basedirPath ) )
600         {
601             // MECLIPSE-261
602             // The canonical form of a windows root dir ends in a slash, whereas the canonical form of any other file
603             // does not.
604             // The absolutePath is assumed to be: basedirPath + Separator + fileToAdd
605             // In the case of a windows root directory the Separator is missing since it is contained within
606             // basedirPath.
607             int length = basedirPath.length() + 1;
608             if ( basedirPath.endsWith( "\\" ) )
609             {
610                 length--;
611             }
612             relative = absolutePath.substring( length );
613         }
614         else
615         {
616             relative = absolutePath;
617         }
618 
619         relative = fixSeparator( relative );
620 
621         if ( replaceSlashesWithDashes )
622         {
623             relative = StringUtils.replace( relative, '/', '-' );
624             relative = StringUtils.replace( relative, ':', '-' ); // remove ":" for absolute paths in windows
625         }
626 
627         return relative;
628     }
629 
630     /**
631      * Convert the provided filename from a Windows separator \\ to a unix/java separator /
632      *
633      * @param filename file name to fix separator
634      * @return filename with all \\ replaced with /
635      */
636     public static String fixSeparator( String filename )
637     {
638         return StringUtils.replace( filename, '\\', '/' );
639     }
640 
641     /**
642      * NOTE: This is to account for the unfortunate fact that "file:" URIs differ between Windows and Unix. On a Windows
643      * box, the path "C:\dir" is mapped to "file:/C:/dir". On a Unix box, the path "/home/dir" is mapped to
644      * "file:/home/dir". So, in the first case the slash after "file:" is not part of the corresponding filesystem path
645      * while in the later case it is. This discrepancy makes verifying the javadoc attachments in ".classpath" a little
646      * tricky.
647      *
648      * @param input string input that may contain a windows URI
649      * @return all windows URI convert "file:C:/dir" to "file:/C:/dir"
650      */
651     public static String fixWindowsDriveURI( String input )
652     {
653         return input.replaceAll( "file:([a-zA-Z]):", "file:/$1:" );
654     }
655 
656     /**
657      * Returns a compiler plugin settings from a list of plugins .
658      *
659      * @param project maven project
660      * @return option value (may be null)
661      */
662     private static String findCompilerPluginSettingInPlugins( List plugins, String optionName )
663     {
664         String value = null;
665 
666         for ( Iterator it = plugins.iterator(); it.hasNext(); )
667         {
668             Plugin plugin = (Plugin) it.next();
669 
670             if ( plugin.getArtifactId().equals( ARTIFACT_MAVEN_COMPILER_PLUGIN ) )
671             {
672                 // TODO: This may cause ClassCastExceptions eventually, if the dom impls differ.
673                 Xpp3Dom o = (Xpp3Dom) plugin.getConfiguration();
674 
675                 // this is the default setting
676                 if ( o != null && o.getChild( optionName ) != null )
677                 {
678                     value = o.getChild( optionName ).getValue();
679                 }
680 
681                 List executions = plugin.getExecutions();
682 
683                 // a different source/target version can be configured for test sources compilation
684                 for ( Iterator iter = executions.iterator(); iter.hasNext(); )
685                 {
686                     PluginExecution execution = (PluginExecution) iter.next();
687 
688                     // TODO: This may cause ClassCastExceptions eventually, if the dom impls differ.
689                     o = (Xpp3Dom) execution.getConfiguration();
690 
691                     if ( o != null && o.getChild( optionName ) != null )
692                     {
693                         value = o.getChild( optionName ).getValue();
694                     }
695                 }
696             }
697         }
698         return value;
699     }
700 
701     private static String getProjectName( String template, String groupId, String artifactId, String version )
702     {
703         String s = template;
704         s = s.replaceAll( "\\[groupId\\]", groupId );
705         s = s.replaceAll( "\\[artifactId\\]", artifactId );
706         s = s.replaceAll( "\\[version\\]", version );
707         return s;
708     }
709 
710     private IdeUtils()
711     {
712         // don't instantiate
713     }
714 }