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 * <modelObjectStylesheetResources> 83 * <modelObjectStylesheetResource> 84 * <location>The location of the XSLT document.</location> 85 * <optional>Flag indicating the XSLT document is optional.</optional> 86 * <connectTimeout>Timeout value, in milliseconds.</connectTimeout> 87 * <readTimeout>Timeout value, in milliseconds.</readTimeout> 88 * <transformationParameterResources> 89 * <transformationParameterResource> 90 * <location>The location of the properties resource.</location> 91 * <optional>Flag indicating the properties resource is optional.</optional> 92 * <format>The format of the properties resource.</format> 93 * <connectTimeout>Timeout value, in milliseconds.</connectTimeout> 94 * <readTimeout>Timeout value, in milliseconds.</readTimeout> 95 * </transformationParameterResource> 96 * </transformationParameterResources> 97 * <transformationParameters> 98 * <transformationParameter> 99 * <key>The name of the parameter.</key> 100 * <value>The value of the parameter.</value> 101 * <type>The name of the class of the parameter's object.</type> 102 * </transformationParameter> 103 * </transformationParameters> 104 * <transformationOutputProperties> 105 * <transformationOutputProperty> 106 * <key>The name of the property.</key> 107 * <value>The value of the property.</value> 108 * <type>The name of the class of the properties object.</type> 109 * </transformationOutputProperty> 110 * </transformationOutputProperties> 111 * </modelObjectStylesheetResource> 112 * </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 }