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 597410 2007-11-22 13:59:27Z 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     public static String getProjectName( String template, IdeDependency dep )
270     {
271         return getProjectName( template, dep.getGroupId(), dep.getArtifactId(), dep.getVersion() );
272     }
273 
274     /**
275      * Use the project name template to create an eclipse project.
276      * 
277      * @param template Template for the project name
278      * @param artifact the artifact to create the project name for
279      * @return the created ide project name
280      */
281     public static String getProjectName( String template, Artifact artifact )
282     {
283         return getProjectName( template, artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion() );
284     }
285 
286     public static String getProjectName( String template, MavenProject project )
287     {
288         return getProjectName( template, project.getGroupId(), project.getArtifactId(), project.getVersion() );
289     }
290 
291     public static String getProjectName( IdeDependency dep, boolean addVersionToProjectName )
292     {
293         return getProjectName( addVersionToProjectName ? PROJECT_NAME_WITH_VERSION_TEMPLATE
294                         : PROJECT_NAME_DEFAULT_TEMPLATE, dep );
295     }
296 
297     public static String getProjectName( MavenProject project, boolean addVersionToProjectName )
298     {
299         return getProjectName( addVersionToProjectName ? PROJECT_NAME_WITH_VERSION_TEMPLATE
300                         : PROJECT_NAME_DEFAULT_TEMPLATE, project );
301     }
302 
303     public static Artifact resolveArtifactWithClassifier( String groupId, String artifactId, String version,
304                                                           String classifier, ArtifactRepository localRepository,
305                                                           ArtifactResolver artifactResolver,
306                                                           ArtifactFactory artifactFactory, List remoteRepos, Log log )
307 
308     {
309         String type = classifier;
310 
311         // the "sources" classifier maps to the "java-source" type
312         if ( "sources".equals( type ) || "test-sources".equals( type ) ) //$NON-NLS-1$
313         {
314             type = "java-source"; //$NON-NLS-1$
315         }
316 
317         Artifact resolvedArtifact =
318             artifactFactory.createArtifactWithClassifier( groupId, artifactId, version, type, classifier );
319 
320         try
321         {
322             artifactResolver.resolve( resolvedArtifact, remoteRepos, localRepository );
323         }
324         catch ( ArtifactNotFoundException e )
325         {
326             // ignore, the jar has not been found
327         }
328         catch ( ArtifactResolutionException e )
329         {
330             String message = Messages.getString( "errorresolving", new Object[] { //$NON-NLS-1$
331                                                  classifier, resolvedArtifact.getId(), e.getMessage() } );
332 
333             log.warn( message );
334         }
335 
336         return resolvedArtifact;
337     }
338 
339     public static String resolveJavaVersion( MavenProject project )
340     {
341         String version = IdeUtils.getCompilerTargetVersion( project );
342         if ( version == null )
343         {
344             version = IdeUtils.getCompilerSourceVersion( project );
345         }
346 
347         if ( "1.5".equals( version ) ) //$NON-NLS-1$ //$NON-NLS-2$
348         {
349             version = IdeUtils.JAVA_5_0;// see MECLIPSE-47 eclipse only accept 5.0 as a valid version //$NON-NLS-1$
350         }
351         else if ( "1.6".equals( version ) ) //$NON-NLS-1$ //$NON-NLS-2$
352         {
353             version = IdeUtils.JAVA_6_0;
354         }
355         else if ( version != null && version.length() == 1 )
356         {
357             version = version + ".0";// 5->5.0 6->6.0 7->7.0 //$NON-NLS-1$
358         }
359 
360         return version == null ? IdeUtils.JAVA_1_4 : version; //$NON-NLS-1$
361     }
362 
363     public static String toRelativeAndFixSeparator( File basedir, File fileToAdd, boolean replaceSlashesWithDashes )
364         throws MojoExecutionException
365     {
366         if ( !fileToAdd.isAbsolute() )
367         {
368             fileToAdd = new File( basedir, fileToAdd.getPath() );
369         }
370 
371         String basedirpath;
372         String absolutePath;
373 
374         basedirpath = getCanonicalPath( basedir );
375         absolutePath = getCanonicalPath( fileToAdd );
376 
377         String relative;
378 
379         if ( absolutePath.equals( basedirpath ) )
380         {
381             relative = "."; //$NON-NLS-1$
382         }
383         else if ( absolutePath.startsWith( basedirpath ) )
384         {
385             relative = absolutePath.substring( basedirpath.length() + 1 );
386         }
387         else
388         {
389             relative = absolutePath;
390         }
391 
392         relative = StringUtils.replace( relative, '\\', '/' );
393 
394         if ( replaceSlashesWithDashes )
395         {
396             relative = StringUtils.replace( relative, '/', '-' );
397             relative = StringUtils.replace( relative, ':', '-' ); // remove ":" for absolute paths in windows
398         }
399 
400         return relative;
401     }
402 
403     /**
404      * Returns a compiler plugin settings from a list of plugins .
405      * 
406      * @param project maven project
407      * @return option value (may be null)
408      */
409     private static String findCompilerPluginSettingInPlugins( List plugins, String optionName )
410     {
411         String value = null;
412 
413         for ( Iterator it = plugins.iterator(); it.hasNext(); )
414         {
415             Plugin plugin = (Plugin) it.next();
416 
417             if ( plugin.getArtifactId().equals( ARTIFACT_MAVEN_COMPILER_PLUGIN ) )
418             {
419                 Xpp3Dom o = (Xpp3Dom) plugin.getConfiguration();
420 
421                 // this is the default setting
422                 if ( o != null && o.getChild( optionName ) != null )
423                 {
424                     value = o.getChild( optionName ).getValue();
425                 }
426 
427                 List executions = plugin.getExecutions();
428 
429                 // a different source/target version can be configured for test sources compilation
430                 for ( Iterator iter = executions.iterator(); iter.hasNext(); )
431                 {
432                     PluginExecution execution = (PluginExecution) iter.next();
433                     o = (Xpp3Dom) execution.getConfiguration();
434 
435                     if ( o != null && o.getChild( optionName ) != null )
436                     {
437                         value = o.getChild( optionName ).getValue();
438                     }
439                 }
440             }
441         }
442         return value;
443     }
444 
445     private static String getProjectName( String template, String groupId, String artifactId, String version )
446     {
447         String s = template;
448         s = s.replaceAll( "\\[groupId\\]", groupId );
449         s = s.replaceAll( "\\[artifactId\\]", artifactId );
450         s = s.replaceAll( "\\[version\\]", version );
451         return s;
452     }
453 
454     private IdeUtils()
455     {
456         // don't instantiate
457     }
458 }