001/* 002 * Copyright (C) 2005 Christian Schulte <cs@schulte.it> 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without 006 * modification, are permitted provided that the following conditions 007 * are met: 008 * 009 * o Redistributions of source code must retain the above copyright 010 * notice, this list of conditions and the following disclaimer. 011 * 012 * o Redistributions in binary form must reproduce the above copyright 013 * notice, this list of conditions and the following disclaimer in 014 * the documentation and/or other materials provided with the 015 * distribution. 016 * 017 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 018 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 019 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 020 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, 021 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 022 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 023 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 024 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 025 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 026 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 027 * 028 * $JOMC: CommitClassesTask.java 5179 2016-04-15 02:58:23Z schulte $ 029 * 030 */ 031package org.jomc.ant; 032 033import java.io.File; 034import java.io.IOException; 035import java.util.ArrayList; 036import java.util.LinkedList; 037import java.util.List; 038import java.util.logging.Level; 039import javax.xml.bind.JAXBContext; 040import javax.xml.bind.JAXBException; 041import javax.xml.bind.util.JAXBSource; 042import javax.xml.transform.Source; 043import javax.xml.transform.Transformer; 044import javax.xml.transform.TransformerConfigurationException; 045import org.apache.tools.ant.BuildException; 046import org.jomc.ant.types.TransformerResourceType; 047import org.jomc.model.Implementation; 048import org.jomc.model.Module; 049import org.jomc.model.Specification; 050import org.jomc.modlet.Model; 051import org.jomc.modlet.ModelContext; 052import org.jomc.modlet.ModelException; 053import org.jomc.modlet.ModelValidationReport; 054import org.jomc.modlet.ObjectFactory; 055import org.jomc.tools.ClassFileProcessor; 056 057/** 058 * Task for committing model objects to class files. 059 * 060 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a> 061 * @version $JOMC: CommitClassesTask.java 5179 2016-04-15 02:58:23Z schulte $ 062 */ 063public final class CommitClassesTask extends ClassFileProcessorTask 064{ 065 066 /** 067 * The directory holding the class files to commit model objects to. 068 */ 069 private File classesDirectory; 070 071 /** 072 * XSLT documents to use for transforming model objects. 073 */ 074 private List<TransformerResourceType> modelObjectStylesheetResources; 075 076 /** 077 * Creates a new {@code CommitClassesTask} instance. 078 */ 079 public CommitClassesTask() 080 { 081 super(); 082 } 083 084 /** 085 * Gets the directory holding the class files to commit model objects to. 086 * 087 * @return The directory holding the class files to commit model objects to or {@code null}. 088 * 089 * @see #setClassesDirectory(java.io.File) 090 */ 091 public File getClassesDirectory() 092 { 093 return this.classesDirectory; 094 } 095 096 /** 097 * Sets the directory holding the class files to commit model objects to. 098 * 099 * @param value The new directory holding the class files to commit model objects to or {@code null}. 100 * 101 * @see #getClassesDirectory() 102 */ 103 public void setClassesDirectory( final File value ) 104 { 105 this.classesDirectory = value; 106 } 107 108 /** 109 * Gets the XSLT documents to use for transforming model objects. 110 * <p> 111 * This accessor method returns a reference to the live list, not a snapshot. Therefore any modification you make 112 * to the returned list will be present inside the object. This is why there is no {@code set} method for the 113 * model object stylesheet resources property. 114 * </p> 115 * 116 * @return The XSLT documents to use for transforming model objects. 117 * 118 * @see #createModelObjectStylesheetResource() 119 */ 120 public List<TransformerResourceType> getModelObjectStylesheetResources() 121 { 122 if ( this.modelObjectStylesheetResources == null ) 123 { 124 this.modelObjectStylesheetResources = new LinkedList<TransformerResourceType>(); 125 } 126 127 return this.modelObjectStylesheetResources; 128 } 129 130 /** 131 * Creates a new {@code modelObjectStylesheetResource} element instance. 132 * 133 * @return A new {@code modelObjectStylesheetResource} element instance. 134 * 135 * @see #getModelObjectStylesheetResources() 136 */ 137 public TransformerResourceType createModelObjectStylesheetResource() 138 { 139 final TransformerResourceType modelObjectStylesheetResource = new TransformerResourceType(); 140 this.getModelObjectStylesheetResources().add( modelObjectStylesheetResource ); 141 return modelObjectStylesheetResource; 142 } 143 144 /** 145 * {@inheritDoc} 146 */ 147 @Override 148 public void preExecuteTask() throws BuildException 149 { 150 super.preExecuteTask(); 151 152 this.assertNotNull( "classesDirectory", this.getClassesDirectory() ); 153 this.assertLocationsNotNull( this.getModelObjectStylesheetResources() ); 154 } 155 156 /** 157 * Commits model objects to class files. 158 * 159 * @throws BuildException if committing model objects fails. 160 */ 161 @Override 162 public void processClassFiles() throws BuildException 163 { 164 ProjectClassLoader classLoader = null; 165 166 try 167 { 168 this.log( Messages.getMessage( "committingModelObjects", this.getModel() ) ); 169 170 classLoader = this.newProjectClassLoader(); 171 final ModelContext context = this.newModelContext( classLoader ); 172 final ClassFileProcessor tool = this.newClassFileProcessor(); 173 final JAXBContext jaxbContext = context.createContext( this.getModel() ); 174 final Model model = this.getModel( context ); 175 final Source source = new JAXBSource( jaxbContext, new ObjectFactory().createModel( model ) ); 176 final ModelValidationReport validationReport = context.validateModel( this.getModel(), source ); 177 178 this.logValidationReport( context, validationReport ); 179 tool.setModel( model ); 180 181 final List<Transformer> transformers = 182 new ArrayList<Transformer>( this.getModelObjectStylesheetResources().size() ); 183 184 for ( int i = 0, s0 = this.getModelObjectStylesheetResources().size(); i < s0; i++ ) 185 { 186 final Transformer transformer = 187 this.getTransformer( this.getModelObjectStylesheetResources().get( i ) ); 188 189 if ( transformer != null ) 190 { 191 transformers.add( transformer ); 192 } 193 } 194 195 if ( validationReport.isModelValid() ) 196 { 197 final Specification s = this.getSpecification( model ); 198 final Implementation i = this.getImplementation( model ); 199 final Module m = this.getModule( model ); 200 201 if ( s != null ) 202 { 203 tool.commitModelObjects( s, context, this.getClassesDirectory() ); 204 205 if ( !transformers.isEmpty() ) 206 { 207 tool.transformModelObjects( s, context, this.getClassesDirectory(), transformers ); 208 } 209 } 210 211 if ( i != null ) 212 { 213 tool.commitModelObjects( i, context, this.getClassesDirectory() ); 214 215 if ( !transformers.isEmpty() ) 216 { 217 tool.transformModelObjects( i, context, this.getClassesDirectory(), transformers ); 218 } 219 } 220 221 if ( m != null ) 222 { 223 tool.commitModelObjects( m, context, this.getClassesDirectory() ); 224 225 if ( !transformers.isEmpty() ) 226 { 227 tool.transformModelObjects( m, context, this.getClassesDirectory(), transformers ); 228 } 229 } 230 231 if ( this.isModulesProcessingRequested() ) 232 { 233 tool.commitModelObjects( context, this.getClassesDirectory() ); 234 235 if ( !transformers.isEmpty() ) 236 { 237 tool.transformModelObjects( context, this.getClassesDirectory(), transformers ); 238 } 239 } 240 241 classLoader.close(); 242 classLoader = null; 243 } 244 else 245 { 246 throw new ModelException( Messages.getMessage( "invalidModel", this.getModel() ) ); 247 } 248 } 249 catch ( final IOException e ) 250 { 251 throw new ClassProcessingException( Messages.getMessage( e ), e, this.getLocation() ); 252 } 253 catch ( final JAXBException e ) 254 { 255 throw new ClassProcessingException( Messages.getMessage( e ), e, this.getLocation() ); 256 } 257 catch ( final TransformerConfigurationException e ) 258 { 259 throw new ClassProcessingException( Messages.getMessage( e ), e, this.getLocation() ); 260 } 261 catch ( final ModelException e ) 262 { 263 throw new ClassProcessingException( Messages.getMessage( e ), e, this.getLocation() ); 264 } 265 finally 266 { 267 try 268 { 269 if ( classLoader != null ) 270 { 271 classLoader.close(); 272 } 273 } 274 catch ( final IOException e ) 275 { 276 this.logMessage( Level.SEVERE, Messages.getMessage( e ), e ); 277 } 278 } 279 } 280 281 /** 282 * {@inheritDoc} 283 */ 284 @Override 285 public CommitClassesTask clone() 286 { 287 final CommitClassesTask clone = (CommitClassesTask) super.clone(); 288 clone.classesDirectory = 289 this.classesDirectory != null ? new File( this.classesDirectory.getAbsolutePath() ) : null; 290 291 if ( this.modelObjectStylesheetResources != null ) 292 { 293 clone.modelObjectStylesheetResources = 294 new ArrayList<TransformerResourceType>( this.modelObjectStylesheetResources.size() ); 295 296 for ( final TransformerResourceType e : this.modelObjectStylesheetResources ) 297 { 298 clone.modelObjectStylesheetResources.add( e.clone() ); 299 } 300 } 301 302 return clone; 303 } 304 305}