View Javadoc

1   /*
2    *   Copyright (c) 2009 The JOMC Project
3    *   Copyright (c) 2005 Christian Schulte <cs@jomc.org>
4    *   All rights reserved.
5    *
6    *   Redistribution and use in source and binary forms, with or without
7    *   modification, are permitted provided that the following conditions
8    *   are met:
9    *
10   *     o Redistributions of source code must retain the above copyright
11   *       notice, this list of conditions and the following disclaimer.
12   *
13   *     o Redistributions in binary form must reproduce the above copyright
14   *       notice, this list of conditions and the following disclaimer in
15   *       the documentation and/or other materials provided with the
16   *       distribution.
17   *
18   *   THIS SOFTWARE IS PROVIDED BY THE JOMC PROJECT AND CONTRIBUTORS "AS IS"
19   *   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20   *   THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21   *   PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JOMC PROJECT OR
22   *   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23   *   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24   *   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25   *   OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26   *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27   *   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28   *   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29   *
30   *   $Id: JavaSources.java 1237 2010-01-09 20:22:54Z schulte2005 $
31   *
32   */
33  package org.jomc.tools;
34  
35  import java.io.File;
36  import java.io.IOException;
37  import java.io.StringWriter;
38  import java.text.MessageFormat;
39  import java.util.ResourceBundle;
40  import java.util.logging.Level;
41  import org.apache.commons.io.FileUtils;
42  import org.apache.velocity.Template;
43  import org.apache.velocity.VelocityContext;
44  import org.jomc.model.Dependencies;
45  import org.jomc.model.Implementation;
46  import org.jomc.model.Messages;
47  import org.jomc.model.Module;
48  import org.jomc.model.Properties;
49  import org.jomc.model.Specification;
50  import org.jomc.model.Specifications;
51  import org.jomc.util.LineEditor;
52  import org.jomc.util.Section;
53  import org.jomc.util.SectionEditor;
54  import org.jomc.util.TrailingWhitespaceEditor;
55  
56  /**
57   * Manages Java source code.
58   *
59   * <p><b>Use cases</b><br/><ul>
60   * <li>{@link #manageSources(java.io.File) }</li>
61   * <li>{@link #manageSources(org.jomc.model.Module, java.io.File) }</li>
62   * <li>{@link #manageSources(org.jomc.model.Specification, java.io.File) }</li>
63   * <li>{@link #manageSources(org.jomc.model.Implementation, java.io.File) }</li>
64   * </ul></p>
65   *
66   * @author <a href="mailto:cs@jomc.org">Christian Schulte</a>
67   * @version $Id: JavaSources.java 1237 2010-01-09 20:22:54Z schulte2005 $
68   *
69   * @see #getModules()
70   */
71  public class JavaSources extends JomcTool
72  {
73  
74      /** Constant for the name of the constructors source code section. */
75      private static final String CONSTRUCTORS_SECTION_NAME = "Constructors";
76  
77      /** Constant for the name of the default constructor source code section. */
78      private static final String DEFAULT_CONSTRUCTOR_SECTION_NAME = "Default Constructor";
79  
80      /** Constant for the name of the dependencies source code section. */
81      private static final String DEPENDENCIES_SECTION_NAME = "Dependencies";
82  
83      /** Constant for the name of the properties source code section. */
84      private static final String PROPERTIES_SECTION_NAME = "Properties";
85  
86      /** Constant for the name of the messages source code section. */
87      private static final String MESSAGES_SECTION_NAME = "Messages";
88  
89      /** Constant for the name of the license source code section. */
90      private static final String LICENSE_SECTION_NAME = "License Header";
91  
92      /** Constant for the name of the documentation source code section. */
93      private static final String DOCUMENTATION_SECTION_NAME = "Documentation";
94  
95      /** Constant for the name of the implementation annotations source code section. */
96      private static final String ANNOTATIONS_SECTION_NAME = "Annotations";
97  
98      /** Name of the generator. */
99      private static final String GENERATOR_NAME = JavaSources.class.getName();
100 
101     /** Constant for the version of the generator. */
102     private static final String GENERATOR_VERSION = "1.0";
103 
104     /** Name of the {@code implementation-constructors-head.vm} template. */
105     private static final String CONSTRUCTORS_HEAD_TEMPLATE = "implementation-constructors-head.vm";
106 
107     /** Name of the {@code implementation-constructors-tail.vm} template. */
108     private static final String CONSTRUCTORS_TAIL_TEMPLATE = "implementation-constructors-tail.vm";
109 
110     /** Name of the {@code implementation-dependencies.vm} template. */
111     private static final String DEPENDENCIES_TEMPLATE = "implementation-dependencies.vm";
112 
113     /** Name of the {@code implementation-properties.vm} template. */
114     private static final String PROPERTIES_TEMPLATE = "implementation-properties.vm";
115 
116     /** Name of the {@code implementation-messages.vm} template. */
117     private static final String MESSAGES_TEMPLATE = "implementation-messages.vm";
118 
119     /** Name of the {@code specification-license.vm} template. */
120     private static final String SPECIFICATION_LICENSE_TEMPLATE = "specification-license.vm";
121 
122     /** Name of the {@code implementation-license.vm} template. */
123     private static final String IMPLEMENTATION_LICENSE_TEMPLATE = "implementation-license.vm";
124 
125     /** Name of the {@code specification-documentation.vm} template. */
126     private static final String SPECIFICATION_DOCUMENTATION_TEMPLATE = "specification-documentation.vm";
127 
128     /** Name of the {@code implementation-documentation.vm} template. */
129     private static final String IMPLEMENTATION_DOCUMENTATION_TEMPLATE = "implementation-documentation.vm";
130 
131     /** Name of the {@code Implementation.java.vm} template. */
132     private static final String IMPLEMENTATION_TEMPLATE = "Implementation.java.vm";
133 
134     /** Name of the {@code Specification.java.vm} template. */
135     private static final String SPECIFICATION_TEMPLATE = "Specification.java.vm";
136 
137     /** Name of the {@code specification-annotations.vm} template. */
138     private static final String SPECIFICATION_ANNOTATIONS_TEMPLATE = "specification-annotations.vm";
139 
140     /** Name of the {@code implementation-annotations.vm} template. */
141     private static final String IMPLEMENTATION_ANNOTATIONS_TEMPLATE = "implementation-annotations.vm";
142 
143     /** Creates a new {@code JavaSources} instance. */
144     public JavaSources()
145     {
146         super();
147     }
148 
149     /**
150      * Creates a new {@code JavaSources} instance taking a {@code JavaSources} instance to initialize the instance with.
151      *
152      * @param tool The instance to initialize the new instance with,
153      */
154     public JavaSources( final JavaSources tool )
155     {
156         super( tool );
157     }
158 
159     /**
160      * Manages the source code of the modules of the instance.
161      *
162      * @param sourcesDirectory The directory holding the sources to manage.
163      *
164      * @throws NullPointerException if {@code sourcesDirectory} is {@code null}.
165      * @throws ToolException if managing sources fails.
166      *
167      * @see #manageSources(org.jomc.model.Module, java.io.File)
168      */
169     public void manageSources( final File sourcesDirectory ) throws ToolException
170     {
171         if ( sourcesDirectory == null )
172         {
173             throw new NullPointerException( "sourcesDirectory" );
174         }
175 
176         for ( Module m : this.getModules().getModule() )
177         {
178             this.manageSources( m, sourcesDirectory );
179         }
180     }
181 
182     /**
183      * Manages the source code of a given module of the modules of the instance.
184      *
185      * @param module The module to process.
186      * @param sourcesDirectory The directory holding the sources to manage.
187      *
188      * @throws NullPointerException if {@code module} or {@code sourcesDirectory} is {@code null}.
189      * @throws ToolException if managing sources fails.
190      *
191      * @see #manageSources(org.jomc.model.Specification, java.io.File)
192      * @see #manageSources(org.jomc.model.Implementation, java.io.File)
193      */
194     public void manageSources( final Module module, final File sourcesDirectory ) throws ToolException
195     {
196         if ( module == null )
197         {
198             throw new NullPointerException( "module" );
199         }
200         if ( sourcesDirectory == null )
201         {
202             throw new NullPointerException( "sourcesDirectory" );
203         }
204 
205         if ( module.getSpecifications() != null )
206         {
207             for ( Specification s : module.getSpecifications().getSpecification() )
208             {
209                 this.manageSources( s, sourcesDirectory );
210             }
211         }
212         if ( module.getImplementations() != null )
213         {
214             for ( Implementation i : module.getImplementations().getImplementation() )
215             {
216                 this.manageSources( i, sourcesDirectory );
217             }
218         }
219     }
220 
221     /**
222      * Manages the source code of a given specification of the modules of the instance.
223      *
224      * @param specification The specification to process.
225      * @param sourcesDirectory The directory holding the sources to manage.
226      *
227      * @throws NullPointerException if {@code specification} or {@code sourcesDirectory} is {@code null}.
228      * @throws ToolException if managing sources fails.
229      *
230      * @see #getSpecificationEditor(org.jomc.model.Specification)
231      */
232     public void manageSources( final Specification specification, final File sourcesDirectory ) throws ToolException
233     {
234         if ( specification == null )
235         {
236             throw new NullPointerException( "specification" );
237         }
238         if ( sourcesDirectory == null )
239         {
240             throw new NullPointerException( "sourcesDirectory" );
241         }
242 
243         try
244         {
245             final Implementation i = this.getModules().getImplementation( specification.getIdentifier() );
246 
247             if ( i != null && i.isClassDeclaration() )
248             {
249                 this.manageSources( i, sourcesDirectory );
250             }
251             else if ( specification.isClassDeclaration() )
252             {
253                 final File f =
254                     new File( sourcesDirectory, specification.getIdentifier().replace( '.', '/' ) + ".java" );
255 
256                 final String content = f.exists()
257                                        ? FileUtils.readFileToString( f, this.getInputEncoding() )
258                                        : this.getSpecificationTemplate( specification );
259 
260                 final JavaSpecificationEditor editor = this.getSpecificationEditor( specification );
261                 final String edited;
262                 try
263                 {
264                     edited = editor.edit( content );
265                 }
266                 catch ( final IOException e )
267                 {
268                     throw new ToolException( this.getMessage( "failedEditing", new Object[]
269                         {
270                             f.getCanonicalPath(), e.getMessage()
271                         } ), e );
272 
273                 }
274 
275                 if ( !editor.isLicenseSectionPresent() && this.isLoggable( Level.INFO ) )
276                 {
277                     this.log( Level.INFO, this.getMessage( "missingOptionalSection", new Object[]
278                         {
279                             LICENSE_SECTION_NAME,
280                             f.getCanonicalPath()
281                         } ), null );
282 
283                 }
284 
285                 if ( !editor.isAnnotationsSectionPresent() )
286                 {
287                     throw new IOException( this.getMessage( "missingSection", new Object[]
288                         {
289                             ANNOTATIONS_SECTION_NAME,
290                             f.getCanonicalPath()
291                         } ) );
292 
293                 }
294 
295                 if ( !editor.isDocumentationSectionPresent() && this.isLoggable( Level.INFO ) )
296                 {
297                     this.log( Level.INFO, this.getMessage( "missingOptionalSection", new Object[]
298                         {
299                             DOCUMENTATION_SECTION_NAME,
300                             f.getCanonicalPath()
301                         } ), null );
302 
303                 }
304 
305                 if ( !edited.equals( content ) )
306                 {
307                     if ( !f.getParentFile().exists() && !f.getParentFile().mkdirs() )
308                     {
309                         throw new ToolException( this.getMessage( "failedCreatingDirectory", new Object[]
310                             {
311                                 f.getParentFile().getAbsolutePath()
312                             } ) );
313 
314                     }
315 
316                     if ( this.isLoggable( Level.INFO ) )
317                     {
318                         this.log( Level.INFO, this.getMessage( "editing", new Object[]
319                             {
320                                 f.getCanonicalPath()
321                             } ), null );
322 
323                     }
324 
325                     FileUtils.writeStringToFile( f, edited, this.getOutputEncoding() );
326                 }
327             }
328         }
329         catch ( final IOException e )
330         {
331             throw new ToolException( e );
332         }
333     }
334 
335     /**
336      * Manages the source code of a given implementation of the modules of the instance.
337      *
338      * @param implementation The implementation to process.
339      * @param sourcesDirectory The directory holding the sources to manage.
340      *
341      * @throws NullPointerException if {@code implementation} or {@code sourcesDirectory} is {@code null}.
342      * @throws ToolException if managing sources fails.
343      *
344      * @see #getImplementationEditor(org.jomc.model.Implementation)
345      */
346     public void manageSources( final Implementation implementation, final File sourcesDirectory ) throws ToolException
347     {
348         if ( implementation == null )
349         {
350             throw new NullPointerException( "implementation" );
351         }
352         if ( sourcesDirectory == null )
353         {
354             throw new NullPointerException( "sourcesDirectory" );
355         }
356 
357         try
358         {
359             if ( implementation.isClassDeclaration() )
360             {
361                 final File f = new File( sourcesDirectory, implementation.getClazz().replace( '.', '/' ) + ".java" );
362                 final String content = f.exists()
363                                        ? FileUtils.readFileToString( f, this.getInputEncoding() )
364                                        : this.getImplementationTemplate( implementation );
365 
366                 final JavaImplementationEditor editor = this.getImplementationEditor( implementation );
367                 final String edited;
368                 try
369                 {
370                     edited = editor.edit( content );
371                 }
372                 catch ( final IOException e )
373                 {
374                     throw new ToolException( this.getMessage( "failedEditing", new Object[]
375                         {
376                             f.getCanonicalPath(), e.getMessage()
377                         } ), e );
378 
379                 }
380 
381                 if ( !editor.isLicenseSectionPresent() && this.isLoggable( Level.INFO ) )
382                 {
383                     this.log( Level.INFO, this.getMessage( "missingOptionalSection", new Object[]
384                         {
385                             LICENSE_SECTION_NAME,
386                             f.getCanonicalPath()
387                         } ), null );
388 
389                 }
390 
391                 if ( !editor.isAnnotationsSectionPresent() )
392                 {
393                     throw new ToolException( this.getMessage( "missingSection", new Object[]
394                         {
395                             ANNOTATIONS_SECTION_NAME,
396                             f.getCanonicalPath()
397                         } ) );
398 
399                 }
400 
401                 if ( !editor.isDocumentationSectionPresent() && this.isLoggable( Level.INFO ) )
402                 {
403                     this.log( Level.INFO, this.getMessage( "missingOptionalSection", new Object[]
404                         {
405                             DOCUMENTATION_SECTION_NAME,
406                             f.getCanonicalPath()
407                         } ), null );
408 
409                 }
410 
411                 if ( !editor.isConstructorsSectionPresent() )
412                 {
413                     final Specifications specifications =
414                         this.getModules().getSpecifications( implementation.getIdentifier() );
415 
416                     if ( specifications != null &&
417                          !( specifications.getSpecification().isEmpty() && specifications.getReference().isEmpty() ) )
418                     {
419                         throw new ToolException( this.getMessage( "missingSection", new Object[]
420                             {
421                                 CONSTRUCTORS_SECTION_NAME,
422                                 f.getCanonicalPath()
423                             } ) );
424 
425                     }
426                     else if ( this.isLoggable( Level.INFO ) )
427                     {
428                         this.log( Level.INFO, this.getMessage( "missingOptionalSection", new Object[]
429                             {
430                                 CONSTRUCTORS_SECTION_NAME,
431                                 f.getCanonicalPath()
432                             } ), null );
433 
434                     }
435                 }
436                 else if ( !editor.isDefaultConstructorSectionPresent() )
437                 {
438                     throw new ToolException( this.getMessage( "missingSection", new Object[]
439                         {
440                             DEFAULT_CONSTRUCTOR_SECTION_NAME,
441                             f.getCanonicalPath()
442                         } ) );
443 
444                 }
445 
446                 if ( !editor.isPropertiesSectionPresent() )
447                 {
448                     final Properties properties = this.getModules().getProperties( implementation.getIdentifier() );
449 
450                     if ( properties != null && !properties.getProperty().isEmpty() )
451                     {
452                         throw new ToolException( this.getMessage( "missingSection", new Object[]
453                             {
454                                 PROPERTIES_SECTION_NAME,
455                                 f.getCanonicalPath()
456                             } ) );
457 
458                     }
459                     else if ( this.isLoggable( Level.INFO ) )
460                     {
461                         this.log( Level.INFO, this.getMessage( "missingOptionalSection", new Object[]
462                             {
463                                 PROPERTIES_SECTION_NAME,
464                                 f.getCanonicalPath()
465                             } ), null );
466 
467                     }
468                 }
469 
470                 if ( !editor.isDependenciesSectionPresent() )
471                 {
472                     final Dependencies dependencies =
473                         this.getModules().getDependencies( implementation.getIdentifier() );
474 
475                     if ( dependencies != null && !dependencies.getDependency().isEmpty() )
476                     {
477                         throw new ToolException( this.getMessage( "missingSection", new Object[]
478                             {
479                                 DEPENDENCIES_SECTION_NAME,
480                                 f.getCanonicalPath()
481                             } ) );
482 
483                     }
484                     else if ( this.isLoggable( Level.INFO ) )
485                     {
486                         this.log( Level.INFO, this.getMessage( "missingOptionalSection", new Object[]
487                             {
488                                 DEPENDENCIES_SECTION_NAME,
489                                 f.getCanonicalPath()
490                             } ), null );
491 
492                     }
493                 }
494 
495                 if ( !editor.isMessagesSectionPresent() )
496                 {
497                     final Messages messages = this.getModules().getMessages( implementation.getIdentifier() );
498 
499                     if ( messages != null && !messages.getMessage().isEmpty() )
500                     {
501                         throw new ToolException( this.getMessage( "missingSection", new Object[]
502                             {
503                                 MESSAGES_SECTION_NAME,
504                                 f.getCanonicalPath()
505                             } ) );
506 
507                     }
508                     else if ( this.isLoggable( Level.INFO ) )
509                     {
510                         this.log( Level.INFO, this.getMessage( "missingOptionalSection", new Object[]
511                             {
512                                 MESSAGES_SECTION_NAME,
513                                 f.getCanonicalPath()
514                             } ), null );
515 
516                     }
517                 }
518 
519                 if ( !edited.equals( content ) )
520                 {
521                     if ( !f.getParentFile().exists() && !f.getParentFile().mkdirs() )
522                     {
523                         throw new ToolException( this.getMessage( "failedCreatingDirectory", new Object[]
524                             {
525                                 f.getParentFile().getAbsolutePath()
526                             } ) );
527 
528                     }
529 
530                     if ( this.isLoggable( Level.INFO ) )
531                     {
532                         this.log( Level.INFO, this.getMessage( "editing", new Object[]
533                             {
534                                 f.getCanonicalPath()
535                             } ), null );
536 
537                     }
538 
539                     FileUtils.writeStringToFile( f, edited, this.getOutputEncoding() );
540                 }
541             }
542         }
543         catch ( final IOException e )
544         {
545             throw new ToolException( e );
546         }
547     }
548 
549     /**
550      * Gets a new editor for editing Java specification source code.
551      *
552      * @param specification The specification to create a new editor for.
553      *
554      * @return A new editor for editing the source code of {@code specification}.
555      *
556      * @throws NullPointerException if {@code specification} is {@code null}.
557      */
558     public JavaSpecificationEditor getSpecificationEditor( final Specification specification )
559     {
560         if ( specification == null )
561         {
562             throw new NullPointerException( "specification" );
563         }
564 
565         return new JavaSpecificationEditor( new TrailingWhitespaceEditor(), specification );
566     }
567 
568     /**
569      * Gets a new editor for editing Java implementation source code.
570      *
571      * @param implementation The implementation to create a new editor for.
572      *
573      * @return A new editor for editing the source code of {@code implementation}.
574      *
575      * @throws NullPointerException if {@code implementation} is {@code null}.
576      */
577     public JavaImplementationEditor getImplementationEditor( final Implementation implementation )
578     {
579         if ( implementation == null )
580         {
581             throw new NullPointerException( "implementation" );
582         }
583 
584         return new JavaImplementationEditor( new TrailingWhitespaceEditor(), implementation );
585     }
586 
587     /**
588      * Gets the velocity context used for merging templates.
589      *
590      * @return The velocity context used for merging templates.
591      */
592     @Override
593     public VelocityContext getVelocityContext()
594     {
595         final VelocityContext ctx = super.getVelocityContext();
596         ctx.put( "generatorName", GENERATOR_NAME );
597         ctx.put( "generatorVersion", GENERATOR_VERSION );
598         return ctx;
599     }
600 
601     /**
602      * Gets the Java source code template of specification.
603      *
604      * @param specification The specification to get the source code template of.
605      *
606      * @throws ToolException if getting the source code section fails.
607      */
608     private String getSpecificationTemplate( final Specification specification ) throws ToolException
609     {
610         try
611         {
612             final StringWriter writer = new StringWriter();
613             final VelocityContext ctx = this.getVelocityContext();
614             final Template template = this.getVelocityTemplate( SPECIFICATION_TEMPLATE );
615             ctx.put( "specification", specification );
616             ctx.put( "template", template );
617             template.merge( ctx, writer );
618             writer.close();
619             return writer.toString();
620         }
621         catch ( final IOException e )
622         {
623             throw new ToolException( e );
624         }
625     }
626 
627     /**
628      * Gets the Java source code template of an implementation.
629      *
630      * @param implementation The implementation to get the source code template of.
631      *
632      * @throws ToolException if getting the source code section fails.
633      */
634     private String getImplementationTemplate( final Implementation implementation ) throws ToolException
635     {
636         try
637         {
638             final StringWriter writer = new StringWriter();
639             final VelocityContext ctx = this.getVelocityContext();
640             final Template template = this.getVelocityTemplate( IMPLEMENTATION_TEMPLATE );
641             ctx.put( "implementation", implementation );
642             ctx.put( "template", template );
643             template.merge( ctx, writer );
644             writer.close();
645             return writer.toString();
646         }
647         catch ( final IOException e )
648         {
649             throw new ToolException( e );
650         }
651     }
652 
653     /**
654      * Gets the Java source code of the license section of a specification.
655      *
656      * @param specification The specification to get the source code of the license section of.
657      *
658      * @throws ToolException if getting the source code section fails.
659      */
660     private String getLicenseSection( final Specification specification ) throws ToolException
661     {
662         try
663         {
664             final StringWriter writer = new StringWriter();
665             final VelocityContext ctx = this.getVelocityContext();
666             final Template template = this.getVelocityTemplate( SPECIFICATION_LICENSE_TEMPLATE );
667             ctx.put( "specification", specification );
668             ctx.put( "template", template );
669             template.merge( ctx, writer );
670             writer.close();
671             return writer.toString();
672         }
673         catch ( final IOException e )
674         {
675             throw new ToolException( e );
676         }
677     }
678 
679     /**
680      * Gets the Java source code of the license section of an implementation..
681      *
682      * @param implementation The implementation to get the source code of the license section of.
683      *
684      * @throws ToolException if getting the source code section fails.
685      */
686     private String getLicenseSection( final Implementation implementation ) throws ToolException
687     {
688         try
689         {
690             final StringWriter writer = new StringWriter();
691             final VelocityContext ctx = this.getVelocityContext();
692             final Template template = this.getVelocityTemplate( IMPLEMENTATION_LICENSE_TEMPLATE );
693             ctx.put( "implementation", implementation );
694             ctx.put( "template", template );
695             template.merge( ctx, writer );
696             writer.close();
697             return writer.toString();
698         }
699         catch ( final IOException e )
700         {
701             throw new ToolException( e );
702         }
703     }
704 
705     /**
706      * Gets the Java source code of the specification annotations section.
707      *
708      * @param specification The specification to get the source code of the annotations section of.
709      *
710      * @throws ToolException if getting the source code section fails.
711      */
712     private String getAnnotationsSection( final Specification specification ) throws ToolException
713     {
714         try
715         {
716             final StringWriter writer = new StringWriter();
717             final VelocityContext ctx = this.getVelocityContext();
718             final Template template = this.getVelocityTemplate( SPECIFICATION_ANNOTATIONS_TEMPLATE );
719             ctx.put( "specification", specification );
720             ctx.put( "template", template );
721             template.merge( ctx, writer );
722             writer.close();
723             return writer.toString();
724         }
725         catch ( final IOException e )
726         {
727             throw new ToolException( e );
728         }
729     }
730 
731     /**
732      * Gets the Java source code of the implementation annotations section.
733      *
734      * @param implementation The implementation to get the source code of the annotations section of.
735      *
736      * @throws ToolException if getting the source code section fails.
737      */
738     private String getAnnotationsSection( final Implementation implementation ) throws ToolException
739     {
740         try
741         {
742             final StringWriter writer = new StringWriter();
743             final VelocityContext ctx = this.getVelocityContext();
744             final Template template = this.getVelocityTemplate( IMPLEMENTATION_ANNOTATIONS_TEMPLATE );
745             ctx.put( "implementation", implementation );
746             ctx.put( "template", template );
747             template.merge( ctx, writer );
748             writer.close();
749             return writer.toString();
750         }
751         catch ( final IOException e )
752         {
753             throw new ToolException( e );
754         }
755     }
756 
757     /**
758      * Gets the Java source code of the documentation section of a specification.
759      *
760      * @param specification The specification to get the source code section of.
761      *
762      * @throws ToolException if getting the source code section fails.
763      */
764     private String getDocumentationSection( final Specification specification ) throws ToolException
765     {
766         try
767         {
768             final StringWriter writer = new StringWriter();
769             final VelocityContext ctx = this.getVelocityContext();
770             final Template template = this.getVelocityTemplate( SPECIFICATION_DOCUMENTATION_TEMPLATE );
771             ctx.put( "specification", specification );
772             ctx.put( "template", template );
773             template.merge( ctx, writer );
774             writer.close();
775             return writer.toString();
776         }
777         catch ( final IOException e )
778         {
779             throw new ToolException( e );
780         }
781     }
782 
783     /**
784      * Gets the Java source code of the documentation section of an implementation.
785      *
786      * @param implementation The implementation to get the source code section of.
787      *
788      * @throws ToolException if getting the source code section fails.
789      */
790     private String getDocumentationSection( final Implementation implementation ) throws ToolException
791     {
792         try
793         {
794             final StringWriter writer = new StringWriter();
795             final VelocityContext ctx = this.getVelocityContext();
796             final Template template = this.getVelocityTemplate( IMPLEMENTATION_DOCUMENTATION_TEMPLATE );
797             ctx.put( "implementation", implementation );
798             ctx.put( "template", template );
799             template.merge( ctx, writer );
800             writer.close();
801             return writer.toString();
802         }
803         catch ( final IOException e )
804         {
805             throw new ToolException( e );
806         }
807     }
808 
809     /**
810      * Gets the Java source code of the constructors section head content of an implementation.
811      *
812      * @param implementation The implementation to get the constructors section head content of.
813      *
814      * @throws ToolException if getting the source code section fails.
815      */
816     private String getConstructorsSectionHeadContent( final Implementation implementation ) throws ToolException
817     {
818         try
819         {
820             final StringWriter writer = new StringWriter();
821             final VelocityContext ctx = this.getVelocityContext();
822             final Template template = this.getVelocityTemplate( CONSTRUCTORS_HEAD_TEMPLATE );
823             ctx.put( "implementation", implementation );
824             ctx.put( "template", template );
825             template.merge( ctx, writer );
826             writer.close();
827             return writer.toString();
828         }
829         catch ( final IOException e )
830         {
831             throw new ToolException( e );
832         }
833     }
834 
835     /**
836      * Gets the Java source code of the constructors section tail content of an implementation.
837      *
838      * @param implementation The implementation to get the constructors section tail content of.
839      *
840      * @throws ToolException if getting the source code section fails.
841      */
842     private String getConstructorsSectionTailContent( final Implementation implementation ) throws ToolException
843     {
844         try
845         {
846             final StringWriter writer = new StringWriter();
847             final VelocityContext ctx = this.getVelocityContext();
848             final Template template = this.getVelocityTemplate( CONSTRUCTORS_TAIL_TEMPLATE );
849             ctx.put( "implementation", implementation );
850             ctx.put( "template", template );
851             template.merge( ctx, writer );
852             writer.close();
853             return writer.toString();
854         }
855         catch ( final IOException e )
856         {
857             throw new ToolException( e );
858         }
859     }
860 
861     /**
862      * Gets the Java source code of the dependencies section of an implementation.
863      *
864      * @param implementation The implementation to get the source code of the dependencies section of.
865      *
866      * @throws ToolException if getting the source code section fails.
867      */
868     private String getDependenciesSection( final Implementation implementation ) throws ToolException
869     {
870         try
871         {
872             final StringWriter writer = new StringWriter();
873             final VelocityContext ctx = this.getVelocityContext();
874             final Template template = this.getVelocityTemplate( DEPENDENCIES_TEMPLATE );
875             ctx.put( "implementation", implementation );
876             ctx.put( "template", template );
877             template.merge( ctx, writer );
878             writer.close();
879             return writer.toString();
880         }
881         catch ( final IOException e )
882         {
883             throw new ToolException( e );
884         }
885     }
886 
887     /**
888      * Gets the Java source code of the properties section of an implementation.
889      *
890      * @param implementation The implementation to get the source code of the properties section of.
891      *
892      * @throws ToolException if getting the source code section fails.
893      */
894     private String getPropertiesSection( final Implementation implementation ) throws ToolException
895     {
896         try
897         {
898             final StringWriter writer = new StringWriter();
899             final VelocityContext ctx = this.getVelocityContext();
900             final Template template = this.getVelocityTemplate( PROPERTIES_TEMPLATE );
901             ctx.put( "implementation", implementation );
902             ctx.put( "template", template );
903             template.merge( ctx, writer );
904             writer.close();
905             return writer.toString();
906         }
907         catch ( final IOException e )
908         {
909             throw new ToolException( e );
910         }
911     }
912 
913     /**
914      * Gets the Java source code of the messages section of an implementation.
915      *
916      * @param implementation The implementation to get the source code of the messages section of.
917      *
918      * @throws ToolException if getting the source code section fails.
919      */
920     private String getMessagesSection( final Implementation implementation ) throws ToolException
921     {
922         try
923         {
924             final StringWriter writer = new StringWriter();
925             final VelocityContext ctx = this.getVelocityContext();
926             final Template template = this.getVelocityTemplate( MESSAGES_TEMPLATE );
927             ctx.put( "implementation", implementation );
928             ctx.put( "template", template );
929             template.merge( ctx, writer );
930             writer.close();
931             return writer.toString();
932         }
933         catch ( final IOException e )
934         {
935             throw new ToolException( e );
936         }
937     }
938 
939     private String getMessage( final String key, final Object args )
940     {
941         final ResourceBundle b = ResourceBundle.getBundle( JavaSources.class.getName().replace( '.', '/' ) );
942         final MessageFormat f = new MessageFormat( b.getString( key ) );
943         return f.format( args );
944     }
945 
946     /**
947      * Extension to {@code SectionEditor} for editing Java source code.
948      *
949      * @author <a href="mailto:cs@jomc.org">Christian Schulte</a>
950      * @version $Id: JavaSources.java 1237 2010-01-09 20:22:54Z schulte2005 $
951      */
952     public abstract class JavaEditor extends SectionEditor
953     {
954 
955         /** Flag indicating that the source code of the editor contains a license section. */
956         private boolean licenseSectionPresent;
957 
958         /** Flag indicating that the source code of the editor contains an annotations section. */
959         private boolean annotationsSectionPresent;
960 
961         /** Flag indicating that the source code of the editor contains a documentation section. */
962         private boolean documentationSectionPresent;
963 
964         /** Creates a new {@code JavaEditor} instance. */
965         public JavaEditor()
966         {
967             super();
968         }
969 
970         /**
971          * Creates a new {@code JavaEditor} instance taking a {@code LineEditor} to chain.
972          *
973          * @param lineEditor The editor to chain.
974          */
975         public JavaEditor( final LineEditor lineEditor )
976         {
977             super( lineEditor );
978         }
979 
980         @Override
981         public String getOutput( final Section section ) throws IOException
982         {
983             if ( section == null )
984             {
985                 throw new NullPointerException( "section" );
986             }
987 
988             this.licenseSectionPresent = false;
989             this.annotationsSectionPresent = false;
990             this.documentationSectionPresent = false;
991             return super.getOutput( section );
992         }
993 
994         @Override
995         public void editSection( final Section section ) throws IOException
996         {
997             if ( section == null )
998             {
999                 throw new NullPointerException( "section" );
1000             }
1001 
1002             if ( section.getName() != null )
1003             {
1004                 if ( LICENSE_SECTION_NAME.equals( section.getName() ) )
1005                 {
1006                     this.editLicenseSection( section );
1007                     this.licenseSectionPresent = true;
1008                 }
1009                 if ( ANNOTATIONS_SECTION_NAME.equals( section.getName() ) )
1010                 {
1011                     this.editAnnotationsSection( section );
1012                     this.annotationsSectionPresent = true;
1013                 }
1014                 if ( DOCUMENTATION_SECTION_NAME.equals( section.getName() ) )
1015                 {
1016                     this.editDocumentationSection( section );
1017                     this.documentationSectionPresent = true;
1018                 }
1019             }
1020         }
1021 
1022         /**
1023          * Edits the license section of the source code of the editor.
1024          *
1025          * @param s The section to edit.
1026          *
1027          * @throws NullPointerException if {@code s} is {@code null}.
1028          * @throws IOException if editing {@code s} fails.
1029          */
1030         public abstract void editLicenseSection( final Section s ) throws IOException;
1031 
1032         /**
1033          * Edits the annotations section of the source code of the editor.
1034          *
1035          * @param s The section to edit.
1036          *
1037          * @throws NullPointerException if {@code s} is {@code null}.
1038          * @throws IOException if editing {@code s} fails.
1039          */
1040         public abstract void editAnnotationsSection( final Section s ) throws IOException;
1041 
1042         /**
1043          * Edits the documentation section of the source code of the editor.
1044          *
1045          * @param s The section to edit.
1046          *
1047          * @throws NullPointerException if {@code s} is {@code null}.
1048          * @throws IOException if editing {@code s} fails.
1049          */
1050         public abstract void editDocumentationSection( final Section s ) throws IOException;
1051 
1052         /**
1053          * Gets a flag indicating that the source code of the editor contains a license section.
1054          *
1055          * @return {@code true} if the source code of the editor contains a license section; {@code false} if the
1056          * source code of the editor does not contain a license section.
1057          */
1058         public boolean isLicenseSectionPresent()
1059         {
1060             return this.licenseSectionPresent;
1061         }
1062 
1063         /**
1064          * Gets a flag indicating that the source code of the editor contains an annotations section.
1065          *
1066          * @return {@code true} if the source code of the editor contains an annotations section; {@code false} if the
1067          * source code of the editor does not contain an annotations section.
1068          */
1069         public boolean isAnnotationsSectionPresent()
1070         {
1071             return this.annotationsSectionPresent;
1072         }
1073 
1074         /**
1075          * Gets a flag indicating that the source code of the editor contains a documentation section.
1076          *
1077          * @return {@code true} if the source code of the editor contains a documentation section; {@code false} if the
1078          * source code of the editor does not contain a documentation section.
1079          */
1080         public boolean isDocumentationSectionPresent()
1081         {
1082             return this.documentationSectionPresent;
1083         }
1084 
1085     }
1086 
1087     /**
1088      * Extension to {@code JavaEditor} for editing specification source code.
1089      *
1090      * @author <a href="mailto:cs@jomc.org">Christian Schulte</a>
1091      * @version $Id: JavaSources.java 1237 2010-01-09 20:22:54Z schulte2005 $
1092      */
1093     public class JavaSpecificationEditor extends JavaEditor
1094     {
1095 
1096         /** The specification to edit. */
1097         private Specification specification;
1098 
1099         /**
1100          * Creates a new {@code JavaSpecificationEditor} instance for editing the source code of a given specification.
1101          *
1102          * @param specification The specification to edit.
1103          */
1104         public JavaSpecificationEditor( final Specification specification )
1105         {
1106             super();
1107             this.specification = specification;
1108         }
1109 
1110         /**
1111          * Creates a new {@code JavaSpecificationEditor} instance for editing the source code of a given specification
1112          * taking a {@code LineEditor} to chain.
1113          *
1114          * @param lineEditor The editor to chain.
1115          * @param specification The specification to edit.
1116          */
1117         public JavaSpecificationEditor( final LineEditor lineEditor, final Specification specification )
1118         {
1119             super( lineEditor );
1120             this.specification = specification;
1121         }
1122 
1123         /**
1124          * Edits the license section of the source code of the editor.
1125          *
1126          * @param s The section to edit.
1127          *
1128          * @throws NullPointerException if {@code s} is {@code null}.
1129          * @throws IOException if editing {@code s} fails.
1130          */
1131         public void editLicenseSection( final Section s ) throws IOException
1132         {
1133             if ( s == null )
1134             {
1135                 throw new NullPointerException( "s" );
1136             }
1137 
1138             try
1139             {
1140                 s.getHeadContent().setLength( 0 );
1141                 if ( this.specification != null )
1142                 {
1143                     s.getHeadContent().append( getLicenseSection( this.specification ) );
1144                 }
1145             }
1146             catch ( final ToolException e )
1147             {
1148                 throw (IOException) new IOException( e.getMessage() ).initCause( e );
1149             }
1150         }
1151 
1152         /**
1153          * Edits the annotations section of the source code of the editor.
1154          *
1155          * @param s The section to edit.
1156          *
1157          * @throws NullPointerException if {@code s} is {@code null}.
1158          * @throws IOException if editing {@code s} fails.
1159          */
1160         public void editAnnotationsSection( final Section s ) throws IOException
1161         {
1162             if ( s == null )
1163             {
1164                 throw new NullPointerException( "s" );
1165             }
1166 
1167             try
1168             {
1169                 s.getHeadContent().setLength( 0 );
1170                 if ( this.specification != null )
1171                 {
1172                     s.getHeadContent().append( getAnnotationsSection( this.specification ) );
1173                 }
1174             }
1175             catch ( final ToolException e )
1176             {
1177                 throw (IOException) new IOException( e.getMessage() ).initCause( e );
1178             }
1179         }
1180 
1181         /**
1182          * Edits the documentation section of the source code of the editor.
1183          *
1184          * @param s The section to edit.
1185          *
1186          * @throws NullPointerException if {@code s} is {@code null}.
1187          * @throws IOException if editing {@code s} fails.
1188          */
1189         public void editDocumentationSection( final Section s ) throws IOException
1190         {
1191             if ( s == null )
1192             {
1193                 throw new NullPointerException( "s" );
1194             }
1195 
1196             try
1197             {
1198                 s.getHeadContent().setLength( 0 );
1199                 if ( this.specification != null )
1200                 {
1201                     s.getHeadContent().append( getDocumentationSection( this.specification ) );
1202                 }
1203             }
1204             catch ( final ToolException e )
1205             {
1206                 throw (IOException) new IOException( e.getMessage() ).initCause( e );
1207             }
1208         }
1209 
1210     }
1211 
1212     /**
1213      * Extension to {@code JavaEditor} for editing implementation source code.
1214      *
1215      * @author <a href="mailto:cs@jomc.org">Christian Schulte</a>
1216      * @version $Id: JavaSources.java 1237 2010-01-09 20:22:54Z schulte2005 $
1217      */
1218     public class JavaImplementationEditor extends JavaEditor
1219     {
1220 
1221         /** The implementation to edit. */
1222         private Implementation implementation;
1223 
1224         /** Flag indicating that the source code of the editor contains a constructors section. */
1225         private boolean constructorsSectionPresent;
1226 
1227         /** Flag indicating that the source code of the editor contains a default constructor section. */
1228         private boolean defaultConstructorSectionPresent;
1229 
1230         /** Flag indicating that the source code of the editor contains a messages section. */
1231         private boolean messagesSectionPresent;
1232 
1233         /** Flag indicating that the source code of the editor contains a dependencies section. */
1234         private boolean dependenciesSectionPresent;
1235 
1236         /** Flag indicating that the source code of the editor contains a properties section. */
1237         private boolean propertiesSectionPresent;
1238 
1239         /**
1240          * Creates a new {@code JavaImplementationEditor} instance for editing the source code of a given implementation.
1241          *
1242          * @param implementation The implementation to edit.
1243          */
1244         public JavaImplementationEditor( final Implementation implementation )
1245         {
1246             super();
1247             this.implementation = implementation;
1248         }
1249 
1250         /**
1251          * Creates a new {@code JavaImplementationEditor} instance for editing the source code of a given implementation
1252          * taking a {@code LineEditor} to chain.
1253          *
1254          * @param lineEditor The editor to chain.
1255          * @param implementation The implementation to edit.
1256          */
1257         public JavaImplementationEditor( final LineEditor lineEditor, final Implementation implementation )
1258         {
1259             super( lineEditor );
1260             this.implementation = implementation;
1261         }
1262 
1263         @Override
1264         public String getOutput( final Section section ) throws IOException
1265         {
1266             if ( section == null )
1267             {
1268                 throw new NullPointerException( "section" );
1269             }
1270 
1271             this.constructorsSectionPresent = false;
1272             this.defaultConstructorSectionPresent = false;
1273             this.messagesSectionPresent = false;
1274             this.dependenciesSectionPresent = false;
1275             this.propertiesSectionPresent = false;
1276             return super.getOutput( section );
1277         }
1278 
1279         @Override
1280         public void editSection( final Section section ) throws IOException
1281         {
1282             if ( section == null )
1283             {
1284                 throw new NullPointerException( "section" );
1285             }
1286 
1287             super.editSection( section );
1288 
1289             if ( section.getName() != null )
1290             {
1291                 if ( CONSTRUCTORS_SECTION_NAME.equals( section.getName() ) )
1292                 {
1293                     this.editConstructorsSection( section );
1294                     this.constructorsSectionPresent = true;
1295                 }
1296                 else if ( DEFAULT_CONSTRUCTOR_SECTION_NAME.equals( section.getName() ) )
1297                 {
1298                     this.editDefaultConstructorSection( section );
1299                     this.defaultConstructorSectionPresent = true;
1300                 }
1301                 else if ( DEPENDENCIES_SECTION_NAME.equals( section.getName() ) )
1302                 {
1303                     this.editDependenciesSection( section );
1304                     this.dependenciesSectionPresent = true;
1305                 }
1306                 else if ( MESSAGES_SECTION_NAME.equals( section.getName() ) )
1307                 {
1308                     this.editMessagesSection( section );
1309                     this.messagesSectionPresent = true;
1310                 }
1311                 else if ( PROPERTIES_SECTION_NAME.equals( section.getName() ) )
1312                 {
1313                     this.editPropertiesSection( section );
1314                     this.propertiesSectionPresent = true;
1315                 }
1316             }
1317         }
1318 
1319         /**
1320          * Edits the license section of the source code of the editor.
1321          *
1322          * @param s The section to edit.
1323          *
1324          * @throws IOException if editing {@code s} fails.
1325          */
1326         public void editLicenseSection( final Section s ) throws IOException
1327         {
1328             if ( s == null )
1329             {
1330                 throw new NullPointerException( "s" );
1331             }
1332 
1333             try
1334             {
1335                 s.getHeadContent().setLength( 0 );
1336                 if ( this.implementation != null )
1337                 {
1338                     s.getHeadContent().append( getLicenseSection( this.implementation ) );
1339                 }
1340             }
1341             catch ( final ToolException e )
1342             {
1343                 throw (IOException) new IOException( e.getMessage() ).initCause( e );
1344             }
1345         }
1346 
1347         /**
1348          * Edits the annotations section of the source code of the editor.
1349          *
1350          * @param s The section to edit.
1351          *
1352          * @throws NullPointerException if {@code s} is {@code null}.
1353          * @throws IOException if editing {@code s} fails.
1354          */
1355         public void editAnnotationsSection( final Section s ) throws IOException
1356         {
1357             if ( s == null )
1358             {
1359                 throw new NullPointerException( "s" );
1360             }
1361 
1362             try
1363             {
1364                 s.getHeadContent().setLength( 0 );
1365                 if ( this.implementation != null )
1366                 {
1367                     s.getHeadContent().append( getAnnotationsSection( this.implementation ) );
1368                 }
1369             }
1370             catch ( final ToolException e )
1371             {
1372                 throw (IOException) new IOException( e.getMessage() ).initCause( e );
1373             }
1374         }
1375 
1376         /**
1377          * Edits the documentation section of the source code of the editor.
1378          *
1379          * @param s The section to edit.
1380          *
1381          * @throws NullPointerException if {@code s} is {@code null}.
1382          * @throws IOException if editing {@code s} fails.
1383          */
1384         public void editDocumentationSection( final Section s ) throws IOException
1385         {
1386             if ( s == null )
1387             {
1388                 throw new NullPointerException( "s" );
1389             }
1390 
1391             try
1392             {
1393                 s.getHeadContent().setLength( 0 );
1394                 if ( this.implementation != null )
1395                 {
1396                     s.getHeadContent().append( getDocumentationSection( this.implementation ) );
1397                 }
1398             }
1399             catch ( final ToolException e )
1400             {
1401                 throw (IOException) new IOException( e.getMessage() ).initCause( e );
1402             }
1403         }
1404 
1405         /**
1406          * Edits the constructors section of the source code of the editor.
1407          *
1408          * @param s The section to edit.
1409          *
1410          * @throws NullPointerException if {@code s} is {@code null}.
1411          * @throws IOException if editing {@code s} fails.
1412          */
1413         public void editConstructorsSection( final Section s ) throws IOException
1414         {
1415             if ( s == null )
1416             {
1417                 throw new NullPointerException( "s" );
1418             }
1419 
1420             try
1421             {
1422                 s.getHeadContent().setLength( 0 );
1423                 s.getTailContent().setLength( 0 );
1424 
1425                 if ( this.implementation != null )
1426                 {
1427                     s.getHeadContent().append( getConstructorsSectionHeadContent( this.implementation ) );
1428                     s.getTailContent().append( getConstructorsSectionTailContent( this.implementation ) );
1429                 }
1430 
1431                 for ( Section child : s.getSections() )
1432                 {
1433                     if ( child.getName() != null && DEFAULT_CONSTRUCTOR_SECTION_NAME.equals( child.getName() ) )
1434                     {
1435                         this.defaultConstructorSectionPresent = true;
1436                         break;
1437                     }
1438                 }
1439 
1440                 if ( !this.defaultConstructorSectionPresent )
1441                 {
1442                     final Section defaultCtor = new Section();
1443                     defaultCtor.setName( DEFAULT_CONSTRUCTOR_SECTION_NAME );
1444                     defaultCtor.setStartingLine( "        // SECTION-START[" + DEFAULT_CONSTRUCTOR_SECTION_NAME + "]" );
1445                     defaultCtor.setEndingLine( "        // SECTION-END" );
1446                     defaultCtor.getHeadContent().append( "        super();" ).append( this.getLineSeparator() );
1447                     s.getSections().add( defaultCtor );
1448                     this.defaultConstructorSectionPresent = true;
1449                 }
1450             }
1451             catch ( final ToolException e )
1452             {
1453                 throw (IOException) new IOException( e.getMessage() ).initCause( e );
1454             }
1455         }
1456 
1457         /**
1458          * Edits the default constructor section of the source code of the editor.
1459          *
1460          * @param s The section to edit.
1461          *
1462          * @throws NullPointerException if {@code s} is {@code null}.
1463          * @throws IOException if editing {@code s} fails.
1464          */
1465         public void editDefaultConstructorSection( final Section s ) throws IOException
1466         {
1467             if ( s == null )
1468             {
1469                 throw new NullPointerException( "s" );
1470             }
1471 
1472             if ( s.getHeadContent().toString().trim().length() == 0 )
1473             {
1474                 s.getHeadContent().setLength( 0 );
1475 
1476                 if ( this.implementation != null )
1477                 {
1478                     s.getHeadContent().append( "        super();" ).append( this.getLineSeparator() );
1479                 }
1480             }
1481         }
1482 
1483         /**
1484          * Edits the dependencies section of the source code of the editor.
1485          *
1486          * @param s The section to edit.
1487          *
1488          * @throws NullPointerException if {@code s} is {@code null}.
1489          * @throws IOException if editing {@code s} fails.
1490          */
1491         public void editDependenciesSection( final Section s ) throws IOException
1492         {
1493             if ( s == null )
1494             {
1495                 throw new NullPointerException( "s" );
1496             }
1497 
1498             try
1499             {
1500                 s.getHeadContent().setLength( 0 );
1501                 if ( this.implementation != null )
1502                 {
1503                     s.getHeadContent().append( getDependenciesSection( this.implementation ) );
1504                 }
1505             }
1506             catch ( final ToolException e )
1507             {
1508                 throw (IOException) new IOException( e.getMessage() ).initCause( e );
1509             }
1510         }
1511 
1512         /**
1513          * Edits the messages section of the source code of the editor.
1514          *
1515          * @param s The section to edit.
1516          *
1517          * @throws NullPointerException if {@code s} is {@code null}.
1518          * @throws IOException if editing {@code s} fails.
1519          */
1520         public void editMessagesSection( final Section s ) throws IOException
1521         {
1522             if ( s == null )
1523             {
1524                 throw new NullPointerException( "s" );
1525             }
1526 
1527             try
1528             {
1529                 s.getHeadContent().setLength( 0 );
1530                 if ( this.implementation != null )
1531                 {
1532                     s.getHeadContent().append( getMessagesSection( this.implementation ) );
1533                 }
1534             }
1535             catch ( final ToolException e )
1536             {
1537                 throw (IOException) new IOException( e.getMessage() ).initCause( e );
1538             }
1539         }
1540 
1541         /**
1542          * Edits the properties section of the source code of the editor.
1543          *
1544          * @param s The section to edit.
1545          *
1546          * @throws NullPointerException if {@code s} is {@code null}.
1547          * @throws IOException if editing {@code s} fails.
1548          */
1549         public void editPropertiesSection( final Section s ) throws IOException
1550         {
1551             if ( s == null )
1552             {
1553                 throw new NullPointerException( "s" );
1554             }
1555 
1556             try
1557             {
1558                 s.getHeadContent().setLength( 0 );
1559                 if ( this.implementation != null )
1560                 {
1561                     s.getHeadContent().append( getPropertiesSection( this.implementation ) );
1562                 }
1563             }
1564             catch ( final ToolException e )
1565             {
1566                 throw (IOException) new IOException( e.getMessage() ).initCause( e );
1567             }
1568         }
1569 
1570         /**
1571          * Gets a flag indicating that the source code of the editor contains a constructors section.
1572          *
1573          * @return {@code true} if the source code of the editor contains a constructors section; {@code false} if the
1574          * source code of the editor does not contain a constructors section.
1575          */
1576         public boolean isConstructorsSectionPresent()
1577         {
1578             return this.constructorsSectionPresent;
1579         }
1580 
1581         /**
1582          * Gets a flag indicating that the source code of the editor contains a default constructor section.
1583          *
1584          * @return {@code true} if the source code of the editor contains a default constructor section; {@code false}
1585          * if the source code of the editor does not contain a default constructor section.
1586          */
1587         public boolean isDefaultConstructorSectionPresent()
1588         {
1589             return this.defaultConstructorSectionPresent;
1590         }
1591 
1592         /**
1593          * Gets a flag indicating that the source code of the editor contains a messages section.
1594          *
1595          * @return {@code true} if the source code of the editor contains a messages section; {@code false}
1596          * if the source code of the editor does not contain a messages section.
1597          */
1598         public boolean isMessagesSectionPresent()
1599         {
1600             return this.messagesSectionPresent;
1601         }
1602 
1603         /**
1604          * Gets a flag indicating that the source code of the editor contains a dependencies section.
1605          *
1606          * @return {@code true} if the source code of the editor contains a dependencies section; {@code false}
1607          * if the source code of the editor does not contain a dependencies section.
1608          */
1609         public boolean isDependenciesSectionPresent()
1610         {
1611             return this.dependenciesSectionPresent;
1612         }
1613 
1614         /**
1615          * Gets a flag indicating that the source code of the editor contains a properties section.
1616          *
1617          * @return {@code true} if the source code of the editor contains a properties section; {@code false}
1618          * if the source code of the editor does not contain a properties section.
1619          */
1620         public boolean isPropertiesSectionPresent()
1621         {
1622             return this.propertiesSectionPresent;
1623         }
1624 
1625     }
1626 
1627 }