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: WriteModelTask.java 4174 2012-01-15 09:30:01Z schulte2005 $
29   *
30   */
31  package org.jomc.ant;
32  
33  import java.io.BufferedReader;
34  import java.io.ByteArrayOutputStream;
35  import java.io.File;
36  import java.io.IOException;
37  import java.io.OutputStreamWriter;
38  import java.io.StringReader;
39  import java.io.StringWriter;
40  import java.util.logging.Level;
41  import javax.xml.bind.JAXBException;
42  import javax.xml.bind.Marshaller;
43  import javax.xml.bind.util.JAXBSource;
44  import org.apache.tools.ant.BuildException;
45  import org.apache.tools.ant.Project;
46  import org.jomc.model.Instance;
47  import org.jomc.model.Module;
48  import org.jomc.model.Modules;
49  import org.jomc.model.Specification;
50  import org.jomc.model.modlet.ModelHelper;
51  import org.jomc.modlet.Model;
52  import org.jomc.modlet.ModelContext;
53  import org.jomc.modlet.ModelException;
54  import org.jomc.modlet.ModelValidationReport;
55  import org.jomc.modlet.ObjectFactory;
56  
57  /**
58   * Task for writing model objects.
59   *
60   * @author <a href="mailto:schulte2005@users.sourceforge.net">Christian Schulte</a>
61   * @version $JOMC: WriteModelTask.java 4174 2012-01-15 09:30:01Z schulte2005 $
62   */
63  public final class WriteModelTask extends JomcModelTask
64  {
65  
66      /** The identifier of a specification to write. */
67      private String specification;
68  
69      /** The identifier of an implementation to write. */
70      private String implementation;
71  
72      /** The name of a module to write. */
73      private String module;
74  
75      /** The encoding to use when writing the model. */
76      private String modelEncoding;
77  
78      /** File to write the model to. */
79      private File modelFile;
80  
81      /** Creates a new {@code WriteModelTask} instance. */
82      public WriteModelTask()
83      {
84          super();
85      }
86  
87      /**
88       * Gets the encoding of the model resource.
89       *
90       * @return The encoding of the model resource.
91       *
92       * @see #setModelEncoding(java.lang.String)
93       */
94      public String getModelEncoding()
95      {
96          if ( this.modelEncoding == null )
97          {
98              this.modelEncoding = new OutputStreamWriter( new ByteArrayOutputStream() ).getEncoding();
99          }
100 
101         return this.modelEncoding;
102     }
103 
104     /**
105      * Sets the encoding of the model resource.
106      *
107      * @param value The new encoding of the model resource or {@code null}.
108      *
109      * @see #getModelEncoding()
110      */
111     public void setModelEncoding( final String value )
112     {
113         this.modelEncoding = value;
114     }
115 
116     /**
117      * Gets the file to write the model to.
118      *
119      * @return The file to write the model to or {@code null}.
120      *
121      * @see #setModelFile(java.io.File)
122      */
123     public File getModelFile()
124     {
125         return this.modelFile;
126     }
127 
128     /**
129      * Sets the file to write the model to.
130      *
131      * @param value The new file to write the model to or {@code null}.
132      *
133      * @see #getModelFile()
134      */
135     public void setModelFile( final File value )
136     {
137         this.modelFile = value;
138     }
139 
140     /**
141      * Gets the identifier of a specification to write.
142      *
143      * @return The identifier of a specification to write or {@code null}.
144      *
145      * @see #setSpecification(java.lang.String)
146      */
147     public String getSpecification()
148     {
149         return this.specification;
150     }
151 
152     /**
153      * Sets the identifier of a specification to write.
154      *
155      * @param value The new identifier of a specification to write or {@code null}.
156      *
157      * @see #getSpecification()
158      */
159     public void setSpecification( final String value )
160     {
161         this.specification = value;
162     }
163 
164     /**
165      * Gets the specification to write from a given model.
166      *
167      * @param model The model to get the specification to write from.
168      *
169      * @return The specification to write or {@code null}.
170      *
171      * @throws NullPointerException if {@code model} is {@code null}.
172      *
173      * @see #getSpecification()
174      */
175     public Specification getSpecification( final Model model )
176     {
177         if ( model == null )
178         {
179             throw new NullPointerException( "model" );
180         }
181 
182         Specification s = null;
183 
184         if ( this.getSpecification() != null )
185         {
186             final Modules modules = ModelHelper.getModules( model );
187 
188             if ( modules != null )
189             {
190                 s = modules.getSpecification( this.getSpecification() );
191             }
192 
193             if ( s == null )
194             {
195                 this.log( Messages.getMessage( "specificationNotFound", this.getSpecification() ), Project.MSG_WARN );
196             }
197         }
198 
199         return s;
200     }
201 
202     /**
203      * Gets the identifier of an implementation to write.
204      *
205      * @return The identifier of an implementation to write or {@code null}.
206      *
207      * @see #setImplementation(java.lang.String)
208      */
209     public String getImplementation()
210     {
211         return this.implementation;
212     }
213 
214     /**
215      * Sets the identifier of an implementation to write.
216      *
217      * @param value The new identifier of an implementation to write or {@code null}.
218      *
219      * @see #getImplementation()
220      */
221     public void setImplementation( final String value )
222     {
223         this.implementation = value;
224     }
225 
226     /**
227      * Gets the instance to write from a given model.
228      *
229      * @param model The model to get the instance to write from.
230      *
231      * @return The instance to write or {@code null}.
232      *
233      * @throws NullPointerException if {@code model} is {@code null}.
234      *
235      * @see #getImplementation()
236      */
237     public Instance getInstance( final Model model )
238     {
239         if ( model == null )
240         {
241             throw new NullPointerException( "model" );
242         }
243 
244         Instance i = null;
245 
246         if ( this.getImplementation() != null )
247         {
248             final Modules modules = ModelHelper.getModules( model );
249 
250             if ( modules != null )
251             {
252                 i = modules.getInstance( this.getImplementation() );
253             }
254 
255             if ( i == null )
256             {
257                 this.log( Messages.getMessage( "implementationNotFound", this.getImplementation() ), Project.MSG_WARN );
258             }
259         }
260 
261         return i;
262     }
263 
264     /**
265      * Gets the identifier of a module to write.
266      *
267      * @return The identifier of a module to write or {@code null}.
268      *
269      * @see #setModule(java.lang.String)
270      */
271     public String getModule()
272     {
273         return this.module;
274     }
275 
276     /**
277      * Sets the identifier of a module to write.
278      *
279      * @param value The new identifier of a module to write or {@code null}.
280      *
281      * @see #getModule()
282      */
283     public void setModule( final String value )
284     {
285         this.module = value;
286     }
287 
288     /**
289      * Gets the module to write from a given model.
290      *
291      * @param model The model to get the module to write from.
292      *
293      * @return The module to write or {@code null}.
294      *
295      * @throws NullPointerException if {@code model} is {@code null}.
296      *
297      * @see #getModule()
298      */
299     public Module getModule( final Model model )
300     {
301         if ( model == null )
302         {
303             throw new NullPointerException( "model" );
304         }
305 
306         Module m = null;
307 
308         if ( this.getModule() != null )
309         {
310             final Modules modules = ModelHelper.getModules( model );
311 
312             if ( modules != null )
313             {
314                 m = modules.getModule( this.getModule() );
315             }
316 
317             if ( m == null )
318             {
319                 this.log( Messages.getMessage( "moduleNotFound", this.getModule() ), Project.MSG_WARN );
320             }
321         }
322 
323         return m;
324     }
325 
326     /** {@inheritDoc} */
327     @Override
328     public void executeTask() throws BuildException
329     {
330         BufferedReader reader = null;
331         ProjectClassLoader classLoader = null;
332         boolean suppressExceptionOnClose = true;
333 
334         try
335         {
336             classLoader = this.newProjectClassLoader();
337             final ModelContext modelContext = this.newModelContext( classLoader );
338             final Model model = this.getModel( modelContext );
339             final Marshaller marshaller = modelContext.createMarshaller( this.getModel() );
340             final ModelValidationReport validationReport = modelContext.validateModel(
341                 this.getModel(), new JAXBSource( marshaller, new ObjectFactory().createModel( model ) ) );
342 
343             this.logValidationReport( modelContext, validationReport );
344             marshaller.setProperty( Marshaller.JAXB_ENCODING, this.getModelEncoding() );
345             marshaller.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE );
346 
347             Model displayModel = new Model();
348             displayModel.setIdentifier( this.getModel() );
349 
350             final Specification s = this.getSpecification( model );
351             if ( s != null )
352             {
353                 displayModel.getAny().add( s );
354             }
355 
356             final Instance i = this.getInstance( model );
357             if ( i != null )
358             {
359                 displayModel.getAny().add( i );
360             }
361 
362             final Module m = this.getModule( model );
363             if ( m != null )
364             {
365                 displayModel.getAny().add( m );
366             }
367 
368             if ( displayModel.getAny().isEmpty() )
369             {
370                 displayModel = model;
371             }
372 
373             if ( this.getModelFile() != null )
374             {
375                 this.log( Messages.getMessage( "writingModelObjects", this.getModel(),
376                                                this.getModelFile().getAbsolutePath() ), Project.MSG_INFO );
377 
378                 marshaller.marshal( new ObjectFactory().createModel( displayModel ), this.getModelFile() );
379             }
380             else
381             {
382                 this.log( Messages.getMessage( "showingModelObjects", this.getModel() ), Project.MSG_INFO );
383 
384                 final StringWriter writer = new StringWriter();
385                 marshaller.marshal( new ObjectFactory().createModel( displayModel ), writer );
386 
387                 reader = new BufferedReader( new StringReader( writer.toString() ) );
388                 String line;
389 
390                 while ( ( line = reader.readLine() ) != null )
391                 {
392                     this.log( line, Project.MSG_INFO );
393                 }
394             }
395 
396             suppressExceptionOnClose = false;
397         }
398         catch ( final IOException e )
399         {
400             throw new BuildException( Messages.getMessage( e ), e, this.getLocation() );
401         }
402         catch ( final JAXBException e )
403         {
404             String message = Messages.getMessage( e );
405             if ( message == null )
406             {
407                 message = Messages.getMessage( e.getLinkedException() );
408             }
409 
410             throw new BuildException( message, e, this.getLocation() );
411         }
412         catch ( final ModelException e )
413         {
414             throw new BuildException( Messages.getMessage( e ), e, this.getLocation() );
415         }
416         finally
417         {
418             try
419             {
420                 if ( reader != null )
421                 {
422                     reader.close();
423                 }
424             }
425             catch ( final IOException e )
426             {
427                 if ( suppressExceptionOnClose )
428                 {
429                     this.logMessage( Level.SEVERE, Messages.getMessage( e ), e );
430                 }
431                 else
432                 {
433                     throw new BuildException( Messages.getMessage( e ), e, this.getLocation() );
434                 }
435             }
436             finally
437             {
438                 try
439                 {
440                     if ( classLoader != null )
441                     {
442                         classLoader.close();
443                     }
444                 }
445                 catch ( final IOException e )
446                 {
447                     if ( suppressExceptionOnClose )
448                     {
449                         this.logMessage( Level.SEVERE, Messages.getMessage( e ), e );
450                     }
451                     else
452                     {
453                         throw new BuildException( Messages.getMessage( e ), e, this.getLocation() );
454                     }
455                 }
456             }
457         }
458     }
459 
460     /** {@inheritDoc} */
461     @Override
462     public WriteModelTask clone()
463     {
464         return (WriteModelTask) super.clone();
465     }
466 
467 }