View Javadoc

1   package org.codehaus.modello.maven;
2   
3   /*
4    * Copyright (c) 2004, Codehaus.org
5    *
6    * Permission is hereby granted, free of charge, to any person obtaining a copy of
7    * this software and associated documentation files (the "Software"), to deal in
8    * the Software without restriction, including without limitation the rights to
9    * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
10   * of the Software, and to permit persons to whom the Software is furnished to do
11   * so, subject to the following conditions:
12   *
13   * The above copyright notice and this permission notice shall be included in all
14   * copies or substantial portions of the Software.
15   *
16   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22   * SOFTWARE.
23   */
24  
25  import java.io.File;
26  import java.io.FileNotFoundException;
27  import java.io.IOException;
28  import java.util.ArrayList;
29  import java.util.Collections;
30  import java.util.List;
31  import java.util.Properties;
32  
33  import org.apache.maven.model.Resource;
34  import org.apache.maven.plugin.AbstractMojo;
35  import org.apache.maven.plugin.MojoExecutionException;
36  import org.apache.maven.plugins.annotations.Component;
37  import org.apache.maven.plugins.annotations.Parameter;
38  import org.apache.maven.project.MavenProject;
39  import org.codehaus.modello.ModelloException;
40  import org.codehaus.modello.ModelloParameterConstants;
41  import org.codehaus.modello.core.ModelloCore;
42  import org.codehaus.modello.model.Model;
43  import org.codehaus.modello.model.ModelValidationException;
44  import org.codehaus.plexus.util.StringUtils;
45  import org.sonatype.plexus.build.incremental.BuildContext;
46  
47  /**
48   * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
49   */
50  public abstract class AbstractModelloGeneratorMojo
51      extends AbstractMojo
52  {
53      // ----------------------------------------------------------------------
54      // Parameters
55      // ----------------------------------------------------------------------
56  
57      /**
58       * Base directory of the project.
59       */
60      @Parameter( defaultValue = "${basedir}", readonly = true, required = true )
61      private String basedir;
62  
63      /**
64       * List of relative paths to mdo files containing the models.
65       */
66      @Parameter( required = true )
67      private String[] models;
68  
69      /**
70       * The version of the model we will be working on.
71       */
72      @Parameter( property = "version", required = true )
73      private String version;
74  
75      /**
76       * True if the generated package names should include the version.
77       */
78      @Parameter( property = "packageWithVersion", defaultValue = "false", required = true )
79      private boolean packageWithVersion;
80  
81      /**
82       * <p>Note: This is passed by Maven and must not be configured by the user.</p>
83       */
84      @Component
85      private ModelloCore modelloCore;
86  
87      /**
88       * The Maven project instance for the executing project.
89       */
90      @Parameter( defaultValue = "${project}", readonly = true, required = true )
91      private MavenProject project;
92  
93      /**
94       * Additional historical versions to generate, each being packaged with the version regardless of the
95       * <code>packageWithVersion</code> setting.
96       */
97      @Parameter
98      private List<String> packagedVersions = new ArrayList<String>();
99  
100     /**
101      * @since 1.0.1
102      */
103     @Component
104     private BuildContext buildContext;
105 
106     // ----------------------------------------------------------------------
107     // Overridables
108     // ----------------------------------------------------------------------
109 
110     protected abstract String getGeneratorType();
111 
112     public abstract File getOutputDirectory();
113 
114     protected boolean producesCompilableResult()
115     {
116         return false;
117     }
118 
119     protected boolean producesResources()
120     {
121         return false;
122     }
123 
124     /**
125      * Creates a Properties objects.
126      * <br>
127      * The abstract mojo will override the output directory, the version and the
128      * package with version flag.
129      *
130      * @return the parameters
131      */
132     protected Properties createParameters()
133     {
134         return new Properties();
135     }
136 
137     /**
138      * Override this method to customize the values in the properties set.
139      * <p>
140      * This method will be called after the parameters have been populated with the
141      * parameters in the abstract mojo.
142      *
143      * @param parameters the parameters to customize
144      */
145     protected void customizeParameters( Properties parameters )
146     {
147     }
148 
149     // ----------------------------------------------------------------------
150     //
151     // ----------------------------------------------------------------------
152 
153     public void execute()
154         throws MojoExecutionException
155     {
156         String outputDirectory = getOutputDirectory().getAbsolutePath();
157 
158         getLog().info( "outputDirectory: " + outputDirectory );
159 
160         // ----------------------------------------------------------------------
161         // Initialize the parameters
162         // ----------------------------------------------------------------------
163 
164         Properties parameters = createParameters();
165 
166         parameters.setProperty( ModelloParameterConstants.OUTPUT_DIRECTORY, outputDirectory );
167 
168         parameters.setProperty( ModelloParameterConstants.VERSION, version );
169 
170         parameters.setProperty( ModelloParameterConstants.PACKAGE_WITH_VERSION,
171                                 Boolean.toString( packageWithVersion ) );
172 
173         if ( packagedVersions.size() > 0 )
174         {
175             parameters.setProperty( ModelloParameterConstants.ALL_VERSIONS,
176                                     StringUtils.join( packagedVersions.iterator(), "," ) );
177         }
178         
179         customizeParameters( parameters );
180 
181         // ----------------------------------------------------------------------
182         //
183         // ----------------------------------------------------------------------
184 
185         MojoExecutionException firstError = null;
186         for ( String modelStr : models )
187         {
188             try
189             {
190                 doExecute( modelStr, outputDirectory, parameters );
191             }
192             catch ( MojoExecutionException e )
193             {
194                 if ( firstError == null )
195                 {
196                     firstError = e;
197                 }
198                 getLog().error( e );
199             }
200         }
201         if ( firstError != null )
202         {
203             throw firstError;
204         }
205     }
206 
207     /**
208      * Performs execute on a single specified model.
209      */
210     private void doExecute( String modelStr, String outputDirectory, Properties parameters )
211         throws MojoExecutionException
212     {
213         if ( !buildContext.hasDelta( modelStr ) )
214         {
215             getLog().debug( "Skipping unchanged model: " + modelStr );
216             return;
217         }
218 
219         getLog().info( "Working on model: " + modelStr );
220 
221         File modelFile = new File( basedir, modelStr );
222         buildContext.removeMessages( modelFile );
223 
224         try
225         {
226             Model model = modelloCore.loadModel( modelFile );
227 
228             // TODO: dynamically resolve/load the generator type
229             getLog().info( "Generating current version: " + version );
230             modelloCore.generate( model, getGeneratorType(), parameters );
231 
232             for ( String version : packagedVersions )
233             {
234                 parameters.setProperty( ModelloParameterConstants.VERSION, version );
235 
236                 parameters.setProperty( ModelloParameterConstants.PACKAGE_WITH_VERSION, Boolean.toString( true ) );
237 
238                 getLog().info( "Generating packaged version: " + version );
239                 modelloCore.generate( model, getGeneratorType(), parameters );
240             }
241 
242             if ( producesCompilableResult() && project != null )
243             {
244                 project.addCompileSourceRoot( outputDirectory );
245             }
246 
247             if ( producesResources() && project != null )
248             {
249                 Resource resource = new Resource();
250                 resource.setDirectory( outputDirectory );
251                 project.addResource( resource );
252             }
253         }
254         catch ( FileNotFoundException e )
255         {
256             MojoExecutionException mojoExecutionException = new MojoExecutionException( e.getMessage(), e );
257             buildContext.addMessage( modelFile, 1 /* line */, 1 /* column */, mojoExecutionException.getMessage(),
258                                      BuildContext.SEVERITY_ERROR, mojoExecutionException );
259             throw mojoExecutionException;
260         }
261         catch ( ModelloException e )
262         {
263             MojoExecutionException mojoExecutionException =
264                 new MojoExecutionException( "Error generating: " + e.getMessage(), e );
265             // TODO: Provide actual line/column numbers
266             buildContext.addMessage( modelFile, 1 /* line */, 1 /* column */, mojoExecutionException.getMessage(),
267                                      BuildContext.SEVERITY_ERROR, mojoExecutionException );
268             throw mojoExecutionException;
269         }
270         catch ( ModelValidationException e )
271         {
272             MojoExecutionException mojoExecutionException =
273                 new MojoExecutionException( "Error generating: " + e.getMessage(), e );
274             // TODO: Provide actual line/column numbers
275             buildContext.addMessage( modelFile, 1 /* line */, 1 /* column */, mojoExecutionException.getMessage(),
276                                      BuildContext.SEVERITY_ERROR, mojoExecutionException );
277             throw mojoExecutionException;
278         }
279         catch ( IOException e )
280         {
281             MojoExecutionException mojoExecutionException =
282                 new MojoExecutionException( "Couldn't read file: " + e.getMessage(), e );
283             buildContext.addMessage( modelFile, 1 /* line */, 1 /* column */, mojoExecutionException.getMessage(),
284                                      BuildContext.SEVERITY_ERROR, mojoExecutionException );
285             throw mojoExecutionException;
286         }
287         catch ( RuntimeException e )
288         {
289             MojoExecutionException mojoExecutionException =
290                 new MojoExecutionException( "Error generating: " + e.getMessage(), e );
291             buildContext.addMessage( modelFile, 1 /* line */, 1 /* column */, mojoExecutionException.getMessage(),
292                                      BuildContext.SEVERITY_ERROR, mojoExecutionException );
293             throw mojoExecutionException;
294         }
295     }
296 
297     // ----------------------------------------------------------------------
298     // Accessors
299     // ----------------------------------------------------------------------
300 
301     public String getBasedir()
302     {
303         return basedir;
304     }
305 
306     public void setBasedir( String basedir )
307     {
308         this.basedir = basedir;
309     }
310 
311     public String getVersion()
312     {
313         return version;
314     }
315 
316     public void setVersion( String version )
317     {
318         this.version = version;
319     }
320 
321     public boolean getPackageWithVersion()
322     {
323         return packageWithVersion;
324     }
325 
326     public void setPackageWithVersion( boolean packageWithVersion )
327     {
328         this.packageWithVersion = packageWithVersion;
329     }
330 
331     public ModelloCore getModelloCore()
332     {
333         return modelloCore;
334     }
335 
336     public void setModelloCore( ModelloCore modelloCore )
337     {
338         this.modelloCore = modelloCore;
339     }
340 
341     public void setBuildContext( BuildContext context )
342     {
343         this.buildContext = context;
344     }
345 
346     public MavenProject getProject()
347     {
348         return project;
349     }
350 
351     public void setProject( MavenProject project )
352     {
353         this.project = project;
354     }
355 
356     public void setPackagedVersions( List<String> packagedVersions )
357     {
358         this.packagedVersions = Collections.unmodifiableList( packagedVersions );
359     }
360 
361     /**
362      * @return Returns the paths to the models.
363      */
364     public String[] getModels()
365     {
366         return models;
367     }
368 
369     /**
370      * @param models Sets the paths to the models.
371      */
372     public void setModels( String[] models )
373     {
374         this.models = models;
375     }
376 }