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.build.BuildContext;
45  import org.codehaus.plexus.util.StringUtils;
46  
47  /**
48   * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
49   */
50  public abstract class AbstractModelloGeneratorMojo extends AbstractMojo {
51      // ----------------------------------------------------------------------
52      // Parameters
53      // ----------------------------------------------------------------------
54  
55      /**
56       * Base directory of the project, from where the Modello models are loaded.
57       */
58      @Parameter(defaultValue = "${basedir}", required = true)
59      private String basedir;
60  
61      /**
62       * List of relative paths to mdo files containing the models.
63       */
64      @Parameter(required = true)
65      private String[] models;
66  
67      /**
68       * The version of the model we will be working on.
69       */
70      @Parameter(property = "version", required = true)
71      private String version;
72  
73      /**
74       * True if the generated package names should include the version.
75       */
76      @Parameter(property = "packageWithVersion", defaultValue = "false", required = true)
77      private boolean packageWithVersion;
78  
79      /**
80       * <p>Note: This is passed by Maven and must not be configured by the user.</p>
81       */
82      @Component
83      private ModelloCore modelloCore;
84  
85      /**
86       * The Maven project instance for the executing project.
87       */
88      @Parameter(defaultValue = "${project}", readonly = true, required = true)
89      private MavenProject project;
90  
91      /**
92       * Additional historical versions to generate, each being packaged with the version regardless of the
93       * <code>packageWithVersion</code> setting.
94       */
95      @Parameter
96      private List<String> packagedVersions = new ArrayList<String>();
97  
98      /**
99       * @since 1.0.1
100      */
101     @Component
102     private BuildContext buildContext;
103 
104     // ----------------------------------------------------------------------
105     // Overridables
106     // ----------------------------------------------------------------------
107 
108     protected abstract String getGeneratorType();
109 
110     public abstract File getOutputDirectory();
111 
112     protected boolean producesCompilableResult() {
113         return false;
114     }
115 
116     protected boolean producesResources() {
117         return false;
118     }
119 
120     /**
121      * Creates a Properties objects.
122      * <br>
123      * The abstract mojo will override the output directory, the version and the
124      * package with version flag.
125      *
126      * @return the parameters
127      */
128     protected Properties createParameters() {
129         return new Properties();
130     }
131 
132     /**
133      * Override this method to customize the values in the properties set.
134      * <p>
135      * This method will be called after the parameters have been populated with the
136      * parameters in the abstract mojo.
137      *
138      * @param parameters the parameters to customize
139      */
140     protected void customizeParameters(Properties parameters) {}
141 
142     // ----------------------------------------------------------------------
143     //
144     // ----------------------------------------------------------------------
145 
146     public void execute() throws MojoExecutionException {
147         String outputDirectory = getOutputDirectory().getAbsolutePath();
148 
149         getLog().info("outputDirectory: " + outputDirectory);
150 
151         // ----------------------------------------------------------------------
152         // Initialize the parameters
153         // ----------------------------------------------------------------------
154 
155         Properties parameters = createParameters();
156 
157         parameters.setProperty(ModelloParameterConstants.OUTPUT_DIRECTORY, outputDirectory);
158 
159         parameters.setProperty(ModelloParameterConstants.VERSION, version);
160 
161         parameters.setProperty(ModelloParameterConstants.PACKAGE_WITH_VERSION, Boolean.toString(packageWithVersion));
162 
163         if (packagedVersions.size() > 0) {
164             parameters.setProperty(
165                     ModelloParameterConstants.ALL_VERSIONS, StringUtils.join(packagedVersions.iterator(), ","));
166         }
167 
168         customizeParameters(parameters);
169 
170         // ----------------------------------------------------------------------
171         //
172         // ----------------------------------------------------------------------
173 
174         MojoExecutionException firstError = null;
175         for (String modelStr : models) {
176             try {
177                 doExecute(modelStr, outputDirectory, parameters);
178             } catch (MojoExecutionException e) {
179                 if (firstError == null) {
180                     firstError = e;
181                 }
182                 getLog().error(e);
183             }
184         }
185         if (firstError != null) {
186             throw firstError;
187         }
188     }
189 
190     /**
191      * Performs execute on a single specified model.
192      */
193     private void doExecute(String modelStr, String outputDirectory, Properties parameters)
194             throws MojoExecutionException {
195         if (!buildContext.hasDelta(modelStr)) {
196             getLog().debug("Skipping unchanged model: " + modelStr);
197             return;
198         }
199 
200         getLog().info("Working on model: " + modelStr);
201 
202         File modelFile = new File(basedir, modelStr);
203         buildContext.removeMessages(modelFile);
204 
205         try {
206             Model model = modelloCore.loadModel(modelFile);
207 
208             // TODO: dynamically resolve/load the generator type
209             getLog().info("Generating current version: " + version);
210             modelloCore.generate(model, getGeneratorType(), parameters);
211 
212             for (String version : packagedVersions) {
213                 parameters.setProperty(ModelloParameterConstants.VERSION, version);
214 
215                 parameters.setProperty(ModelloParameterConstants.PACKAGE_WITH_VERSION, Boolean.toString(true));
216 
217                 getLog().info("Generating packaged version: " + version);
218                 modelloCore.generate(model, getGeneratorType(), parameters);
219             }
220 
221             if (producesCompilableResult() && project != null) {
222                 project.addCompileSourceRoot(outputDirectory);
223             }
224 
225             if (producesResources() && project != null) {
226                 Resource resource = new Resource();
227                 resource.setDirectory(outputDirectory);
228                 project.addResource(resource);
229             }
230         } catch (FileNotFoundException e) {
231             MojoExecutionException mojoExecutionException = new MojoExecutionException(e.getMessage(), e);
232             buildContext.addMessage(
233                     modelFile,
234                     1 /* line */,
235                     1 /* column */,
236                     mojoExecutionException.getMessage(),
237                     BuildContext.SEVERITY_ERROR,
238                     mojoExecutionException);
239             throw mojoExecutionException;
240         } catch (ModelloException e) {
241             MojoExecutionException mojoExecutionException =
242                     new MojoExecutionException("Error generating: " + e.getMessage(), e);
243             // TODO: Provide actual line/column numbers
244             buildContext.addMessage(
245                     modelFile,
246                     1 /* line */,
247                     1 /* column */,
248                     mojoExecutionException.getMessage(),
249                     BuildContext.SEVERITY_ERROR,
250                     mojoExecutionException);
251             throw mojoExecutionException;
252         } catch (ModelValidationException e) {
253             MojoExecutionException mojoExecutionException =
254                     new MojoExecutionException("Error generating: " + e.getMessage(), e);
255             // TODO: Provide actual line/column numbers
256             buildContext.addMessage(
257                     modelFile,
258                     1 /* line */,
259                     1 /* column */,
260                     mojoExecutionException.getMessage(),
261                     BuildContext.SEVERITY_ERROR,
262                     mojoExecutionException);
263             throw mojoExecutionException;
264         } catch (IOException e) {
265             MojoExecutionException mojoExecutionException =
266                     new MojoExecutionException("Couldn't read file: " + e.getMessage(), e);
267             buildContext.addMessage(
268                     modelFile,
269                     1 /* line */,
270                     1 /* column */,
271                     mojoExecutionException.getMessage(),
272                     BuildContext.SEVERITY_ERROR,
273                     mojoExecutionException);
274             throw mojoExecutionException;
275         } catch (RuntimeException e) {
276             MojoExecutionException mojoExecutionException =
277                     new MojoExecutionException("Error generating: " + e.getMessage(), e);
278             buildContext.addMessage(
279                     modelFile,
280                     1 /* line */,
281                     1 /* column */,
282                     mojoExecutionException.getMessage(),
283                     BuildContext.SEVERITY_ERROR,
284                     mojoExecutionException);
285             throw mojoExecutionException;
286         }
287     }
288 
289     // ----------------------------------------------------------------------
290     // Accessors
291     // ----------------------------------------------------------------------
292 
293     public String getBasedir() {
294         return basedir;
295     }
296 
297     public void setBasedir(String basedir) {
298         this.basedir = basedir;
299     }
300 
301     public String getVersion() {
302         return version;
303     }
304 
305     public void setVersion(String version) {
306         this.version = version;
307     }
308 
309     public boolean getPackageWithVersion() {
310         return packageWithVersion;
311     }
312 
313     public void setPackageWithVersion(boolean packageWithVersion) {
314         this.packageWithVersion = packageWithVersion;
315     }
316 
317     public ModelloCore getModelloCore() {
318         return modelloCore;
319     }
320 
321     public void setModelloCore(ModelloCore modelloCore) {
322         this.modelloCore = modelloCore;
323     }
324 
325     public void setBuildContext(BuildContext context) {
326         this.buildContext = context;
327     }
328 
329     public MavenProject getProject() {
330         return project;
331     }
332 
333     public void setProject(MavenProject project) {
334         this.project = project;
335     }
336 
337     public void setPackagedVersions(List<String> packagedVersions) {
338         this.packagedVersions = Collections.unmodifiableList(packagedVersions);
339     }
340 
341     /**
342      * @return Returns the paths to the models.
343      */
344     public String[] getModels() {
345         return models;
346     }
347 
348     /**
349      * @param models Sets the paths to the models.
350      */
351     public void setModels(String[] models) {
352         this.models = models;
353     }
354 }