EMMA Coverage Report (generated Wed May 23 02:58:44 CEST 2012)
[all classes][org.jomc.tools]

COVERAGE SUMMARY FOR SOURCE FILE [SourceFileProcessor.java]

nameclass, %method, %block, %line, %
SourceFileProcessor.java100% (2/2)74%  (34/46)58%  (1387/2382)70%  (281.9/404)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class SourceFileProcessor$SourceFileEditor100% (1/1)58%  (15/26)53%  (888/1686)64%  (185.2/290)
SourceFileProcessor$SourceFileEditor (SourceFileProcessor): void 0%   (0/1)0%   (0/8)0%   (0/2)
SourceFileProcessor$SourceFileEditor (SourceFileProcessor, Implementation): void 0%   (0/1)0%   (0/7)0%   (0/2)
SourceFileProcessor$SourceFileEditor (SourceFileProcessor, Implementation, Li... 0%   (0/1)0%   (0/7)0%   (0/2)
SourceFileProcessor$SourceFileEditor (SourceFileProcessor, Implementation, Li... 0%   (0/1)0%   (0/43)0%   (0/8)
SourceFileProcessor$SourceFileEditor (SourceFileProcessor, Implementation, St... 0%   (0/1)0%   (0/7)0%   (0/2)
SourceFileProcessor$SourceFileEditor (SourceFileProcessor, LineEditor): void 0%   (0/1)0%   (0/6)0%   (0/2)
SourceFileProcessor$SourceFileEditor (SourceFileProcessor, Specification): void 0%   (0/1)0%   (0/7)0%   (0/2)
SourceFileProcessor$SourceFileEditor (SourceFileProcessor, Specification, Lin... 0%   (0/1)0%   (0/7)0%   (0/2)
SourceFileProcessor$SourceFileEditor (SourceFileProcessor, Specification, Lin... 0%   (0/1)0%   (0/43)0%   (0/8)
SourceFileProcessor$SourceFileEditor (SourceFileProcessor, Specification, Str... 0%   (0/1)0%   (0/7)0%   (0/2)
SourceFileProcessor$SourceFileEditor (SourceFileProcessor, String): void 0%   (0/1)0%   (0/7)0%   (0/2)
getVelocityContext (): VelocityContext 100% (1/1)20%  (6/30)25%  (2/8)
writeSourceFile (File, String): void 100% (1/1)24%  (74/311)50%  (21.8/44)
getSourceFileType (): SourceFileType 100% (1/1)25%  (6/24)33%  (2/6)
readSourceFile (File): String 100% (1/1)31%  (106/338)53%  (23.8/45)
edit (Implementation, SourceFileType, File): void 100% (1/1)62%  (48/78)79%  (13.4/17)
edit (Specification, SourceFileType, File): void 100% (1/1)62%  (48/78)79%  (13.4/17)
<static initializer> 100% (1/1)75%  (6/8)75%  (0.8/1)
createSection (String, String, SourceSectionType): Section 100% (1/1)80%  (60/75)77%  (10/13)
editSourceFile (File): void 100% (1/1)80%  (185/230)89%  (35.5/40)
editSection (Section): void 100% (1/1)93%  (216/232)93%  (35.5/38)
SourceFileProcessor$SourceFileEditor (SourceFileProcessor, LineEditor, String... 100% (1/1)100% (8/8)100% (3/3)
createSections (SourceFileType, SourceSectionsType, Section): void 100% (1/1)100% (82/82)100% (12/12)
getAddedSections (): List 100% (1/1)100% (11/11)100% (3/3)
getOutput (Section): String 100% (1/1)100% (21/21)100% (6/6)
getUnknownSections (): List 100% (1/1)100% (11/11)100% (3/3)
     
class SourceFileProcessor100% (1/1)95%  (19/20)72%  (499/696)85%  (96.7/114)
setSourceFileEditor (SourceFileProcessor$SourceFileEditor): void 0%   (0/1)0%   (0/4)0%   (0/2)
getSourceFilesType (Implementation): SourceFilesType 100% (1/1)50%  (40/80)73%  (8.7/12)
getSourceFileEditor (Implementation): SourceFileProcessor$SourceFileEditor 100% (1/1)55%  (18/33)84%  (3.3/4)
getSourceFileEditor (Specification): SourceFileProcessor$SourceFileEditor 100% (1/1)55%  (18/33)84%  (3.3/4)
getSourceFilesType (Specification): SourceFilesType 100% (1/1)55%  (30/55)73%  (7.3/10)
getMessage (Throwable): String 100% (1/1)64%  (9/14)64%  (0.6/1)
getSourceFileType (Implementation): SourceFileType 100% (1/1)67%  (30/45)91%  (6.3/7)
getSourceFileType (Specification): SourceFileType 100% (1/1)67%  (30/45)91%  (6.3/7)
getMessage (String, Object []): String 100% (1/1)72%  (13/18)67%  (2/3)
<static initializer> 100% (1/1)75%  (6/8)75%  (0.8/1)
SourceFileProcessor (SourceFileProcessor): void 100% (1/1)78%  (14/18)94%  (3.8/4)
manageSourceFiles (Implementation, File): void 100% (1/1)79%  (58/73)94%  (11.3/12)
manageSourceFiles (Specification, File): void 100% (1/1)81%  (94/116)83%  (18.3/22)
manageSourceFiles (Module, File): void 100% (1/1)83%  (71/86)94%  (11.3/12)
SourceFileProcessor (): void 100% (1/1)100% (3/3)100% (2/2)
access$000 (String, Object []): String 100% (1/1)100% (4/4)100% (1/1)
access$100 (Throwable): String 100% (1/1)100% (3/3)100% (1/1)
getSourceFileEditor (): SourceFileProcessor$SourceFileEditor 100% (1/1)100% (19/19)100% (3/3)
getSourceFilesType (): SourceFilesType 100% (1/1)100% (11/11)100% (3/3)
manageSourceFiles (File): void 100% (1/1)100% (28/28)100% (5/5)

1/*
2 *   Copyright (C) Christian Schulte, 2005-206
3 *   All rights reserved.
4 *
5 *   Redistribution and use in source and binary forms, with or without
6 *   modification, are permitted provided that the following conditions
7 *   are met:
8 *
9 *     o Redistributions of source code must retain the above copyright
10 *       notice, this list of conditions and the following disclaimer.
11 *
12 *     o Redistributions in binary form must reproduce the above copyright
13 *       notice, this list of conditions and the following disclaimer in
14 *       the documentation and/or other materials provided with the
15 *       distribution.
16 *
17 *   THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
18 *   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
19 *   AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20 *   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 *   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 *   NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 *   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 *   $JOMC: SourceFileProcessor.java 4352 2012-03-01 11:19:48Z schulte2005 $
29 *
30 */
31package org.jomc.tools;
32 
33import java.io.File;
34import java.io.IOException;
35import java.io.RandomAccessFile;
36import java.io.StringWriter;
37import java.nio.ByteBuffer;
38import java.nio.channels.FileChannel;
39import java.nio.channels.FileLock;
40import java.text.MessageFormat;
41import java.util.LinkedList;
42import java.util.List;
43import java.util.ResourceBundle;
44import java.util.logging.Level;
45import org.apache.commons.lang.StringUtils;
46import org.apache.velocity.Template;
47import org.apache.velocity.VelocityContext;
48import org.apache.velocity.exception.VelocityException;
49import org.jomc.model.Implementation;
50import org.jomc.model.Implementations;
51import org.jomc.model.Instance;
52import org.jomc.model.Module;
53import org.jomc.model.Specification;
54import org.jomc.tools.model.SourceFileType;
55import org.jomc.tools.model.SourceFilesType;
56import org.jomc.tools.model.SourceSectionType;
57import org.jomc.tools.model.SourceSectionsType;
58import org.jomc.util.LineEditor;
59import org.jomc.util.Section;
60import org.jomc.util.SectionEditor;
61import org.jomc.util.TrailingWhitespaceEditor;
62 
63/**
64 * Processes source code files.
65 *
66 * <p><b>Use Cases:</b><br/><ul>
67 * <li>{@link #manageSourceFiles(File) }</li>
68 * <li>{@link #manageSourceFiles(Module, File) }</li>
69 * <li>{@link #manageSourceFiles(Specification, File) }</li>
70 * <li>{@link #manageSourceFiles(Implementation, File) }</li>
71 * </ul></p>
72 *
73 * @author <a href="mailto:schulte2005@users.sourceforge.net">Christian Schulte</a>
74 * @version $JOMC: SourceFileProcessor.java 4352 2012-03-01 11:19:48Z schulte2005 $
75 */
76public class SourceFileProcessor extends JomcTool
77{
78 
79    /** The source file editor of the instance. */
80    private SourceFileProcessor.SourceFileEditor sourceFileEditor;
81 
82    /** Source files model. */
83    @Deprecated
84    private SourceFilesType sourceFilesType;
85 
86    /** Creates a new {@code SourceFileProcessor} instance. */
87    public SourceFileProcessor()
88    {
89        super();
90    }
91 
92    /**
93     * Creates a new {@code SourceFileProcessor} instance taking a {@code SourceFileProcessor} instance to initialize
94     * the instance with.
95     *
96     * @param tool The instance to initialize the new instance with,
97     *
98     * @throws NullPointerException if {@code tool} is {@code null}.
99     * @throws IOException if copying {@code tool} fails.
100     */
101    public SourceFileProcessor( final SourceFileProcessor tool ) throws IOException
102    {
103        super( tool );
104        this.sourceFilesType = tool.sourceFilesType != null ? tool.sourceFilesType.clone() : null;
105        this.sourceFileEditor = tool.sourceFileEditor;
106    }
107 
108    /**
109     * Gets the source files model of the instance.
110     * <p>This accessor method returns a reference to the live object, not a snapshot. Therefore any modification you
111     * make to the returned object will be present inside the object. This is why there is no {@code set} method.</p>
112     *
113     * @return The source files model of the instance.
114     *
115     * @see #getSourceFileType(org.jomc.model.Specification)
116     * @see #getSourceFileType(org.jomc.model.Implementation)
117     *
118     * @deprecated As of JOMC 1.2, please add source file models to {@code Specification}s and {@code Implementation}s
119     * directly. This method will be removed in version 2.0.
120     */
121    @Deprecated
122    public SourceFilesType getSourceFilesType()
123    {
124        if ( this.sourceFilesType == null )
125        {
126            this.sourceFilesType = new SourceFilesType();
127        }
128 
129        return this.sourceFilesType;
130    }
131 
132    /**
133     * Gets the model of a specification source file of the modules of the instance.
134     *
135     * @param specification The specification to get a source file model for.
136     *
137     * @return The source file model for {@code specification}. As of JOMC 1.2, this method returns {@code null} if no
138     * source file model is found.
139     *
140     * @throws NullPointerException if {@code specification} is {@code null}.
141     *
142     * @deprecated As of JOMC 1.2, please use method {@link #getSourceFilesType(org.jomc.model.Specification)}. This
143     * method will be removed in version 2.0.
144     */
145    @Deprecated
146    public SourceFileType getSourceFileType( final Specification specification )
147    {
148        if ( specification == null )
149        {
150            throw new NullPointerException( "specification" );
151        }
152 
153        assert this.getModules().getSpecification( specification.getIdentifier() ) != null :
154            "Specification '" + specification.getIdentifier() + "' not found.";
155 
156        SourceFileType sourceFileType = this.getSourceFilesType().getSourceFile( specification.getIdentifier() );
157 
158        if ( sourceFileType == null )
159        {
160            sourceFileType = specification.getAnyObject( SourceFileType.class );
161        }
162 
163        return sourceFileType;
164    }
165 
166    /**
167     * Gets the source files model of a specification of the modules of the instance.
168     *
169     * @param specification The specification to get a source files model for.
170     *
171     * @return The source files model for {@code specification} or {@code null}, if no source files model is found.
172     *
173     * @throws NullPointerException if {@code specification} is {@code null}.
174     *
175     * @since 1.2
176     */
177    public SourceFilesType getSourceFilesType( final Specification specification )
178    {
179        if ( specification == null )
180        {
181            throw new NullPointerException( "specification" );
182        }
183 
184        assert this.getModules().getSpecification( specification.getIdentifier() ) != null :
185            "Specification '" + specification.getIdentifier() + "' not found.";
186 
187        SourceFilesType model = null;
188        final SourceFileType sourceFileType = this.getSourceFileType( specification );
189 
190        if ( sourceFileType != null )
191        {
192            model = new SourceFilesType();
193            model.getSourceFile().add( sourceFileType );
194        }
195        else
196        {
197            model = specification.getAnyObject( SourceFilesType.class );
198        }
199 
200        return model;
201    }
202 
203    /**
204     * Gets the model of an implementation source file of the modules of the instance.
205     *
206     * @param implementation The implementation to get a source file model for.
207     *
208     * @return The source file model for {@code implementation}. As of JOMC 1.2, this method returns {@code null} if no
209     * source file model is found.
210     *
211     * @throws NullPointerException if {@code implementation} is {@code null}.
212     *
213     * @deprecated As of JOMC 1.2, please use method {@link #getSourceFilesType(org.jomc.model.Implementation)}. This
214     * method will be removed in version 2.0.
215     */
216    @Deprecated
217    public SourceFileType getSourceFileType( final Implementation implementation )
218    {
219        if ( implementation == null )
220        {
221            throw new NullPointerException( "implementation" );
222        }
223 
224        assert this.getModules().getImplementation( implementation.getIdentifier() ) != null :
225            "Implementation '" + implementation.getIdentifier() + "' not found.";
226 
227        SourceFileType sourceFileType = this.getSourceFilesType().getSourceFile( implementation.getIdentifier() );
228 
229        if ( sourceFileType == null )
230        {
231            sourceFileType = implementation.getAnyObject( SourceFileType.class );
232        }
233 
234        return sourceFileType;
235    }
236 
237    /**
238     * Gets the source files model of an implementation of the modules of the instance.
239     *
240     * @param implementation The implementation to get a source files model for.
241     *
242     * @return The source files model for {@code implementation} or {@code null}, if no source files model is found.
243     *
244     * @throws NullPointerException if {@code implementation} is {@code null}.
245     *
246     * @since 1.2
247     */
248    public SourceFilesType getSourceFilesType( final Implementation implementation )
249    {
250        if ( implementation == null )
251        {
252            throw new NullPointerException( "implementation" );
253        }
254 
255        assert this.getModules().getImplementation( implementation.getIdentifier() ) != null :
256            "Implementation '" + implementation.getIdentifier() + "' not found.";
257 
258        SourceFilesType model = null;
259        final SourceFileType sourceFileType = this.getSourceFileType( implementation );
260 
261        if ( sourceFileType != null )
262        {
263            model = new SourceFilesType();
264            model.getSourceFile().add( sourceFileType );
265        }
266        else
267        {
268            final Instance instance = this.getModules().getInstance( implementation.getIdentifier() );
269            assert instance != null : "Instance '" + implementation.getIdentifier() + "' not found.";
270            model = instance.getAnyObject( SourceFilesType.class );
271        }
272 
273        return model;
274    }
275 
276    /**
277     * Gets the source file editor of the instance.
278     *
279     * @return The source file editor of the instance.
280     *
281     * @since 1.2
282     *
283     * @see #setSourceFileEditor(org.jomc.tools.SourceFileProcessor.SourceFileEditor)
284     */
285    public final SourceFileProcessor.SourceFileEditor getSourceFileEditor()
286    {
287        if ( this.sourceFileEditor == null )
288        {
289            this.sourceFileEditor =
290                new SourceFileProcessor.SourceFileEditor( new TrailingWhitespaceEditor( this.getLineSeparator() ),
291                                                          this.getLineSeparator() );
292 
293        }
294 
295        return this.sourceFileEditor;
296    }
297 
298    /**
299     * Sets the source file editor of the instance.
300     *
301     * @param value The new source file editor of the instance or {@code null}.
302     *
303     * @since 1.2
304     *
305     * @see #getSourceFileEditor()
306     */
307    public final void setSourceFileEditor( final SourceFileProcessor.SourceFileEditor value )
308    {
309        this.sourceFileEditor = value;
310    }
311 
312    /**
313     * Gets a new editor for editing the source file of a given specification of the modules of the instance.
314     *
315     * @param specification The specification whose source file to edit.
316     *
317     * @return A new editor for editing the source file of {@code specification}.
318     *
319     * @throws NullPointerException if {@code specification} is {@code null}.
320     *
321     * @deprecated As of JOMC 1.2, please use method {@link #getSourceFileEditor()}. This method will be removed in
322     * version 2.0.
323     *
324     * @see SourceFileEditor#edit(org.jomc.model.Specification, org.jomc.tools.model.SourceFileType, java.io.File)
325     */
326    @Deprecated
327    public SourceFileProcessor.SourceFileEditor getSourceFileEditor( final Specification specification )
328    {
329        if ( specification == null )
330        {
331            throw new NullPointerException( "specification" );
332        }
333 
334        assert this.getModules().getSpecification( specification.getIdentifier() ) != null :
335            "Specification '" + specification.getIdentifier() + "' not found.";
336 
337        return this.getSourceFileEditor();
338    }
339 
340    /**
341     * Gets a new editor for editing the source file of a given implementation of the modules of the instance.
342     *
343     * @param implementation The implementation whose source file to edit.
344     *
345     * @return A new editor for editing the source file of {@code implementation}.
346     *
347     * @throws NullPointerException if {@code implementation} is {@code null}.
348     *
349     * @deprecated As of JOMC 1.2, please use method {@link #getSourceFileEditor()}. This method will be removed in
350     * version 2.0.
351     *
352     * @see SourceFileEditor#edit(org.jomc.model.Implementation, org.jomc.tools.model.SourceFileType, java.io.File)
353     */
354    @Deprecated
355    public SourceFileProcessor.SourceFileEditor getSourceFileEditor( final Implementation implementation )
356    {
357        if ( implementation == null )
358        {
359            throw new NullPointerException( "implementation" );
360        }
361 
362        assert this.getModules().getImplementation( implementation.getIdentifier() ) != null :
363            "Implementation '" + implementation.getIdentifier() + "' not found.";
364 
365        return this.getSourceFileEditor();
366    }
367 
368    /**
369     * Manages the source files of the modules of the instance.
370     *
371     * @param sourcesDirectory The directory holding the source files to manage.
372     *
373     * @throws NullPointerException if {@code sourcesDirectory} is {@code null}.
374     * @throws IOException if managing source files fails.
375     *
376     * @see #manageSourceFiles(org.jomc.model.Module, java.io.File)
377     */
378    public void manageSourceFiles( final File sourcesDirectory ) throws IOException
379    {
380        if ( sourcesDirectory == null )
381        {
382            throw new NullPointerException( "sourcesDirectory" );
383        }
384 
385        for ( int i = this.getModules().getModule().size() - 1; i >= 0; i-- )
386        {
387            this.manageSourceFiles( this.getModules().getModule().get( i ), sourcesDirectory );
388        }
389    }
390 
391    /**
392     * Manages the source files of a given module of the modules of the instance.
393     *
394     * @param module The module to process.
395     * @param sourcesDirectory The directory holding the source files to manage.
396     *
397     * @throws NullPointerException if {@code module} or {@code sourcesDirectory} is {@code null}.
398     * @throws IOException if managing source files fails.
399     *
400     * @see #manageSourceFiles(org.jomc.model.Specification, java.io.File)
401     * @see #manageSourceFiles(org.jomc.model.Implementation, java.io.File)
402     */
403    public void manageSourceFiles( final Module module, final File sourcesDirectory ) throws IOException
404    {
405        if ( module == null )
406        {
407            throw new NullPointerException( "module" );
408        }
409        if ( sourcesDirectory == null )
410        {
411            throw new NullPointerException( "sourcesDirectory" );
412        }
413 
414        assert this.getModules().getModule( module.getName() ) != null : "Module '" + module.getName() + "' not found.";
415 
416        if ( module.getSpecifications() != null )
417        {
418            for ( int i = 0, s0 = module.getSpecifications().getSpecification().size(); i < s0; i++ )
419            {
420                this.manageSourceFiles( module.getSpecifications().getSpecification().get( i ), sourcesDirectory );
421            }
422        }
423        if ( module.getImplementations() != null )
424        {
425            for ( int i = 0, s0 = module.getImplementations().getImplementation().size(); i < s0; i++ )
426            {
427                this.manageSourceFiles( module.getImplementations().getImplementation().get( i ), sourcesDirectory );
428            }
429        }
430    }
431 
432    /**
433     * Manages the source files of a given specification of the modules of the instance.
434     *
435     * @param specification The specification to process.
436     * @param sourcesDirectory The directory holding the source files to manage.
437     *
438     * @throws NullPointerException if {@code specification} or {@code sourcesDirectory} is {@code null}.
439     * @throws IOException if managing source files fails.
440     *
441     * @see #getSourceFileEditor()
442     * @see #getSourceFilesType(org.jomc.model.Specification)
443     */
444    public void manageSourceFiles( final Specification specification, final File sourcesDirectory ) throws IOException
445    {
446        if ( specification == null )
447        {
448            throw new NullPointerException( "specification" );
449        }
450        if ( sourcesDirectory == null )
451        {
452            throw new NullPointerException( "sourcesDirectory" );
453        }
454 
455        assert this.getModules().getSpecification( specification.getIdentifier() ) != null :
456            "Specification '" + specification.getIdentifier() + "' not found.";
457 
458        if ( specification.isClassDeclaration() )
459        {
460            boolean manage = true;
461            final Implementations implementations = this.getModules().getImplementations();
462 
463            if ( implementations != null )
464            {
465                for ( int i = 0, s0 = implementations.getImplementation().size(); i < s0; i++ )
466                {
467                    final Implementation impl = implementations.getImplementation().get( i );
468 
469                    if ( impl.isClassDeclaration() && specification.getClazz().equals( impl.getClazz() ) )
470                    {
471                        this.manageSourceFiles( impl, sourcesDirectory );
472                        manage = false;
473                        break;
474                    }
475                }
476            }
477 
478            if ( manage )
479            {
480                final SourceFileProcessor.SourceFileEditor editor = this.getSourceFileEditor( specification );
481                final SourceFilesType model = this.getSourceFilesType( specification );
482 
483                if ( editor != null && model != null )
484                {
485                    for ( int i = 0, s0 = model.getSourceFile().size(); i < s0; i++ )
486                    {
487                        editor.edit( specification, model.getSourceFile().get( i ), sourcesDirectory );
488                    }
489                }
490            }
491        }
492    }
493 
494    /**
495     * Manages the source files of a given implementation of the modules of the instance.
496     *
497     * @param implementation The implementation to process.
498     * @param sourcesDirectory The directory holding the source files to manage.
499     *
500     * @throws NullPointerException if {@code implementation} or {@code sourcesDirectory} is {@code null}.
501     * @throws IOException if managing source files fails.
502     *
503     * @see #getSourceFileEditor()
504     * @see #getSourceFilesType(org.jomc.model.Implementation)
505     */
506    public void manageSourceFiles( final Implementation implementation, final File sourcesDirectory )
507        throws IOException
508    {
509        if ( implementation == null )
510        {
511            throw new NullPointerException( "implementation" );
512        }
513        if ( sourcesDirectory == null )
514        {
515            throw new NullPointerException( "sourcesDirectory" );
516        }
517 
518        assert this.getModules().getImplementation( implementation.getIdentifier() ) != null :
519            "Implementation '" + implementation.getIdentifier() + "' not found.";
520 
521        if ( implementation.isClassDeclaration() )
522        {
523            final SourceFileProcessor.SourceFileEditor editor = this.getSourceFileEditor( implementation );
524            final SourceFilesType model = this.getSourceFilesType( implementation );
525 
526            if ( editor != null && model != null )
527            {
528                for ( int i = 0, s0 = model.getSourceFile().size(); i < s0; i++ )
529                {
530                    editor.edit( implementation, model.getSourceFile().get( i ), sourcesDirectory );
531                }
532            }
533        }
534    }
535 
536    private static String getMessage( final String key, final Object... arguments )
537    {
538        if ( key == null )
539        {
540            throw new NullPointerException( "key" );
541        }
542 
543        return MessageFormat.format( ResourceBundle.getBundle(
544            SourceFileProcessor.class.getName().replace( '.', '/' ) ).getString( key ), arguments );
545 
546    }
547 
548    private static String getMessage( final Throwable t )
549    {
550        return t != null ? t.getMessage() != null ? t.getMessage() : getMessage( t.getCause() ) : null;
551    }
552 
553    /**
554     * Extension to {@code SectionEditor} adding support for editing source code files.
555     *
556     * @author <a href="mailto:schulte2005@users.sourceforge.net">Christian Schulte</a>
557     * @version $JOMC: SourceFileProcessor.java 4352 2012-03-01 11:19:48Z schulte2005 $
558     *
559     * @see #edit(org.jomc.model.Specification, org.jomc.tools.model.SourceFileType, java.io.File)
560     * @see #edit(org.jomc.model.Implementation, org.jomc.tools.model.SourceFileType, java.io.File)
561     */
562    public class SourceFileEditor extends SectionEditor
563    {
564 
565        /** {@code Specification} of the instance or {@code null}. */
566        private Specification specification;
567 
568        /** {@code Implementation} of the instance or {@code null}. */
569        private Implementation implementation;
570 
571        /** The source code file to edit. */
572        private SourceFileType sourceFileType;
573 
574        /** The {@code VelocityContext} of the instance. */
575        private VelocityContext velocityContext;
576 
577        /** List of sections added to the input. */
578        @Deprecated
579        private List<Section> addedSections;
580 
581        /** List of sections without corresponding model entry. */
582        @Deprecated
583        private List<Section> unknownSections;
584 
585        /**
586         * Creates a new {@code SourceFileEditor} instance.
587         *
588         * @since 1.2
589         */
590        public SourceFileEditor()
591        {
592            this( (LineEditor) null, (String) null );
593        }
594 
595        /**
596         * Creates a new {@code SourceFileEditor} instance taking a string to use for separating lines.
597         *
598         * @param lineSeparator String to use for separating lines.
599         *
600         * @since 1.2
601         */
602        public SourceFileEditor( final String lineSeparator )
603        {
604            this( (LineEditor) null, lineSeparator );
605        }
606 
607        /**
608         * Creates a new {@code SourceFileEditor} instance taking an editor to chain.
609         *
610         * @param editor The editor to chain.
611         *
612         * @since 1.2
613         */
614        public SourceFileEditor( final LineEditor editor )
615        {
616            this( editor, null );
617        }
618 
619        /**
620         * Creates a new {@code SourceFileEditor} instance taking an editor to chain and a string to use for separating
621         * lines.
622         *
623         * @param editor The editor to chain.
624         * @param lineSeparator String to use for separating lines.
625         *
626         * @since 1.2
627         */
628        public SourceFileEditor( final LineEditor editor, final String lineSeparator )
629        {
630            super( editor, lineSeparator );
631        }
632 
633        /**
634         * Creates a new {@code SourceFileEditor} taking a {@code Specification} to edit source code of.
635         *
636         * @param specification The specification to edit source code of.
637         *
638         * @deprecated As of JOMC 1.2, please use method {@link #edit(org.jomc.model.Specification, org.jomc.tools.model.SourceFileType, java.io.File)}.
639         * This constructor will be removed in version 2.0.
640         */
641        @Deprecated
642        public SourceFileEditor( final Specification specification )
643        {
644            this( specification, null, null );
645        }
646 
647        /**
648         * Creates a new {@code SourceFileEditor} taking a {@code Specification} to edit source code of and a line
649         * separator.
650         *
651         * @param specification The specification to edit source code of.
652         * @param lineSeparator The line separator of the editor.
653         *
654         * @deprecated As of JOMC 1.2, please use method {@link #edit(org.jomc.model.Specification, org.jomc.tools.model.SourceFileType, java.io.File)}.
655         * This constructor will be removed in version 2.0.
656         */
657        @Deprecated
658        public SourceFileEditor( final Specification specification, final String lineSeparator )
659        {
660            this( specification, null, lineSeparator );
661        }
662 
663        /**
664         * Creates a new {@code SourceFileEditor} taking a {@code Specification} to edit source code of and an editor to
665         * chain.
666         *
667         * @param specification The specification backing the editor.
668         * @param lineEditor The editor to chain.
669         *
670         * @deprecated As of JOMC 1.2, please use method {@link #edit(org.jomc.model.Specification, org.jomc.tools.model.SourceFileType, java.io.File)}.
671         * This constructor will be removed in version 2.0.
672         */
673        @Deprecated
674        public SourceFileEditor( final Specification specification, final LineEditor lineEditor )
675        {
676            this( specification, lineEditor, null );
677        }
678 
679        /**
680         * Creates a new {@code SourceFileEditor} taking a {@code Specification} to edit source code of, an editor to
681         * chain and a line separator.
682         *
683         * @param specification The specification backing the editor.
684         * @param lineEditor The editor to chain.
685         * @param lineSeparator The line separator of the editor.
686         *
687         * @deprecated As of JOMC 1.2, please use method {@link #edit(org.jomc.model.Specification, org.jomc.tools.model.SourceFileType, java.io.File)}.
688         * This constructor will be removed in version 2.0.
689         */
690        @Deprecated
691        public SourceFileEditor( final Specification specification, final LineEditor lineEditor,
692                                 final String lineSeparator )
693        {
694            super( lineEditor, lineSeparator );
695            this.specification = specification;
696            this.implementation = null;
697            this.sourceFileType = null;
698            this.velocityContext = null;
699 
700            assert getModules().getSpecification( specification.getIdentifier() ) != null :
701                "Specification '" + specification.getIdentifier() + "' not found.";
702 
703        }
704 
705        /**
706         * Creates a new {@code SourceFileEditor} taking an {@code Implementation} to edit source code of.
707         *
708         * @param implementation The implementation to edit source code of.
709         *
710         * @deprecated As of JOMC 1.2, please use method {@link #edit(org.jomc.model.Implementation, org.jomc.tools.model.SourceFileType, java.io.File)}.
711         * This constructor will be removed in version 2.0.
712         */
713        @Deprecated
714        public SourceFileEditor( final Implementation implementation )
715        {
716            this( implementation, null, null );
717        }
718 
719        /**
720         * Creates a new {@code SourceFileEditor} taking an {@code Implementation} to edit source code of and a line
721         * separator.
722         *
723         * @param implementation The implementation to edit source code of.
724         * @param lineSeparator The line separator of the editor.
725         *
726         * @deprecated As of JOMC 1.2, please use method {@link #edit(org.jomc.model.Implementation, org.jomc.tools.model.SourceFileType, java.io.File)}.
727         * This constructor will be removed in version 2.0.
728         */
729        @Deprecated
730        public SourceFileEditor( final Implementation implementation, final String lineSeparator )
731        {
732            this( implementation, null, lineSeparator );
733        }
734 
735        /**
736         * Creates a new {@code SourceFileEditor} taking an {@code Implementation} to edit source code of and an editor
737         * to chain.
738         *
739         * @param implementation The implementation to edit source code of.
740         * @param lineEditor The editor to chain.
741         *
742         * @deprecated As of JOMC 1.2, please use method {@link #edit(org.jomc.model.Implementation, org.jomc.tools.model.SourceFileType, java.io.File)}.
743         * This constructor will be removed in version 2.0.
744         */
745        @Deprecated
746        public SourceFileEditor( final Implementation implementation, final LineEditor lineEditor )
747        {
748            this( implementation, lineEditor, null );
749        }
750 
751        /**
752         * Creates a new {@code SourceFileEditor} taking an {@code Implementation} to edit source code of, an editor
753         * to chain and a line separator.
754         *
755         * @param implementation The implementation to edit source code of.
756         * @param lineEditor The editor to chain.
757         * @param lineSeparator The line separator of the editor.
758         *
759         * @deprecated As of JOMC 1.2, please use method {@link #edit(org.jomc.model.Implementation, org.jomc.tools.model.SourceFileType, java.io.File)}.
760         * This constructor will be removed in version 2.0.
761         */
762        @Deprecated
763        public SourceFileEditor( final Implementation implementation, final LineEditor lineEditor,
764                                 final String lineSeparator )
765        {
766            super( lineEditor, lineSeparator );
767            this.implementation = implementation;
768            this.specification = null;
769            this.sourceFileType = null;
770            this.velocityContext = null;
771 
772            assert getModules().getImplementation( implementation.getIdentifier() ) != null :
773                "Implementation '" + implementation.getIdentifier() + "' not found.";
774 
775        }
776 
777        /**
778         * Edits a source file of a given specification.
779         *
780         * @param specification The specification to edit a source file of.
781         * @param sourceFileType The model of the source file to edit.
782         * @param sourcesDirectory The directory holding the source file to edit.
783         *
784         * @throws NullPointerException if {@code specification}, {@code sourceFileType} or {@code sourcesDirectory} is
785         * {@code null}.
786         * @throws IOException if editing fails.
787         *
788         * @since 1.2
789         */
790        public final void edit( final Specification specification, final SourceFileType sourceFileType,
791                                final File sourcesDirectory ) throws IOException
792        {
793            if ( specification == null )
794            {
795                throw new NullPointerException( "specification" );
796            }
797            if ( sourceFileType == null )
798            {
799                throw new NullPointerException( "sourceFileType" );
800            }
801            if ( sourcesDirectory == null )
802            {
803                throw new NullPointerException( "sourcesDirectory" );
804            }
805 
806            assert getModules().getSpecification( specification.getIdentifier() ) != null :
807                "Specification '" + specification.getIdentifier() + "' not found.";
808 
809            this.specification = specification;
810            this.sourceFileType = sourceFileType;
811            this.velocityContext = SourceFileProcessor.this.getVelocityContext();
812            this.velocityContext.put( "specification", specification );
813 
814            this.editSourceFile( sourcesDirectory );
815 
816            this.implementation = null;
817            this.specification = null;
818            this.sourceFileType = null;
819            this.velocityContext = null;
820        }
821 
822        /**
823         * Edits a source file of a given implementation.
824         *
825         * @param implementation The implementation to edit a source file of.
826         * @param sourceFileType The model of the source file to edit.
827         * @param sourcesDirectory The directory holding the source file to edit.
828         *
829         * @throws NullPointerException if {@code implementation}, {@code sourceFileType} or {@code sourcesDirectory} is
830         * {@code null}.
831         * @throws IOException if editing fails.
832         *
833         * @since 1.2
834         */
835        public final void edit( final Implementation implementation, final SourceFileType sourceFileType,
836                                final File sourcesDirectory ) throws IOException
837        {
838            if ( implementation == null )
839            {
840                throw new NullPointerException( "implementation" );
841            }
842            if ( sourceFileType == null )
843            {
844                throw new NullPointerException( "sourceFileType" );
845            }
846            if ( sourcesDirectory == null )
847            {
848                throw new NullPointerException( "sourcesDirectory" );
849            }
850 
851            assert getModules().getImplementation( implementation.getIdentifier() ) != null :
852                "Implementation '" + implementation.getIdentifier() + "' not found.";
853 
854            this.implementation = implementation;
855            this.sourceFileType = sourceFileType;
856            this.velocityContext = SourceFileProcessor.this.getVelocityContext();
857            this.velocityContext.put( "implementation", implementation );
858 
859            this.editSourceFile( sourcesDirectory );
860 
861            this.implementation = null;
862            this.specification = null;
863            this.sourceFileType = null;
864            this.velocityContext = null;
865        }
866 
867        /**
868         * Gets a list of sections added to the input.
869         * <p>This accessor method returns a reference to the live list, not a snapshot. Therefore any modification you
870         * make to the returned list will be present inside the object. This is why there is no {@code set} method
871         * for the added sections property.</p>
872         *
873         * @return A list of sections added to the input.
874         *
875         * @deprecated As of JOMC 1.2, deprecated without replacement. This method will be removed in version 2.0.
876         */
877        @Deprecated
878        public List<Section> getAddedSections()
879        {
880            if ( this.addedSections == null )
881            {
882                this.addedSections = new LinkedList<Section>();
883            }
884 
885            return this.addedSections;
886        }
887 
888        /**
889         * Gets a list of sections without corresponding model entry.
890         * <p>This accessor method returns a reference to the live list, not a snapshot. Therefore any modification you
891         * make to the returned list will be present inside the object. This is why there is no {@code set} method
892         * for the unknown sections property.</p>
893         *
894         * @return A list of sections without corresponding model entry.
895         *
896         * @deprecated As of JOMC 1.2, deprecated without replacement. This method will be removed in version 2.0.
897         */
898        @Deprecated
899        public List<Section> getUnknownSections()
900        {
901            if ( this.unknownSections == null )
902            {
903                this.unknownSections = new LinkedList<Section>();
904            }
905 
906            return this.unknownSections;
907        }
908 
909        /**
910         * Gets the currently edited source code file.
911         *
912         * @return The currently edited source code file.
913         *
914         * @deprecated As of JOMC 1.2, deprecated without replacement. This method will be removed in version 2.0.
915         */
916        @Deprecated
917        protected SourceFileType getSourceFileType()
918        {
919            if ( this.sourceFileType == null )
920            {
921                if ( this.specification != null )
922                {
923                    return SourceFileProcessor.this.getSourceFileType( this.specification );
924                }
925 
926                if ( this.implementation != null )
927                {
928                    return SourceFileProcessor.this.getSourceFileType( this.implementation );
929                }
930            }
931 
932            return this.sourceFileType;
933        }
934 
935        /**
936         * Gets a new velocity context used for merging templates.
937         *
938         * @return A new velocity context used for merging templates.
939         *
940         * @deprecated As of JOMC 1.2, deprecated without replacement. This method will be removed in version 2.0.
941         */
942        @Deprecated
943        protected VelocityContext getVelocityContext()
944        {
945            if ( this.velocityContext == null )
946            {
947                final VelocityContext ctx = SourceFileProcessor.this.getVelocityContext();
948 
949                if ( this.specification != null )
950                {
951                    ctx.put( "specification", this.specification );
952                }
953 
954                if ( this.implementation != null )
955                {
956                    ctx.put( "implementation", this.implementation );
957                }
958 
959                return ctx;
960            }
961 
962            return this.velocityContext;
963        }
964 
965        /**
966         * {@inheritDoc}
967         * <p>This method creates any sections declared in the model of the source file as returned by method
968         * {@code getSourceFileType} prior to rendering the output of the editor.</p>
969         *
970         * @param section The section to start rendering the editor's output with.
971         *
972         * @see #createSection(java.lang.String, java.lang.String, org.jomc.tools.model.SourceSectionType)
973         */
974        @Override
975        protected String getOutput( final Section section ) throws IOException
976        {
977            this.getAddedSections().clear();
978            this.getUnknownSections().clear();
979 
980            final SourceFileType model = this.getSourceFileType();
981 
982            if ( model != null )
983            {
984                this.createSections( model, model.getSourceSections(), section );
985            }
986 
987            return super.getOutput( section );
988        }
989 
990        /**
991         * {@inheritDoc}
992         * <p>This method searches the model of the source file for a section matching {@code s} and updates properties
993         * {@code headContent} and {@code tailContent} of {@code s} according to the templates declared in the model
994         * as returned by method {@code getSourceFileType}.</p>
995         *
996         * @param s The section to edit.
997         */
998        @Override
999        protected void editSection( final Section s ) throws IOException
1000        {
1001            try
1002            {
1003                super.editSection( s );
1004 
1005                final SourceFileType model = this.getSourceFileType();
1006 
1007                if ( s.getName() != null && model != null && model.getSourceSections() != null )
1008                {
1009                    final SourceSectionType sourceSectionType =
1010                        model.getSourceSections().getSourceSection( s.getName() );
1011 
1012                    if ( sourceSectionType != null )
1013                    {
1014                        if ( s.getStartingLine() != null )
1015                        {
1016                            s.setStartingLine( getIndentation( sourceSectionType.getIndentationLevel() )
1017                                               + s.getStartingLine().trim() );
1018 
1019                        }
1020                        if ( s.getEndingLine() != null )
1021                        {
1022                            s.setEndingLine( getIndentation( sourceSectionType.getIndentationLevel() )
1023                                             + s.getEndingLine().trim() );
1024 
1025                        }
1026 
1027                        if ( sourceSectionType.getHeadTemplate() != null
1028                             && ( !sourceSectionType.isEditable()
1029                                  || s.getHeadContent().toString().trim().length() == 0 ) )
1030                        {
1031                            final StringWriter writer = new StringWriter();
1032                            final Template template = getVelocityTemplate( sourceSectionType.getHeadTemplate() );
1033                            final VelocityContext ctx = getVelocityContext();
1034                            ctx.put( "template", template );
1035                            template.merge( ctx, writer );
1036                            writer.close();
1037                            s.getHeadContent().setLength( 0 );
1038                            s.getHeadContent().append( writer.toString() );
1039                        }
1040 
1041                        if ( sourceSectionType.getTailTemplate() != null
1042                             && ( !sourceSectionType.isEditable()
1043                                  || s.getTailContent().toString().trim().length() == 0 ) )
1044                        {
1045                            final StringWriter writer = new StringWriter();
1046                            final Template template = getVelocityTemplate( sourceSectionType.getTailTemplate() );
1047                            final VelocityContext ctx = getVelocityContext();
1048                            ctx.put( "template", template );
1049                            template.merge( ctx, writer );
1050                            writer.close();
1051                            s.getTailContent().setLength( 0 );
1052                            s.getTailContent().append( writer.toString() );
1053                        }
1054                    }
1055                    else
1056                    {
1057                        if ( isLoggable( Level.WARNING ) )
1058                        {
1059                            if ( this.implementation != null )
1060                            {
1061                                log( Level.WARNING, getMessage(
1062                                    "unknownImplementationSection", this.implementation.getIdentifier(),
1063                                    model.getIdentifier(), s.getName() ), null );
1064 
1065 
1066                            }
1067                            else if ( this.specification != null )
1068                            {
1069                                log( Level.WARNING, getMessage(
1070                                    "unknownSpecificationSection", this.specification.getIdentifier(),
1071                                    model.getIdentifier(), s.getName() ), null );
1072 
1073                            }
1074                        }
1075 
1076                        this.getUnknownSections().add( s );
1077                    }
1078                }
1079            }
1080            catch ( final VelocityException e )
1081            {
1082                // JDK: As of JDK 6, "new IOException( message, cause )".
1083                throw (IOException) new IOException( getMessage( e ) ).initCause( e );
1084            }
1085        }
1086 
1087        private void createSections( final SourceFileType sourceFileType, final SourceSectionsType sourceSectionsType,
1088                                     final Section section ) throws IOException
1089        {
1090            if ( sourceSectionsType != null && section != null )
1091            {
1092                for ( int i = 0, s0 = sourceSectionsType.getSourceSection().size(); i < s0; i++ )
1093                {
1094                    final SourceSectionType sourceSectionType = sourceSectionsType.getSourceSection().get( i );
1095                    Section childSection = section.getSection( sourceSectionType.getName() );
1096 
1097                    if ( childSection == null && !sourceSectionType.isOptional() )
1098                    {
1099                        childSection = this.createSection( StringUtils.defaultString( sourceFileType.getHeadComment() ),
1100                                                           StringUtils.defaultString( sourceFileType.getTailComment() ),
1101                                                           sourceSectionType );
1102 
1103                        section.getSections().add( childSection );
1104 
1105                        if ( isLoggable( Level.FINE ) )
1106                        {
1107                            log( Level.FINE, getMessage(
1108                                "addedSection", sourceFileType.getIdentifier(), childSection.getName() ), null );
1109 
1110                        }
1111 
1112                        this.getAddedSections().add( childSection );
1113                    }
1114 
1115                    this.createSections( sourceFileType, sourceSectionType.getSourceSections(), childSection );
1116                }
1117            }
1118        }
1119 
1120        /**
1121         * Creates a new {@code Section} instance for a given {@code SourceSectionType}.
1122         *
1123         * @param headComment Characters to use to start a comment in the source file.
1124         * @param tailComment Characters to use to end a comment in the source file.
1125         * @param sourceSectionType The {@code SourceSectionType} to create a new {@code Section} instance for.
1126         *
1127         * @return A new {@code Section} instance for {@code sourceSectionType}.
1128         *
1129         * @throws NullPointerException if {@code headComment}, {@code tailComment} or {@code sourceSectionType} is
1130         * {@code null}.
1131         * @throws IOException if creating a new {@code Section} instance fails.
1132         *
1133         * @since 1.2
1134         */
1135        private Section createSection( final String headComment, final String tailComment,
1136                                       final SourceSectionType sourceSectionType ) throws IOException
1137        {
1138            if ( headComment == null )
1139            {
1140                throw new NullPointerException( "headComment" );
1141            }
1142            if ( tailComment == null )
1143            {
1144                throw new NullPointerException( "tailComment" );
1145            }
1146            if ( sourceSectionType == null )
1147            {
1148                throw new NullPointerException( "sourceSectionType" );
1149            }
1150 
1151            final Section s = new Section();
1152            s.setName( sourceSectionType.getName() );
1153 
1154            final StringBuilder head = new StringBuilder( 255 );
1155            head.append( getIndentation( sourceSectionType.getIndentationLevel() ) ).append( headComment );
1156 
1157            s.setStartingLine( head + " SECTION-START[" + sourceSectionType.getName() + ']' + tailComment );
1158            s.setEndingLine( head + " SECTION-END" + tailComment );
1159 
1160            return s;
1161        }
1162 
1163        private void editSourceFile( final File sourcesDirectory ) throws IOException
1164        {
1165            if ( sourcesDirectory == null )
1166            {
1167                throw new NullPointerException( "sourcesDirectory" );
1168            }
1169            if ( !sourcesDirectory.isDirectory() )
1170            {
1171                throw new IOException( getMessage( "directoryNotFound", sourcesDirectory.getAbsolutePath() ) );
1172            }
1173 
1174            final SourceFileType model = this.getSourceFileType();
1175 
1176            if ( model != null && model.getLocation() != null )
1177            {
1178                final File f = new File( sourcesDirectory, model.getLocation() );
1179 
1180                try
1181                {
1182                    String content = "";
1183                    String edited = null;
1184                    boolean creating = false;
1185 
1186                    if ( !f.exists() )
1187                    {
1188                        if ( model.getTemplate() != null )
1189                        {
1190                            final StringWriter writer = new StringWriter();
1191                            final Template template = getVelocityTemplate( model.getTemplate() );
1192                            final VelocityContext ctx = this.getVelocityContext();
1193                            ctx.put( "template", template );
1194                            template.merge( ctx, writer );
1195                            writer.close();
1196                            content = writer.toString();
1197                            creating = true;
1198                        }
1199                    }
1200                    else
1201                    {
1202                        if ( isLoggable( Level.FINER ) )
1203                        {
1204                            log( Level.FINER, getMessage( "reading", f.getAbsolutePath() ), null );
1205                        }
1206 
1207                        content = this.readSourceFile( f );
1208                    }
1209 
1210                    try
1211                    {
1212                        edited = super.edit( content );
1213                    }
1214                    catch ( final IOException e )
1215                    {
1216                        // JDK: As of JDK 6, "new IOException( message, cause )".
1217                        throw (IOException) new IOException( getMessage(
1218                            "failedEditing", f.getAbsolutePath(), getMessage( e ) ) ).initCause( e );
1219 
1220                    }
1221 
1222                    if ( !edited.equals( content ) || edited.length() == 0 )
1223                    {
1224                        if ( !f.getParentFile().exists() && !f.getParentFile().mkdirs() )
1225                        {
1226                            throw new IOException( getMessage(
1227                                "failedCreatingDirectory", f.getParentFile().getAbsolutePath() ) );
1228 
1229                        }
1230 
1231                        if ( isLoggable( Level.INFO ) )
1232                        {
1233                            log( Level.INFO, getMessage(
1234                                creating ? "creating" : "editing", f.getAbsolutePath() ), null );
1235 
1236                        }
1237 
1238                        this.writeSourceFile( f, edited );
1239                    }
1240                    else if ( isLoggable( Level.FINER ) )
1241                    {
1242                        log( Level.FINER, getMessage( "unchanged", f.getAbsolutePath() ), null );
1243                    }
1244                }
1245                catch ( final VelocityException e )
1246                {
1247                    // JDK: As of JDK 6, "new IOException( message, cause )".
1248                    throw (IOException) new IOException( getMessage(
1249                        "failedEditing", f.getAbsolutePath(), getMessage( e ) ) ).initCause( e );
1250 
1251                }
1252            }
1253        }
1254 
1255        private String readSourceFile( final File file ) throws IOException
1256        {
1257            if ( file == null )
1258            {
1259                throw new NullPointerException( "file" );
1260            }
1261 
1262            RandomAccessFile randomAccessFile = null;
1263            FileChannel fileChannel = null;
1264            FileLock fileLock = null;
1265            boolean suppressExceptionOnClose = true;
1266 
1267            //final Charset charset = Charset.forName( getInputEncoding() );
1268            final int length = file.length() > 0L ? Long.valueOf( file.length() ).intValue() : 1;
1269            final ByteBuffer buf = ByteBuffer.allocate( length );
1270            final StringBuilder appendable = new StringBuilder( length );
1271 
1272            try
1273            {
1274                randomAccessFile = new RandomAccessFile( file, "r" );
1275                fileChannel = randomAccessFile.getChannel();
1276                fileLock = fileChannel.lock( 0L, file.length(), true );
1277                fileChannel.position( 0L );
1278 
1279                buf.clear();
1280                int read = fileChannel.read( buf );
1281 
1282                while ( read != -1 )
1283                {
1284                    // JDK: As of JDK 6, new String( byte[], int, int, Charset )
1285                    appendable.append( new String( buf.array(), buf.arrayOffset(), read, getInputEncoding() ) );
1286                    buf.clear();
1287                    read = fileChannel.read( buf );
1288                }
1289 
1290                suppressExceptionOnClose = false;
1291                return appendable.toString();
1292            }
1293            finally
1294            {
1295                try
1296                {
1297                    if ( fileLock != null )
1298                    {
1299                        fileLock.release();
1300                    }
1301                }
1302                catch ( final IOException e )
1303                {
1304                    if ( suppressExceptionOnClose )
1305                    {
1306                        log( Level.SEVERE, null, e );
1307                    }
1308                    else
1309                    {
1310                        throw e;
1311                    }
1312                }
1313                finally
1314                {
1315                    try
1316                    {
1317                        if ( fileChannel != null )
1318                        {
1319                            fileChannel.close();
1320                        }
1321                    }
1322                    catch ( final IOException e )
1323                    {
1324                        if ( suppressExceptionOnClose )
1325                        {
1326                            log( Level.SEVERE, null, e );
1327                        }
1328                        else
1329                        {
1330                            throw e;
1331                        }
1332                    }
1333                    finally
1334                    {
1335                        try
1336                        {
1337                            if ( randomAccessFile != null )
1338                            {
1339                                randomAccessFile.close();
1340                            }
1341                        }
1342                        catch ( final IOException e )
1343                        {
1344                            if ( suppressExceptionOnClose )
1345                            {
1346                                log( Level.SEVERE, null, e );
1347                            }
1348                            else
1349                            {
1350                                throw e;
1351                            }
1352                        }
1353                    }
1354                }
1355            }
1356        }
1357 
1358        private void writeSourceFile( final File file, final String content ) throws IOException
1359        {
1360            if ( file == null )
1361            {
1362                throw new NullPointerException( "file" );
1363            }
1364            if ( content == null )
1365            {
1366                throw new NullPointerException( "content" );
1367            }
1368 
1369            RandomAccessFile randomAccessFile = null;
1370            FileChannel fileChannel = null;
1371            FileLock fileLock = null;
1372            boolean suppressExceptionOnClose = true;
1373            final byte[] bytes = content.getBytes( getOutputEncoding() );
1374 
1375            try
1376            {
1377                randomAccessFile = new RandomAccessFile( file, "rw" );
1378                fileChannel = randomAccessFile.getChannel();
1379                fileLock = fileChannel.lock( 0L, bytes.length, false );
1380                fileChannel.truncate( bytes.length );
1381                fileChannel.position( 0L );
1382                fileChannel.write( ByteBuffer.wrap( bytes ) );
1383                fileChannel.force( true );
1384                suppressExceptionOnClose = false;
1385            }
1386            finally
1387            {
1388                try
1389                {
1390                    if ( fileLock != null )
1391                    {
1392                        fileLock.release();
1393                    }
1394                }
1395                catch ( final IOException e )
1396                {
1397                    if ( suppressExceptionOnClose )
1398                    {
1399                        log( Level.SEVERE, null, e );
1400                    }
1401                    else
1402                    {
1403                        throw e;
1404                    }
1405                }
1406                finally
1407                {
1408                    try
1409                    {
1410                        if ( fileChannel != null )
1411                        {
1412                            fileChannel.close();
1413                        }
1414                    }
1415                    catch ( final IOException e )
1416                    {
1417                        if ( suppressExceptionOnClose )
1418                        {
1419                            log( Level.SEVERE, null, e );
1420                        }
1421                        else
1422                        {
1423                            throw e;
1424                        }
1425                    }
1426                    finally
1427                    {
1428                        try
1429                        {
1430                            if ( randomAccessFile != null )
1431                            {
1432                                randomAccessFile.close();
1433                            }
1434                        }
1435                        catch ( final IOException e )
1436                        {
1437                            if ( suppressExceptionOnClose )
1438                            {
1439                                log( Level.SEVERE, null, e );
1440                            }
1441                            else
1442                            {
1443                                throw e;
1444                            }
1445                        }
1446                    }
1447                }
1448            }
1449        }
1450 
1451    }
1452 
1453}

[all classes][org.jomc.tools]
EMMA 2.1.5320 (stable) (C) Vladimir Roubtsov