View Javadoc

1   /*
2    *   Copyright (C) Christian Schulte, 2005-206
3    *   All rights reserved.
4    *
5    *   Redistribution and use in source and binary forms, with or without
6    *   modification, are permitted provided that the following conditions
7    *   are met:
8    *
9    *     o Redistributions of source code must retain the above copyright
10   *       notice, this list of conditions and the following disclaimer.
11   *
12   *     o Redistributions in binary form must reproduce the above copyright
13   *       notice, this list of conditions and the following disclaimer in
14   *       the documentation and/or other materials provided with the
15   *       distribution.
16   *
17   *   THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
18   *   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
19   *   AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20   *   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
21   *   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22   *   NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23   *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24   *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25   *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26   *   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27   *
28   *   $JOMC: AbstractClassesCommitMojo.java 4613 2012-09-22 10:07:08Z schulte $
29   *
30   */
31  package org.jomc.mojo;
32  
33  import java.io.File;
34  import java.util.ArrayList;
35  import java.util.List;
36  import java.util.logging.Level;
37  import javax.xml.bind.JAXBContext;
38  import javax.xml.bind.util.JAXBSource;
39  import javax.xml.transform.Source;
40  import javax.xml.transform.Transformer;
41  import org.apache.maven.plugin.MojoExecutionException;
42  import org.apache.maven.plugin.MojoFailureException;
43  import org.jomc.model.Module;
44  import org.jomc.modlet.ModelContext;
45  import org.jomc.modlet.ModelValidationReport;
46  import org.jomc.modlet.ObjectFactory;
47  import org.jomc.tools.ClassFileProcessor;
48  
49  /**
50   * Base class for committing model objects to class files.
51   *
52   * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
53   * @version $JOMC: AbstractClassesCommitMojo.java 4613 2012-09-22 10:07:08Z schulte $
54   */
55  public abstract class AbstractClassesCommitMojo extends AbstractJomcMojo
56  {
57  
58      /** Constant for the name of the tool backing the mojo. */
59      private static final String TOOLNAME = "ClassFileProcessor";
60  
61      /**
62       * XSLT document to use for transforming model objects.
63       * <p>The value of the parameter is a location to search a XSLT document at. First the value is used to search the
64       * class path of the plugin. If a class path resource is found, a XSLT document is loaded from that resource. If no
65       * class path resource is found, an attempt is made to parse the value to an URL. Succeeding that, an XSLT document
66       * is loaded from that URL (since version 1.2). Failing that, the value is interpreted as a file name of a XSLT
67       * document to load relative to the base directory of the project. If that file exists, a XSLT document is loaded
68       * from that file. If no XSLT document is found at the given location, a build failure is produced.</p>
69       * <p><b>Note:</b> When upgrading to version 1.2, any project dependencies holding XSLT documents referenced by this
70       * parameter need to be added to the plugins' dependencies.</p>
71       * <p><strong>Deprecated:</strong> As of JOMC 1.2, please use the 'modelObjectStylesheetResources' parameter. This
72       * parameter will be removed in version 2.0.</p>
73       *
74       * @parameter
75       */
76      @Deprecated
77      private String modelObjectStylesheet;
78  
79      /**
80       * XSLT documents to use for transforming model objects.
81       * <pre>
82       * &lt;modelObjectStylesheetResources>
83       *   &lt;modelObjectStylesheetResource>
84       *     &lt;location>The location of the XSLT document.&lt;/location>
85       *     &lt;optional>Flag indicating the XSLT document is optional.&lt;/optional>
86       *     &lt;connectTimeout>Timeout value, in milliseconds.&lt;/connectTimeout>
87       *     &lt;readTimeout>Timeout value, in milliseconds.&lt;/readTimeout>
88       *     &lt;transformationParameterResources>
89       *       &lt;transformationParameterResource>
90       *         &lt;location>The location of the properties resource.&lt;/location>
91       *         &lt;optional>Flag indicating the properties resource is optional.&lt;/optional>
92       *         &lt;format>The format of the properties resource.&lt;/format>
93       *         &lt;connectTimeout>Timeout value, in milliseconds.&lt;/connectTimeout>
94       *         &lt;readTimeout>Timeout value, in milliseconds.&lt;/readTimeout>
95       *       &lt;/transformationParameterResource>
96       *     &lt;/transformationParameterResources>
97       *     &lt;transformationParameters>
98       *       &lt;transformationParameter>
99       *         &lt;key>The name of the parameter.&lt;/key>
100      *         &lt;value>The value of the parameter.&lt;/value>
101      *         &lt;type>The name of the class of the parameter's object.&lt;/type>
102      *       &lt;/transformationParameter>
103      *     &lt;/transformationParameters>
104      *     &lt;transformationOutputProperties>
105      *       &lt;transformationOutputProperty>
106      *         &lt;key>The name of the property.&lt;/key>
107      *         &lt;value>The value of the property.&lt;/value>
108      *         &lt;type>The name of the class of the properties object.&lt;/type>
109      *       &lt;/transformationOutputProperty>
110      *     &lt;/transformationOutputProperties>
111      *   &lt;/modelObjectStylesheetResource>
112      * &lt;/modelObjectStylesheetResources>
113      * </pre>
114      * <p>The location value is used to first search the class path of the plugin. If a class path resource is found,
115      * that resource is used. If no class path resource is found, an attempt is made to parse the location value to an
116      * URL. On successful parsing, that URL is used. Otherwise the location value is interpreted as a file name relative
117      * to the base directory of the project. If that file exists, that file is used. If nothing is found at the given
118      * location, depending on the optional flag, a warning message is logged or a build failure is produced.</p>
119      * <p>The optional flag is used to flag the resource optional. When an optional resource is not found, a warning
120      * message is logged instead of producing a build failure.<br/><b>Default value is:</b> false</p>
121      * <p>The connectTimeout value is used to specify the timeout, in milliseconds, to be used when opening
122      * communications links to the resource. A timeout of zero is interpreted as an infinite timeout.<br/>
123      * <b>Default value is:</b> 60000</p>
124      * <p>The readTimeout value is used to specify the timeout, in milliseconds, to be used when reading the resource.
125      * A timeout of zero is interpreted as an infinite timeout.<br/>
126      * <b>Default value is:</b> 60000</p>
127      *
128      * @parameter
129      * @since 1.2
130      */
131     private List<ModelObjectStylesheetResource> modelObjectStylesheetResources;
132 
133     /** Creates a new {@code AbstractClassesCommitMojo} instance. */
134     public AbstractClassesCommitMojo()
135     {
136         super();
137     }
138 
139     /**
140      * Gets transformers to use for transforming model objects.
141      *
142      * @param classLoader The class loader to use for loading a transformer class path resource.
143      *
144      * @return A list of transformers to use for transforming model objects.
145      *
146      * @throws NullPointerException if {@code classLoader} is {@code null}.
147      * @throws MojoExecutionException if getting the transformers fails.
148      *
149      * @deprecated As of JOMC 1.2, the dependencies of the project are no longer searched for XSLT documents. Please
150      * use method {@link #getTransformers()}. This method will be removed in version 2.0.
151      */
152     @Deprecated
153     protected List<Transformer> getTransformers( final ClassLoader classLoader ) throws MojoExecutionException
154     {
155         if ( classLoader == null )
156         {
157             throw new NullPointerException( "classLoader" );
158         }
159 
160         return this.getTransformers();
161     }
162 
163     /**
164      * Gets transformers to use for transforming model objects.
165      *
166      * @return A list of transformers to use for transforming model objects.
167      *
168      * @throws MojoExecutionException if getting the transformers fails.
169      *
170      * @since 1.2
171      */
172     protected List<Transformer> getTransformers() throws MojoExecutionException
173     {
174         final List<Transformer> transformers = new ArrayList<Transformer>(
175             this.modelObjectStylesheetResources != null ? this.modelObjectStylesheetResources.size() + 1 : 1 );
176 
177         if ( this.modelObjectStylesheet != null )
178         {
179             final TransformerResourceType r = new TransformerResourceType();
180             r.setLocation( this.modelObjectStylesheet );
181 
182             final Transformer transformer = this.getTransformer( r );
183 
184             if ( transformer != null )
185             {
186                 transformers.add( transformer );
187             }
188         }
189 
190         if ( this.modelObjectStylesheetResources != null )
191         {
192             for ( int i = 0, s0 = this.modelObjectStylesheetResources.size(); i < s0; i++ )
193             {
194                 final Transformer transformer = this.getTransformer( this.modelObjectStylesheetResources.get( i ) );
195 
196                 if ( transformer != null )
197                 {
198                     transformers.add( transformer );
199                 }
200             }
201         }
202 
203         return transformers;
204     }
205 
206     @Override
207     protected void assertValidParameters() throws MojoFailureException
208     {
209         super.assertValidParameters();
210         this.assertValidResources( this.modelObjectStylesheetResources );
211     }
212 
213     @Override
214     protected final void executeTool() throws Exception
215     {
216         this.logSeparator();
217 
218         if ( this.isClassProcessingEnabled() )
219         {
220             this.logProcessingModule( TOOLNAME, this.getClassesModuleName() );
221 
222             final ClassLoader classLoader = this.getClassesClassLoader();
223             final ModelContext context = this.createModelContext( classLoader );
224             final ClassFileProcessor tool = this.createClassFileProcessor( context );
225             final JAXBContext jaxbContext = context.createContext( this.getModel() );
226             final List<Transformer> transformers = this.getTransformers();
227             final Source source = new JAXBSource( jaxbContext, new ObjectFactory().createModel( tool.getModel() ) );
228             final ModelValidationReport validationReport = context.validateModel( this.getModel(), source );
229 
230             this.log( context, validationReport.isModelValid() ? Level.INFO : Level.SEVERE, validationReport );
231 
232             if ( validationReport.isModelValid() )
233             {
234                 final Module module =
235                     tool.getModules() != null ? tool.getModules().getModule( this.getClassesModuleName() ) : null;
236 
237                 if ( module != null )
238                 {
239                     tool.commitModelObjects( module, context, this.getClassesDirectory() );
240 
241                     if ( !transformers.isEmpty() )
242                     {
243                         tool.transformModelObjects( module, context, this.getClassesDirectory(), transformers );
244                     }
245 
246                     this.logToolSuccess( TOOLNAME );
247                 }
248                 else
249                 {
250                     this.logMissingModule( this.getClassesModuleName() );
251                 }
252             }
253             else
254             {
255                 throw new MojoExecutionException( Messages.getMessage( "classFileProcessingFailure" ) );
256             }
257         }
258         else if ( this.isLoggable( Level.INFO ) )
259         {
260             this.log( Level.INFO, Messages.getMessage( "classFileProcessingDisabled" ), null );
261         }
262     }
263 
264     /**
265      * Gets the name of the module to commit class file model objects of.
266      *
267      * @return The name of the module to commit class file model objects of.
268      *
269      * @throws MojoExecutionException if getting the name fails.
270      */
271     protected abstract String getClassesModuleName() throws MojoExecutionException;
272 
273     /**
274      * Gets the class loader to use for committing class file model objects.
275      *
276      * @return The class loader to use for committing class file model objects.
277      *
278      * @throws MojoExecutionException if getting the class loader fails.
279      */
280     protected abstract ClassLoader getClassesClassLoader() throws MojoExecutionException;
281 
282     /**
283      * Gets the directory holding the class files to commit model objects to.
284      *
285      * @return The directory holding the class files to commit model objects to.
286      *
287      * @throws MojoExecutionException if getting the directory fails.
288      */
289     protected abstract File getClassesDirectory() throws MojoExecutionException;
290 
291 }