001    /*
002     *   Copyright (c) 2009 The JOMC Project
003     *   Copyright (c) 2005 Christian Schulte <cs@jomc.org>
004     *   All rights reserved.
005     *
006     *   Redistribution and use in source and binary forms, with or without
007     *   modification, are permitted provided that the following conditions
008     *   are met:
009     *
010     *     o Redistributions of source code must retain the above copyright
011     *       notice, this list of conditions and the following disclaimer.
012     *
013     *     o Redistributions in binary form must reproduce the above copyright
014     *       notice, this list of conditions and the following disclaimer in
015     *       the documentation and/or other materials provided with the
016     *       distribution.
017     *
018     *   THIS SOFTWARE IS PROVIDED BY THE JOMC PROJECT AND CONTRIBUTORS "AS IS"
019     *   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
020     *   THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
021     *   PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE JOMC PROJECT OR
022     *   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023     *   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024     *   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
025     *   OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
026     *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
027     *   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
028     *   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029     *
030     *   $Id: JavaSources.java 1237 2010-01-09 20:22:54Z schulte2005 $
031     *
032     */
033    package org.jomc.tools;
034    
035    import java.io.File;
036    import java.io.IOException;
037    import java.io.StringWriter;
038    import java.text.MessageFormat;
039    import java.util.ResourceBundle;
040    import java.util.logging.Level;
041    import org.apache.commons.io.FileUtils;
042    import org.apache.velocity.Template;
043    import org.apache.velocity.VelocityContext;
044    import org.jomc.model.Dependencies;
045    import org.jomc.model.Implementation;
046    import org.jomc.model.Messages;
047    import org.jomc.model.Module;
048    import org.jomc.model.Properties;
049    import org.jomc.model.Specification;
050    import org.jomc.model.Specifications;
051    import org.jomc.util.LineEditor;
052    import org.jomc.util.Section;
053    import org.jomc.util.SectionEditor;
054    import org.jomc.util.TrailingWhitespaceEditor;
055    
056    /**
057     * Manages Java source code.
058     *
059     * <p><b>Use cases</b><br/><ul>
060     * <li>{@link #manageSources(java.io.File) }</li>
061     * <li>{@link #manageSources(org.jomc.model.Module, java.io.File) }</li>
062     * <li>{@link #manageSources(org.jomc.model.Specification, java.io.File) }</li>
063     * <li>{@link #manageSources(org.jomc.model.Implementation, java.io.File) }</li>
064     * </ul></p>
065     *
066     * @author <a href="mailto:cs@jomc.org">Christian Schulte</a>
067     * @version $Id: JavaSources.java 1237 2010-01-09 20:22:54Z schulte2005 $
068     *
069     * @see #getModules()
070     */
071    public class JavaSources extends JomcTool
072    {
073    
074        /** Constant for the name of the constructors source code section. */
075        private static final String CONSTRUCTORS_SECTION_NAME = "Constructors";
076    
077        /** Constant for the name of the default constructor source code section. */
078        private static final String DEFAULT_CONSTRUCTOR_SECTION_NAME = "Default Constructor";
079    
080        /** Constant for the name of the dependencies source code section. */
081        private static final String DEPENDENCIES_SECTION_NAME = "Dependencies";
082    
083        /** Constant for the name of the properties source code section. */
084        private static final String PROPERTIES_SECTION_NAME = "Properties";
085    
086        /** Constant for the name of the messages source code section. */
087        private static final String MESSAGES_SECTION_NAME = "Messages";
088    
089        /** Constant for the name of the license source code section. */
090        private static final String LICENSE_SECTION_NAME = "License Header";
091    
092        /** Constant for the name of the documentation source code section. */
093        private static final String DOCUMENTATION_SECTION_NAME = "Documentation";
094    
095        /** Constant for the name of the implementation annotations source code section. */
096        private static final String ANNOTATIONS_SECTION_NAME = "Annotations";
097    
098        /** Name of the generator. */
099        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    }