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: CommitClassesTask.java 4613 2012-09-22 10:07:08Z schulte $ |
29 | * |
30 | */ |
31 | package org.jomc.ant; |
32 | |
33 | import java.io.File; |
34 | import java.io.IOException; |
35 | import java.util.ArrayList; |
36 | import java.util.LinkedList; |
37 | import java.util.List; |
38 | import java.util.logging.Level; |
39 | import javax.xml.bind.JAXBContext; |
40 | import javax.xml.bind.JAXBException; |
41 | import javax.xml.bind.util.JAXBSource; |
42 | import javax.xml.transform.Source; |
43 | import javax.xml.transform.Transformer; |
44 | import javax.xml.transform.TransformerConfigurationException; |
45 | import org.apache.tools.ant.BuildException; |
46 | import org.jomc.ant.types.TransformerResourceType; |
47 | import org.jomc.model.Implementation; |
48 | import org.jomc.model.Module; |
49 | import org.jomc.model.Specification; |
50 | import org.jomc.modlet.Model; |
51 | import org.jomc.modlet.ModelContext; |
52 | import org.jomc.modlet.ModelException; |
53 | import org.jomc.modlet.ModelValidationReport; |
54 | import org.jomc.modlet.ObjectFactory; |
55 | import org.jomc.tools.ClassFileProcessor; |
56 | |
57 | /** |
58 | * Task for committing model objects to class files. |
59 | * |
60 | * @author <a href="mailto:cs@schulte.it">Christian Schulte</a> |
61 | * @version $JOMC: CommitClassesTask.java 4613 2012-09-22 10:07:08Z schulte $ |
62 | */ |
63 | public final class CommitClassesTask extends ClassFileProcessorTask |
64 | { |
65 | |
66 | /** The directory holding the class files to commit model objects to. */ |
67 | private File classesDirectory; |
68 | |
69 | /** XSLT documents to use for transforming model objects. */ |
70 | private List<TransformerResourceType> modelObjectStylesheetResources; |
71 | |
72 | /** Creates a new {@code CommitClassesTask} instance. */ |
73 | public CommitClassesTask() |
74 | { |
75 | super(); |
76 | } |
77 | |
78 | /** |
79 | * Gets the directory holding the class files to commit model objects to. |
80 | * |
81 | * @return The directory holding the class files to commit model objects to or {@code null}. |
82 | * |
83 | * @see #setClassesDirectory(java.io.File) |
84 | */ |
85 | public File getClassesDirectory() |
86 | { |
87 | return this.classesDirectory; |
88 | } |
89 | |
90 | /** |
91 | * Sets the directory holding the class files to commit model objects to. |
92 | * |
93 | * @param value The new directory holding the class files to commit model objects to or {@code null}. |
94 | * |
95 | * @see #getClassesDirectory() |
96 | */ |
97 | public void setClassesDirectory( final File value ) |
98 | { |
99 | this.classesDirectory = value; |
100 | } |
101 | |
102 | /** |
103 | * Gets the XSLT documents to use for transforming model objects. |
104 | * <p>This accessor method returns a reference to the live list, not a snapshot. Therefore any modification you make |
105 | * to the returned list will be present inside the object. This is why there is no {@code set} method for the |
106 | * model object stylesheet resources property.</p> |
107 | * |
108 | * @return The XSLT documents to use for transforming model objects. |
109 | * |
110 | * @see #createModelObjectStylesheetResource() |
111 | */ |
112 | public List<TransformerResourceType> getModelObjectStylesheetResources() |
113 | { |
114 | if ( this.modelObjectStylesheetResources == null ) |
115 | { |
116 | this.modelObjectStylesheetResources = new LinkedList<TransformerResourceType>(); |
117 | } |
118 | |
119 | return this.modelObjectStylesheetResources; |
120 | } |
121 | |
122 | /** |
123 | * Creates a new {@code modelObjectStylesheetResource} element instance. |
124 | * |
125 | * @return A new {@code modelObjectStylesheetResource} element instance. |
126 | * |
127 | * @see #getModelObjectStylesheetResources() |
128 | */ |
129 | public TransformerResourceType createModelObjectStylesheetResource() |
130 | { |
131 | final TransformerResourceType modelObjectStylesheetResource = new TransformerResourceType(); |
132 | this.getModelObjectStylesheetResources().add( modelObjectStylesheetResource ); |
133 | return modelObjectStylesheetResource; |
134 | } |
135 | |
136 | /** {@inheritDoc} */ |
137 | @Override |
138 | public void preExecuteTask() throws BuildException |
139 | { |
140 | super.preExecuteTask(); |
141 | |
142 | this.assertNotNull( "classesDirectory", this.getClassesDirectory() ); |
143 | this.assertLocationsNotNull( this.getModelObjectStylesheetResources() ); |
144 | } |
145 | |
146 | /** |
147 | * Commits model objects to class files. |
148 | * |
149 | * @throws BuildException if committing model objects fails. |
150 | */ |
151 | @Override |
152 | public void processClassFiles() throws BuildException |
153 | { |
154 | ProjectClassLoader classLoader = null; |
155 | boolean suppressExceptionOnClose = true; |
156 | |
157 | try |
158 | { |
159 | this.log( Messages.getMessage( "committingModelObjects", this.getModel() ) ); |
160 | |
161 | classLoader = this.newProjectClassLoader(); |
162 | final ModelContext context = this.newModelContext( classLoader ); |
163 | final ClassFileProcessor tool = this.newClassFileProcessor(); |
164 | final JAXBContext jaxbContext = context.createContext( this.getModel() ); |
165 | final Model model = this.getModel( context ); |
166 | final Source source = new JAXBSource( jaxbContext, new ObjectFactory().createModel( model ) ); |
167 | final ModelValidationReport validationReport = context.validateModel( this.getModel(), source ); |
168 | |
169 | this.logValidationReport( context, validationReport ); |
170 | tool.setModel( model ); |
171 | |
172 | final List<Transformer> transformers = |
173 | new ArrayList<Transformer>( this.getModelObjectStylesheetResources().size() ); |
174 | |
175 | for ( int i = 0, s0 = this.getModelObjectStylesheetResources().size(); i < s0; i++ ) |
176 | { |
177 | final Transformer transformer = |
178 | this.getTransformer( this.getModelObjectStylesheetResources().get( i ) ); |
179 | |
180 | if ( transformer != null ) |
181 | { |
182 | transformers.add( transformer ); |
183 | } |
184 | } |
185 | |
186 | if ( validationReport.isModelValid() ) |
187 | { |
188 | final Specification s = this.getSpecification( model ); |
189 | final Implementation i = this.getImplementation( model ); |
190 | final Module m = this.getModule( model ); |
191 | |
192 | if ( s != null ) |
193 | { |
194 | tool.commitModelObjects( s, context, this.getClassesDirectory() ); |
195 | |
196 | if ( !transformers.isEmpty() ) |
197 | { |
198 | tool.transformModelObjects( s, context, this.getClassesDirectory(), transformers ); |
199 | } |
200 | } |
201 | |
202 | |
203 | if ( i != null ) |
204 | { |
205 | tool.commitModelObjects( i, context, this.getClassesDirectory() ); |
206 | |
207 | if ( !transformers.isEmpty() ) |
208 | { |
209 | tool.transformModelObjects( i, context, this.getClassesDirectory(), transformers ); |
210 | } |
211 | } |
212 | |
213 | if ( m != null ) |
214 | { |
215 | tool.commitModelObjects( m, context, this.getClassesDirectory() ); |
216 | |
217 | if ( !transformers.isEmpty() ) |
218 | { |
219 | tool.transformModelObjects( m, context, this.getClassesDirectory(), transformers ); |
220 | } |
221 | } |
222 | |
223 | if ( this.isModulesProcessingRequested() ) |
224 | { |
225 | tool.commitModelObjects( context, this.getClassesDirectory() ); |
226 | |
227 | if ( !transformers.isEmpty() ) |
228 | { |
229 | tool.transformModelObjects( context, this.getClassesDirectory(), transformers ); |
230 | } |
231 | } |
232 | |
233 | suppressExceptionOnClose = false; |
234 | } |
235 | else |
236 | { |
237 | throw new ModelException( Messages.getMessage( "invalidModel", this.getModel() ) ); |
238 | } |
239 | } |
240 | catch ( final IOException e ) |
241 | { |
242 | throw new ClassProcessingException( Messages.getMessage( e ), e, this.getLocation() ); |
243 | } |
244 | catch ( final JAXBException e ) |
245 | { |
246 | throw new ClassProcessingException( Messages.getMessage( e ), e, this.getLocation() ); |
247 | } |
248 | catch ( final TransformerConfigurationException e ) |
249 | { |
250 | throw new ClassProcessingException( Messages.getMessage( e ), e, this.getLocation() ); |
251 | } |
252 | catch ( final ModelException e ) |
253 | { |
254 | throw new ClassProcessingException( Messages.getMessage( e ), e, this.getLocation() ); |
255 | } |
256 | finally |
257 | { |
258 | try |
259 | { |
260 | if ( classLoader != null ) |
261 | { |
262 | classLoader.close(); |
263 | } |
264 | } |
265 | catch ( final IOException e ) |
266 | { |
267 | if ( suppressExceptionOnClose ) |
268 | { |
269 | this.logMessage( Level.SEVERE, Messages.getMessage( e ), e ); |
270 | } |
271 | else |
272 | { |
273 | throw new ClassProcessingException( Messages.getMessage( e ), e, this.getLocation() ); |
274 | } |
275 | } |
276 | } |
277 | } |
278 | |
279 | /** {@inheritDoc} */ |
280 | @Override |
281 | public CommitClassesTask clone() |
282 | { |
283 | final CommitClassesTask clone = (CommitClassesTask) super.clone(); |
284 | clone.classesDirectory = |
285 | this.classesDirectory != null ? new File( this.classesDirectory.getAbsolutePath() ) : null; |
286 | |
287 | if ( this.modelObjectStylesheetResources != null ) |
288 | { |
289 | clone.modelObjectStylesheetResources = |
290 | new ArrayList<TransformerResourceType>( this.modelObjectStylesheetResources.size() ); |
291 | |
292 | for ( TransformerResourceType e : this.modelObjectStylesheetResources ) |
293 | { |
294 | clone.modelObjectStylesheetResources.add( e.clone() ); |
295 | } |
296 | } |
297 | |
298 | return clone; |
299 | } |
300 | |
301 | } |