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.model.Dependency;
34  import org.apache.maven.model.Plugin;
35  import org.apache.maven.model.PluginExecution;
36  import org.apache.maven.plugin.MojoExecutionException;
37  import org.apache.maven.plugin.logging.Log;
38  import org.apache.maven.project.MavenProject;
39  import org.codehaus.plexus.util.StringUtils;
40  import org.codehaus.plexus.util.xml.Xpp3Dom;
41  
42  /**
43   * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
44   * @author <a href="mailto:fgiust@users.sourceforge.net">Fabrizio Giustina</a>
45   * @version $Id: IdeUtils.java 628794 2008-02-18 16:09:11Z aheritier $
46   */
47  public class IdeUtils
48  {
49      public static final String JAVA_1_1 = "1.1";
50  
51      public static final String JAVA_1_2 = "1.2";
52  
53      public static final String JAVA_1_3 = "1.3";
54  
55      public static final String JAVA_1_4 = "1.4";
56  
57      public static final String JAVA_5_0 = "5.0";
58  
59      public static final String JAVA_6_0 = "6.0";
60  
61      public static final String PROJECT_NAME_DEFAULT_TEMPLATE = "[artifactId]";
62  
63      public static final String PROJECT_NAME_WITH_VERSION_TEMPLATE = "[artifactId]-[version]";
64  
65      public static final String PROJECT_NAME_WITH_GROUP_TEMPLATE = "[groupId].[artifactId]";
66  
67      public static final String PROJECT_NAME_WITH_GROUP_AND_VERSION_TEMPLATE = "[groupId].[artifactId]-[version]";
68  
69      /**
70       * compiler plugin id.
71       */
72      private static final String ARTIFACT_MAVEN_COMPILER_PLUGIN = "maven-compiler-plugin"; //$NON-NLS-1$
73  
74      /**
75       * 'source' property for maven-compiler-plugin.
76       */
77      private static final String PROPERTY_SOURCE = "source"; //$NON-NLS-1$
78  
79      /**
80       * 'target' property for maven-compiler-plugin.
81       */
82      private static final String PROPERTY_TARGET = "target"; //$NON-NLS-1$
83  
84      public static String getCanonicalPath( File file )
85          throws MojoExecutionException
86      {
87          try
88          {
89              return file.getCanonicalPath();
90          }
91          catch ( IOException e )
92          {
93              throw new MojoExecutionException( Messages.getString( "cantcanonicalize", file //$NON-NLS-1$
94              .getAbsolutePath() ), e );
95          }
96      }
97  
98      /**
99       * Returns a compiler plugin settings, considering also settings altered in plugin executions .
100      * 
101      * @param project maven project
102      * @return option value (may be null)
103      */
104     public static String getCompilerPluginSetting( MavenProject project, String optionName )
105     {
106         String value = findCompilerPluginSettingInPlugins( project.getModel().getBuild().getPlugins(), optionName );
107         if ( value == null && project.getModel().getBuild().getPluginManagement() != null )
108         {
109             value =
110                 findCompilerPluginSettingInPlugins( project.getModel().getBuild().getPluginManagement().getPlugins(),
111                                                     optionName );
112         }
113         return value;
114     }
115 
116     /**
117      * Returns the source version configured for the compiler plugin. Returns the minimum version required to compile
118      * both standard and test sources, if settings are different.
119      * 
120      * @param project maven project
121      * @return java source version
122      */
123     public static String getCompilerSourceVersion( MavenProject project )
124     {
125         return IdeUtils.getCompilerPluginSetting( project, PROPERTY_SOURCE );
126     }
127 
128     /**
129      * Returns the target version configured for the compiler plugin. Returns the minimum version required to compile
130      * both standard and test sources, if settings are different.
131      * 
132      * @param project maven project
133      * @return java target version
134      */
135     public static String getCompilerTargetVersion( MavenProject project )
136     {
137         return IdeUtils.getCompilerPluginSetting( project, PROPERTY_TARGET );
138     }
139 
140     // /**
141     // * Extracts the version of the first matching dependency in the given list.
142     // *
143     // * @param artifactIds artifact names to compare against for extracting version
144     // * @param dependencies Collection of dependencies for our project
145     // * @param len expected length of the version sub-string
146     // * @return
147     // */
148     // public static String getDependencyVersion( String[] artifactIds, List dependencies, int len )
149     // {
150     // for ( int j = 0; j < artifactIds.length; j++ )
151     // {
152     // String id = artifactIds[j];
153     // for ( Iterator itr = dependencies.iterator(); itr.hasNext(); )
154     // {
155     // Dependency dependency = (Dependency) itr.next();
156     // if ( id.equals( dependency.getArtifactId() ) )
157     // {
158     // return StringUtils.substring( dependency.getVersion(), 0, len );
159     // }
160     // }
161     // }
162     // return null;
163     // }
164 
165     /**
166      * Extracts the version of the first matching artifact in the given list.
167      * 
168      * @param artifactIds artifact names to compare against for extracting version
169      * @param artifacts Set of artifacts for our project
170      * @param len expected length of the version sub-string
171      * @return
172      */
173     public static String getArtifactVersion( String[] artifactIds, List dependencies, int len )
174     {
175         for ( int j = 0; j < artifactIds.length; j++ )
176         {
177             String id = artifactIds[j];
178             Iterator depIter = dependencies.iterator();
179             while ( depIter.hasNext() )
180             {
181                 Dependency dep = (Dependency) depIter.next();
182                 if ( id.equals( dep.getArtifactId() ) )
183                 {
184                     return StringUtils.substring( dep.getVersion(), 0, len );
185                 }
186 
187             }
188         }
189         return null;
190     }
191 
192     /**
193      * Search for a configuration setting of an other plugin for a configuration setting.
194      * 
195      * @todo there should be a better way to do this
196      * @param project the current maven project to get the configuration from.
197      * @param pluginId the group id and artifact id of the plugin to search for
198      * @param optionName the option to get from the configuration
199      * @param defaultValue the default value if the configuration was not found
200      * @return the value of the option configured in the plugin configuration
201      */
202     public static String getPluginSetting( MavenProject project, String pluginId, String optionName, String defaultValue )
203     {
204         Xpp3Dom dom = getPluginConfigurationDom( project, pluginId );
205         if ( dom != null && dom.getChild( optionName ) != null )
206         {
207             return dom.getChild( optionName ).getValue();
208         }
209         return defaultValue;
210     }
211 
212     /**
213      * Search for the configuration Xpp3 dom of an other plugin.
214      * 
215      * @todo there should be a better way to do this
216      * @param project the current maven project to get the configuration from.
217      * @param pluginId the group id and artifact id of the plugin to search for
218      * @return the value of the option configured in the plugin configuration
219      */
220     public static Xpp3Dom getPluginConfigurationDom( MavenProject project, String pluginId )
221     {
222 
223         Plugin plugin = (org.apache.maven.model.Plugin) project.getBuild().getPluginsAsMap().get( pluginId );
224         if ( plugin != null )
225         {
226             return (Xpp3Dom) plugin.getConfiguration();
227         }
228         return null;
229     }
230 
231     /**
232      * Search for the configuration Xpp3 dom of an other plugin.
233      * 
234      * @todo there should be a better way to do this
235      * @param project the current maven project to get the configuration from.
236      * @param artifactId the artifact id of the plugin to search for
237      * @return the value of the option configured in the plugin configuration
238      */
239     public static Xpp3Dom[] getPluginConfigurationDom( MavenProject project, String artifactId,
240                                                        String[] subConfiguration )
241     {
242         ArrayList configurationDomList = new ArrayList();
243         Xpp3Dom configuration = getPluginConfigurationDom( project, artifactId );
244         if ( configuration != null )
245         {
246             configurationDomList.add( configuration );
247             for ( int index = 0; !configurationDomList.isEmpty() && subConfiguration != null &&
248                 index < subConfiguration.length; index++ )
249             {
250                 ArrayList newConfigurationDomList = new ArrayList();
251                 for ( Iterator childElement = configurationDomList.iterator(); childElement.hasNext(); )
252                 {
253                     Xpp3Dom child = (Xpp3Dom) childElement.next();
254                     Xpp3Dom[] deeperChild = child.getChildren( subConfiguration[index] );
255                     for ( int deeperIndex = 0; deeperIndex < deeperChild.length; deeperIndex++ )
256                     {
257                         if ( deeperChild[deeperIndex] != null )
258                         {
259                             newConfigurationDomList.add( deeperChild[deeperIndex] );
260                         }
261                     }
262                 }
263                 configurationDomList = newConfigurationDomList;
264             }
265         }
266         return (Xpp3Dom[]) configurationDomList.toArray( new Xpp3Dom[configurationDomList.size()] );
267     }
268 
269     /**
270      * Use {@link IdeDependency#getEclipseProjectName()} instead.
271      */
272     protected static String getProjectName( String template, IdeDependency dep )
273     {
274         return getProjectName( template, dep.getGroupId(), dep.getArtifactId(), dep.getVersion() );
275     }
276 
277     /**
278      * Use the project name template to create an eclipse project.
279      * 
280      * @param template Template for the project name
281      * @param artifact the artifact to create the project name for
282      * @return the created ide project name
283      */
284     public static String getProjectName( String template, Artifact artifact )
285     {
286         return getProjectName( template, artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion() );
287     }
288 
289     public static String getProjectName( String template, MavenProject project )
290     {
291         return getProjectName( template, project.getGroupId(), project.getArtifactId(), project.getVersion() );
292     }
293 
294     private static String getProjectName( IdeDependency dep, boolean addVersionToProjectName )
295     {
296         return getProjectName( addVersionToProjectName ? PROJECT_NAME_WITH_VERSION_TEMPLATE
297                         : PROJECT_NAME_DEFAULT_TEMPLATE, dep );
298     }
299 
300     public static String getProjectName( MavenProject project, boolean addVersionToProjectName )
301     {
302         return getProjectName( addVersionToProjectName ? PROJECT_NAME_WITH_VERSION_TEMPLATE
303                         : PROJECT_NAME_DEFAULT_TEMPLATE, project );
304     }
305 
306     public static Artifact resolveArtifactWithClassifier( String groupId, String artifactId, String version,
307                                                           String depClassifier, String inClassifier,
308                                                           ArtifactRepository localRepository,
309                                                           ArtifactResolver artifactResolver,
310                                                           ArtifactFactory artifactFactory, List remoteRepos, Log log )
311 
312     {
313         String type = null;
314 
315         // the "sources" classifier maps to the "java-source" type
316         if ( "sources".equals( inClassifier ) )
317         {
318             type = "java-source";
319         }
320         else
321         {
322             type = inClassifier;
323         }
324 
325         String finalClassifier = null;
326         if ( depClassifier == null )
327         {
328             finalClassifier = inClassifier;
329         }
330         else if ( "sources".equals( inClassifier ) && "tests".equals( depClassifier ) )
331         {
332             // MECLIPSE-151 - if the dependency is a test, get the correct classifier for it. (ignore for javadocs)
333             finalClassifier = "test-sources";
334         }
335         else
336         {
337             finalClassifier = depClassifier + "-" + inClassifier;
338         }
339 
340         Artifact resolvedArtifact =
341             artifactFactory.createArtifactWithClassifier( groupId, artifactId, version, type, finalClassifier );
342 
343         try
344         {
345             artifactResolver.resolve( resolvedArtifact, remoteRepos, localRepository );
346         }
347         catch ( ArtifactNotFoundException e )
348         {
349             // ignore, the jar has not been found
350         }
351         catch ( ArtifactResolutionException e )
352         {
353             String message =
354                 Messages.getString( "errorresolving", new Object[] { finalClassifier, resolvedArtifact.getId(),
355                     e.getMessage() } );
356 
357             log.warn( message );
358         }
359 
360         return resolvedArtifact;
361     }
362 
363     public static String resolveJavaVersion( MavenProject project )
364     {
365         String version = IdeUtils.getCompilerTargetVersion( project );
366         if ( version == null )
367         {
368             version = IdeUtils.getCompilerSourceVersion( project );
369         }
370 
371         if ( "1.5".equals( version ) ) //$NON-NLS-1$ 
372         {
373             version = IdeUtils.JAVA_5_0;// see MECLIPSE-47 eclipse only accept 5.0 as a valid version
374         }
375         else if ( "1.6".equals( version ) ) //$NON-NLS-1$ 
376         {
377             version = IdeUtils.JAVA_6_0;
378         }
379         else if ( version != null && version.length() == 1 )
380         {
381             version = version + ".0";// 5->5.0 6->6.0 7->7.0 //$NON-NLS-1$
382         }
383 
384         return version == null ? IdeUtils.JAVA_1_4 : version;
385     }
386 
387     public static String toRelativeAndFixSeparator( File basedir, File fileToAdd, boolean replaceSlashesWithDashes )
388         throws MojoExecutionException
389     {
390         if ( !fileToAdd.isAbsolute() )
391         {
392             fileToAdd = new File( basedir, fileToAdd.getPath() );
393         }
394 
395         String basedirpath;
396         String absolutePath;
397 
398         basedirpath = getCanonicalPath( basedir );
399         absolutePath = getCanonicalPath( fileToAdd );
400 
401         String relative;
402 
403         if ( absolutePath.equals( basedirpath ) )
404         {
405             relative = "."; //$NON-NLS-1$
406         }
407         else if ( absolutePath.startsWith( basedirpath ) )
408         {
409             relative = absolutePath.substring( basedirpath.length() + 1 );
410         }
411         else
412         {
413             relative = absolutePath;
414         }
415 
416         relative = StringUtils.replace( relative, '\\', '/' );
417 
418         if ( replaceSlashesWithDashes )
419         {
420             relative = StringUtils.replace( relative, '/', '-' );
421             relative = StringUtils.replace( relative, ':', '-' ); // remove ":" for absolute paths in windows
422         }
423 
424         return relative;
425     }
426 
427     /**
428      * Returns a compiler plugin settings from a list of plugins .
429      * 
430      * @param project maven project
431      * @return option value (may be null)
432      */
433     private static String findCompilerPluginSettingInPlugins( List plugins, String optionName )
434     {
435         String value = null;
436 
437         for ( Iterator it = plugins.iterator(); it.hasNext(); )
438         {
439             Plugin plugin = (Plugin) it.next();
440 
441             if ( plugin.getArtifactId().equals( ARTIFACT_MAVEN_COMPILER_PLUGIN ) )
442             {
443                 Xpp3Dom o = (Xpp3Dom) plugin.getConfiguration();
444 
445                 // this is the default setting
446                 if ( o != null && o.getChild( optionName ) != null )
447                 {
448                     value = o.getChild( optionName ).getValue();
449                 }
450 
451                 List executions = plugin.getExecutions();
452 
453                 // a different source/target version can be configured for test sources compilation
454                 for ( Iterator iter = executions.iterator(); iter.hasNext(); )
455                 {
456                     PluginExecution execution = (PluginExecution) iter.next();
457                     o = (Xpp3Dom) execution.getConfiguration();
458 
459                     if ( o != null && o.getChild( optionName ) != null )
460                     {
461                         value = o.getChild( optionName ).getValue();
462                     }
463                 }
464             }
465         }
466         return value;
467     }
468 
469     private static String getProjectName( String template, String groupId, String artifactId, String version )
470     {
471         String s = template;
472         s = s.replaceAll( "\\[groupId\\]", groupId );
473         s = s.replaceAll( "\\[artifactId\\]", artifactId );
474         s = s.replaceAll( "\\[version\\]", version );
475         return s;
476     }
477 
478     private IdeUtils()
479     {
480         // don't instantiate
481     }
482 }