View Javadoc

1   package org.apache.maven.model.converter;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.model.Model;
23  import org.apache.maven.model.converter.plugins.PluginConfigurationConverter;
24  import org.apache.maven.model.converter.relocators.PluginRelocator;
25  import org.apache.maven.model.converter.relocators.PluginRelocatorManager;
26  import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
27  import org.apache.maven.model.v3_0_0.io.xpp3.MavenXpp3Reader;
28  import org.codehaus.plexus.logging.AbstractLogEnabled;
29  import org.apache.maven.shared.utils.io.IOUtil;
30  import org.dom4j.Document;
31  import org.dom4j.Element;
32  import org.dom4j.io.SAXReader;
33  
34  import java.io.File;
35  import java.io.FileInputStream;
36  import java.io.FileReader;
37  import java.io.FileWriter;
38  import java.io.IOException;
39  import java.io.InputStream;
40  import java.io.Writer;
41  import java.util.ArrayList;
42  import java.util.Collection;
43  import java.util.Collections;
44  import java.util.Iterator;
45  import java.util.List;
46  import java.util.Properties;
47  
48  /**
49   * Converts a Maven 1 project.xml (v3 pom) to a Maven 2 pom.xml (v4 pom).
50   *
51   * @author Fabrizio Giustina
52   * @author Dennis Lundberg
53   * @version $Id: Maven1Converter.java 1379502 2012-08-31 16:43:35Z struberg $
54   * @plexus.component role="org.apache.maven.model.converter.Maven1Converter"
55   */
56  public class Maven1Converter
57      extends AbstractLogEnabled
58  {
59      /**
60       * Available converters for specific plugin configurations
61       *
62       * @plexus.requirement role="org.apache.maven.model.converter.plugins.PluginConfigurationConverter"
63       */
64      private List converters;
65  
66      /**
67       * Plexus component that manages plugin relocators
68       *
69       * @plexus.requirement
70       */
71      private PluginRelocatorManager pluginRelocatorManager;
72  
73      private File basedir;
74  
75      private File outputdir;
76  
77      private String fileName = "project.xml";
78  
79      private List listeners = new ArrayList();
80  
81      public void execute()
82          throws ProjectConverterException
83      {
84          File projectxml = new File( basedir, fileName );
85  
86          if ( !projectxml.exists() )
87          {
88              throw new ProjectConverterException( "Missing " + fileName + " in " + basedir.getAbsolutePath() );
89          }
90  
91          PomV3ToV4Translator translator = new PomV3ToV4Translator();
92  
93          org.apache.maven.model.v3_0_0.Model v3Model;
94          try
95          {
96              v3Model = loadV3Pom( projectxml );
97          }
98          catch ( Exception e )
99          {
100             throw new ProjectConverterException( "Exception caught while loading " + fileName + ". " + e.getMessage(),
101                                                  e );
102         }
103 
104         Model v4Model;
105         try
106         {
107             v4Model = translator.translate( v3Model );
108             removeDistributionManagementStatus( v4Model );
109         }
110         catch ( Exception e )
111         {
112             throw new ProjectConverterException(
113                 "Exception caught while converting " + fileName + ". " + e.getMessage(), e );
114         }
115 
116         Properties properties = new Properties();
117 
118         if ( v3Model.getExtend() != null )
119         {
120             loadProperties( properties, new File( new File( basedir, v3Model.getExtend() ).getParentFile(),
121                                                   "project.properties" ) );
122         }
123 
124         loadProperties( properties, new File( basedir, "project.properties" ) );
125 
126         for ( Iterator i = converters.iterator(); i.hasNext(); )
127         {
128             PluginConfigurationConverter converter = (PluginConfigurationConverter) i.next();
129             converter.addListeners( listeners );
130             converter.convertConfiguration( v4Model, v3Model, properties );
131         }
132 
133         // @todo Should this be run before or after the configuration converters?
134         Collection pluginRelocators = pluginRelocatorManager.getPluginRelocators();
135         sendInfoMessage( "There are " + pluginRelocators.size() + " plugin relocators available" );
136         PluginRelocator pluginRelocator;
137         Iterator iterator = pluginRelocators.iterator();
138         while ( iterator.hasNext() )
139         {
140             pluginRelocator = (PluginRelocator) iterator.next();
141             pluginRelocator.addListeners( listeners );
142             pluginRelocator.relocate( v4Model );
143         }
144 
145         // Sort the plugins
146         if ( v4Model.getBuild() != null )
147         {
148             Collections.sort( v4Model.getBuild().getPlugins(), new PluginComparator() );
149         }
150         if ( v4Model.getReporting() != null )
151         {
152             Collections.sort( v4Model.getReporting().getPlugins(), new ReportPluginComparator() );
153         }
154 
155         try
156         {
157             writeV4Pom( v4Model );
158         }
159         catch ( IOException e )
160         {
161             throw new ProjectConverterException( "Failed to write the pom.xml.", e );
162         }
163     }
164 
165     private boolean isEmpty( String value )
166     {
167         return value == null || value.trim().length() == 0;
168     }
169 
170     private void loadProperties( Properties properties, File propertiesFile )
171     {
172         if ( propertiesFile.exists() )
173         {
174             InputStream is = null;
175             try
176             {
177                 is = new FileInputStream( propertiesFile );
178                 properties.load( is );
179             }
180             catch ( IOException e )
181             {
182                 sendWarnMessage( "Unable to read " + propertiesFile.getAbsolutePath() + ", ignoring." );
183             }
184             finally
185             {
186                 IOUtil.close( is );
187             }
188         }
189     }
190 
191     private org.apache.maven.model.v3_0_0.Model loadV3Pom( File inputFile )
192         throws Exception
193     {
194         MavenXpp3Reader v3Reader = new MavenXpp3Reader();
195 
196         org.apache.maven.model.v3_0_0.Model model;
197 
198         model = v3Reader.read( new FileReader( inputFile ) );
199 
200         SAXReader r = new SAXReader();
201 
202         Document d = r.read( new FileReader( inputFile ) );
203 
204         Element root = d.getRootElement();
205 
206         Element idElement = root.element( "id" );
207 
208         String id = null;
209 
210         if ( idElement != null )
211         {
212             id = idElement.getText();
213         }
214         //        String id = model.getId();
215 
216         String groupId = model.getGroupId();
217 
218         String artifactId = model.getArtifactId();
219 
220         if ( !isEmpty( id ) )
221         {
222             int i = id.indexOf( "+" );
223 
224             int j = id.indexOf( ":" );
225 
226             if ( i > 0 )
227             {
228                 model.setGroupId( id.substring( 0, i ) );
229 
230                 model.setArtifactId( id.replace( '+', '-' ) );
231             }
232             else if ( j > 0 )
233             {
234                 model.setGroupId( id.substring( 0, j ) );
235 
236                 model.setArtifactId( id.substring( j + 1 ) );
237             }
238             else
239             {
240                 model.setGroupId( id );
241 
242                 model.setArtifactId( id );
243             }
244 
245             if ( !isEmpty( groupId ) )
246             {
247                 sendWarnMessage( "Both <id> and <groupId> is set, using <groupId>." );
248 
249                 model.setGroupId( groupId );
250             }
251 
252             if ( !isEmpty( artifactId ) )
253             {
254                 sendWarnMessage( "Both <id> and <artifactId> is set, using <artifactId>." );
255 
256                 model.setArtifactId( artifactId );
257             }
258         }
259 
260         return model;
261     }
262 
263     /**
264      * The status element of the distributionManagement section must not be
265      * set in local projects. This method removes that element from the model.
266      */
267     private void removeDistributionManagementStatus( Model v4Model )
268     {
269         if ( v4Model.getDistributionManagement() != null )
270         {
271             if ( "converted".equals( v4Model.getDistributionManagement().getStatus() ) )
272             {
273                 v4Model.getDistributionManagement().setStatus( null );
274             }
275         }
276     }
277 
278     /**
279      * Write the pom to <code>${basedir}/pom.xml</code>. If the file exists it
280      * will be overwritten.
281      *
282      * @param v4Model
283      * @throws ProjectConverterException
284      */
285     private void writeV4Pom( Model v4Model )
286         throws ProjectConverterException, IOException
287     {
288         if ( outputdir == null )
289         {
290             outputdir = basedir;
291         }
292 
293         if ( !outputdir.exists() && !outputdir.mkdirs() )
294         {
295             throw new IOException( "Failed to create directory " + outputdir );
296         }
297 
298         File pomxml = new File( outputdir, "pom.xml" );
299         boolean alreadyExist = false;
300 
301         if ( pomxml.exists() )
302         {
303             sendWarnMessage( "pom.xml in " + outputdir.getAbsolutePath() + " already exists, overwriting" );
304             alreadyExist = true;
305         }
306 
307         MavenXpp3Writer v4Writer = new MavenXpp3Writer();
308 
309         // write the new pom.xml
310         sendInfoMessage( "Writing new pom to: " + pomxml.getAbsolutePath() );
311 
312         Writer output = null;
313         try
314         {
315             output = new FileWriter( pomxml );
316             v4Writer.write( output, v4Model );
317             output.close();
318             fireSavePomEvent( pomxml, alreadyExist );
319         }
320         catch ( IOException e )
321         {
322             throw new ProjectConverterException( "Unable to write pom.xml. " + e.getMessage(), e );
323         }
324         finally
325         {
326             IOUtil.close( output );
327         }
328     }
329 
330     public File getBasedir()
331     {
332         return basedir;
333     }
334 
335     public void setBasedir( File basedir )
336     {
337         this.basedir = basedir;
338     }
339 
340     public String getProjectFileName()
341     {
342         return fileName;
343     }
344 
345     public void setProjectFileName( String projectFileName )
346     {
347         this.fileName = projectFileName;
348     }
349 
350     public void setProjectFile( File projectFile )
351     {
352         if ( projectFile != null )
353         {
354             basedir = projectFile.getParentFile();
355             fileName = projectFile.getName();
356         }
357     }
358 
359     public File getOutputdir()
360     {
361         return outputdir;
362     }
363 
364     public void setOutputdir( File outputdir )
365     {
366         this.outputdir = outputdir;
367     }
368 
369     public void addListener( ConverterListener listener )
370     {
371         if ( !listeners.contains( listener ) )
372         {
373             listeners.add( listener );
374         }
375     }
376 
377     private void sendInfoMessage( String message )
378     {
379         getLogger().info( message );
380 
381         for ( Iterator i = listeners.iterator(); i.hasNext(); )
382         {
383             ConverterListener listener = (ConverterListener) i.next();
384             listener.info( message );
385         }
386     }
387 
388     private void sendWarnMessage( String message )
389     {
390         getLogger().warn( message );
391 
392         for ( Iterator i = listeners.iterator(); i.hasNext(); )
393         {
394             ConverterListener listener = (ConverterListener) i.next();
395             listener.warn( message );
396         }
397     }
398 
399     private void fireSavePomEvent( File pomFile, boolean alreadyExist )
400     {
401         for ( Iterator i = listeners.iterator(); i.hasNext(); )
402         {
403             ConverterListener listener = (ConverterListener) i.next();
404             listener.savePomEvent( pomFile, alreadyExist );
405         }
406     }
407 }