EMMA Coverage Report (generated Tue Nov 18 06:49:09 CET 2014)
[all classes][org.jomc.tools.modlet]

COVERAGE SUMMARY FOR SOURCE FILE [ToolsModelProvider.java]

nameclass, %method, %block, %line, %
ToolsModelProvider.java100% (1/1)78%  (25/32)72%  (1346/1875)71%  (304.6/429)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ToolsModelProvider100% (1/1)78%  (25/32)72%  (1346/1875)71%  (304.6/429)
getField (Class, String): Field 0%   (0/1)0%   (0/14)0%   (0/5)
getMessage (Throwable): String 0%   (0/1)0%   (0/19)0%   (0/1)
isFieldSet (Object, String): boolean 0%   (0/1)0%   (0/43)0%   (0/9)
overwriteSourceFile (SourceFileType, SourceFileType, boolean): void 0%   (0/1)0%   (0/81)0%   (0/21)
overwriteSourceSections (SourceSectionsType, SourceSectionsType, boolean): void 0%   (0/1)0%   (0/128)0%   (0/32)
setDefaultModelObjectClasspathResolutionEnabled (Boolean): void 0%   (0/1)0%   (0/3)0%   (0/2)
setModelObjectClasspathResolutionEnabled (Boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
getDefaultSourceSectionName (ModelContext, Modules, Implementation): String 100% (1/1)48%  (20/42)64%  (9/14)
getDefaultSourceSectionName (ModelContext, Modules, Specification): String 100% (1/1)48%  (20/42)64%  (9/14)
overwriteSourceFiles (SourceFilesType, SourceFilesType, boolean): void 100% (1/1)54%  (25/46)62%  (8/13)
getDefaultSourceFileLocation (ModelContext, Modules, Implementation): String 100% (1/1)56%  (28/50)62%  (8/13)
getDefaultSourceFileLocation (ModelContext, Modules, Specification): String 100% (1/1)56%  (28/50)62%  (8/13)
getDefaultSourceFilesType (ModelContext, Modules, Specification): SourceFiles... 100% (1/1)85%  (227/266)86%  (48/56)
findModel (ModelContext, Model): Model 100% (1/1)88%  (341/387)85%  (65.7/77)
getDefaultSourceFilesType (ModelContext, Modules, Implementation): SourceFile... 100% (1/1)92%  (527/570)93%  (105.9/114)
<static initializer> 100% (1/1)100% (14/14)100% (4/4)
ToolsModelProvider (): void 100% (1/1)100% (3/3)100% (2/2)
getDefaultHeadComment (): String 100% (1/1)100% (8/8)100% (3/3)
getDefaultTailComment (): String 100% (1/1)100% (8/8)100% (3/3)
getHeadComment (): String 100% (1/1)100% (9/9)100% (3/3)
getMessage (String, Object []): String 100% (1/1)100% (12/12)100% (1/1)
getTailComment (): String 100% (1/1)100% (9/9)100% (3/3)
isDefaultEnabled (): boolean 100% (1/1)100% (12/12)100% (3/3)
isDefaultModelObjectClasspathResolutionEnabled (): boolean 100% (1/1)100% (12/12)100% (3/3)
isEnabled (): boolean 100% (1/1)100% (11/11)100% (3/3)
isModelObjectClasspathResolutionEnabled (): boolean 100% (1/1)100% (11/11)100% (3/3)
setDefaultEnabled (Boolean): void 100% (1/1)100% (3/3)100% (2/2)
setDefaultHeadComment (String): void 100% (1/1)100% (3/3)100% (2/2)
setDefaultTailComment (String): void 100% (1/1)100% (3/3)100% (2/2)
setEnabled (Boolean): void 100% (1/1)100% (4/4)100% (2/2)
setHeadComment (String): void 100% (1/1)100% (4/4)100% (2/2)
setTailComment (String): void 100% (1/1)100% (4/4)100% (2/2)

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: ToolsModelProvider.java 4852 2014-01-26 05:42:11Z schulte $
29 *
30 */
31package org.jomc.tools.modlet;
32 
33import java.lang.reflect.Field;
34import java.text.MessageFormat;
35import java.util.ArrayList;
36import java.util.HashMap;
37import java.util.HashSet;
38import java.util.Locale;
39import java.util.Map;
40import java.util.ResourceBundle;
41import java.util.Set;
42import java.util.logging.Level;
43import javax.xml.bind.JAXBElement;
44import javax.xml.namespace.QName;
45import org.jomc.model.Dependencies;
46import org.jomc.model.Implementation;
47import org.jomc.model.InheritanceModel;
48import org.jomc.model.JavaTypeName;
49import org.jomc.model.Messages;
50import org.jomc.model.ModelObjectException;
51import org.jomc.model.Module;
52import org.jomc.model.Modules;
53import org.jomc.model.Properties;
54import org.jomc.model.Specification;
55import org.jomc.model.Specifications;
56import org.jomc.model.modlet.ModelHelper;
57import org.jomc.modlet.Model;
58import org.jomc.modlet.ModelContext;
59import org.jomc.modlet.ModelException;
60import org.jomc.modlet.ModelProvider;
61import org.jomc.tools.model.ObjectFactory;
62import org.jomc.tools.model.SourceFileType;
63import org.jomc.tools.model.SourceFilesType;
64import org.jomc.tools.model.SourceSectionType;
65import org.jomc.tools.model.SourceSectionsType;
66import static org.jomc.tools.modlet.ToolsModletConstants.ANNOTATIONS_SECTION_NAME;
67import static org.jomc.tools.modlet.ToolsModletConstants.CONSTRUCTORS_HEAD_TEMPLATE;
68import static org.jomc.tools.modlet.ToolsModletConstants.CONSTRUCTORS_SECTION_NAME;
69import static org.jomc.tools.modlet.ToolsModletConstants.CONSTRUCTORS_TAIL_TEMPLATE;
70import static org.jomc.tools.modlet.ToolsModletConstants.DEFAULT_CONSTRUCTOR_SECTION_NAME;
71import static org.jomc.tools.modlet.ToolsModletConstants.DEFAULT_CONSTRUCTOR_TEMPLATE;
72import static org.jomc.tools.modlet.ToolsModletConstants.DEPENDENCIES_SECTION_NAME;
73import static org.jomc.tools.modlet.ToolsModletConstants.DEPENDENCIES_TEMPLATE;
74import static org.jomc.tools.modlet.ToolsModletConstants.DOCUMENTATION_SECTION_NAME;
75import static org.jomc.tools.modlet.ToolsModletConstants.IMPLEMENTATION_ANNOTATIONS_TEMPLATE;
76import static org.jomc.tools.modlet.ToolsModletConstants.IMPLEMENTATION_DOCUMENTATION_TEMPLATE;
77import static org.jomc.tools.modlet.ToolsModletConstants.IMPLEMENTATION_LICENSE_TEMPLATE;
78import static org.jomc.tools.modlet.ToolsModletConstants.IMPLEMENTATION_TEMPLATE;
79import static org.jomc.tools.modlet.ToolsModletConstants.LICENSE_SECTION_NAME;
80import static org.jomc.tools.modlet.ToolsModletConstants.MESSAGES_SECTION_NAME;
81import static org.jomc.tools.modlet.ToolsModletConstants.MESSAGES_TEMPLATE;
82import static org.jomc.tools.modlet.ToolsModletConstants.PROPERTIES_SECTION_NAME;
83import static org.jomc.tools.modlet.ToolsModletConstants.PROPERTIES_TEMPLATE;
84import static org.jomc.tools.modlet.ToolsModletConstants.SPECIFICATION_ANNOTATIONS_TEMPLATE;
85import static org.jomc.tools.modlet.ToolsModletConstants.SPECIFICATION_DOCUMENTATION_TEMPLATE;
86import static org.jomc.tools.modlet.ToolsModletConstants.SPECIFICATION_LICENSE_TEMPLATE;
87import static org.jomc.tools.modlet.ToolsModletConstants.SPECIFICATION_TEMPLATE;
88 
89/**
90 * Object management and configuration tools {@code ModelProvider} implementation.
91 *
92 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
93 * @version $JOMC: ToolsModelProvider.java 4852 2014-01-26 05:42:11Z schulte $
94 * @see ModelContext#findModel(java.lang.String)
95 * @since 1.2
96 */
97public class ToolsModelProvider implements ModelProvider
98{
99 
100    /** Constant for the qualified name of {@code source-files} elements. */
101    private static final QName SOURCE_FILES_QNAME = new ObjectFactory().createSourceFiles( null ).getName();
102 
103    /**
104     * Constant for the name of the model context attribute backing property {@code enabled}.
105     * @see #findModel(org.jomc.modlet.ModelContext, org.jomc.modlet.Model)
106     * @see ModelContext#getAttribute(java.lang.String)
107     */
108    public static final String ENABLED_ATTRIBUTE_NAME = "org.jomc.tools.modlet.ToolsModelProvider.enabledAttribute";
109 
110    /**
111     * Constant for the name of the system property controlling property {@code defaultEnabled}.
112     * @see #isDefaultEnabled()
113     */
114    private static final String DEFAULT_ENABLED_PROPERTY_NAME =
115        "org.jomc.tools.modlet.ToolsModelProvider.defaultEnabled";
116 
117    /**
118     * Default value of the flag indicating the provider is enabled by default.
119     * @see #isDefaultEnabled()
120     */
121    private static final Boolean DEFAULT_ENABLED = Boolean.TRUE;
122 
123    /** Flag indicating the provider is enabled by default. */
124    private static volatile Boolean defaultEnabled;
125 
126    /** Flag indicating the provider is enabled. */
127    private Boolean enabled;
128 
129    /**
130     * Constant for the name of the model context attribute backing property
131     * {@code modelObjectClasspathResolutionEnabled}.
132     *
133     * @see #findModel(org.jomc.modlet.ModelContext, org.jomc.modlet.Model)
134     * @see ModelContext#getAttribute(java.lang.String)
135     */
136    public static final String MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_ATTRIBUTE_NAME =
137        "org.jomc.tools.modlet.ToolsModelProvider.modelObjectClasspathResolutionEnabledAttribute";
138 
139    /**
140     * Constant for the name of the system property controlling property
141     * {@code defaultModelObjectClasspathResolutionEnabled}.
142     * @see #isDefaultModelObjectClasspathResolutionEnabled()
143     */
144    private static final String DEFAULT_MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_PROPERTY_NAME =
145        "org.jomc.tools.modlet.ToolsModelProvider.defaultModelObjectClasspathResolutionEnabled";
146 
147    /**
148     * Default value of the flag indicating model object class path resolution is enabled by default.
149     * @see #isDefaultModelObjectClasspathResolutionEnabled()
150     */
151    private static final Boolean DEFAULT_MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED = Boolean.TRUE;
152 
153    /** Flag indicating model object class path resolution is enabled by default. */
154    private static volatile Boolean defaultModelObjectClasspathResolutionEnabled;
155 
156    /** Flag indicating model object class path resolution is enabled. */
157    private Boolean modelObjectClasspathResolutionEnabled;
158 
159    /**
160     * Constant for the name of the model context attribute backing property {@code headComment}.
161     * @see #findModel(org.jomc.modlet.ModelContext, org.jomc.modlet.Model)
162     * @see ModelContext#getAttribute(java.lang.String)
163     * @since 1.6
164     */
165    public static final String HEAD_COMMENT_ATTRIBUTE_NAME =
166        "org.jomc.tools.modlet.ToolsModelProvider.headCommentAttribute";
167 
168    /**
169     * Constant for the name of the system property controlling property {@code defaultHeadComment}.
170     * @see #getDefaultHeadComment()
171     * @since 1.6
172     */
173    private static final String DEFAULT_HEAD_COMMENT_PROPERTY_NAME =
174        "org.jomc.tools.modlet.ToolsModelProvider.defaultHeadComment";
175 
176    /**
177     * Default head comment the provider is providing by default.
178     * @see #getDefaultHeadComment()
179     * @since 1.6
180     */
181    private static final String DEFAULT_HEAD_COMMENT = "//";
182 
183    /**
184     * Head comment the provider is providing by default.
185     * @since 1.6
186     */
187    private static volatile String defaultHeadComment;
188 
189    /**
190     * Head comment the provider is providing.
191     * @since 1.6
192     */
193    private String headComment;
194 
195    /**
196     * Constant for the name of the model context attribute backing property {@code tailComment}.
197     * @see #findModel(org.jomc.modlet.ModelContext, org.jomc.modlet.Model)
198     * @see ModelContext#getAttribute(java.lang.String)
199     * @since 1.6
200     */
201    public static final String TAIL_COMMENT_ATTRIBUTE_NAME =
202        "org.jomc.tools.modlet.ToolsModelProvider.tailCommentAttribute";
203 
204    /**
205     * Constant for the name of the system property controlling property {@code defaultTailComment}.
206     * @see #getDefaultTailComment()
207     * @since 1.6
208     */
209    private static final String DEFAULT_TAIL_COMMENT_PROPERTY_NAME =
210        "org.jomc.tools.modlet.ToolsModelProvider.defaultTailComment";
211 
212    /**
213     * Default tail comment the provider is providing by default.
214     * @see #getDefaultTailComment()
215     * @since 1.6
216     */
217    private static final String DEFAULT_TAIL_COMMENT = null;
218 
219    /**
220     * Tail comment the provider is providing by default.
221     * @since 1.6
222     */
223    private static volatile String defaultTailComment;
224 
225    /**
226     * Tail comment the provider is providing.
227     * @since 1.6
228     */
229    private String tailComment;
230 
231    /** Creates a new {@code ToolsModelProvider} instance. */
232    public ToolsModelProvider()
233    {
234        super();
235    }
236 
237    /**
238     * Gets a flag indicating the provider is enabled by default.
239     * <p>The default enabled flag is controlled by system property
240     * {@code org.jomc.tools.modlet.ToolsModelProvider.defaultEnabled} holding a value indicating the provider is
241     * enabled by default. If that property is not set, the {@code true} default is returned.</p>
242     *
243     * @return {@code true}, if the provider is enabled by default; {@code false}, if the provider is disabled by
244     * default.
245     *
246     * @see #setDefaultEnabled(java.lang.Boolean)
247     */
248    public static boolean isDefaultEnabled()
249    {
250        if ( defaultEnabled == null )
251        {
252            defaultEnabled = Boolean.valueOf( System.getProperty( DEFAULT_ENABLED_PROPERTY_NAME,
253                                                                  Boolean.toString( DEFAULT_ENABLED ) ) );
254 
255        }
256 
257        return defaultEnabled;
258    }
259 
260    /**
261     * Sets the flag indicating the provider is enabled by default.
262     *
263     * @param value The new value of the flag indicating the provider is enabled by default or {@code null}.
264     *
265     * @see #isDefaultEnabled()
266     */
267    public static void setDefaultEnabled( final Boolean value )
268    {
269        defaultEnabled = value;
270    }
271 
272    /**
273     * Gets a flag indicating the provider is enabled.
274     *
275     * @return {@code true}, if the provider is enabled; {@code false}, if the provider is disabled.
276     *
277     * @see #isDefaultEnabled()
278     * @see #setEnabled(java.lang.Boolean)
279     */
280    public final boolean isEnabled()
281    {
282        if ( this.enabled == null )
283        {
284            this.enabled = isDefaultEnabled();
285        }
286 
287        return this.enabled;
288    }
289 
290    /**
291     * Sets the flag indicating the provider is enabled.
292     *
293     * @param value The new value of the flag indicating the provider is enabled or {@code null}.
294     *
295     * @see #isEnabled()
296     */
297    public final void setEnabled( final Boolean value )
298    {
299        this.enabled = value;
300    }
301 
302    /**
303     * Gets a flag indicating model object class path resolution is enabled by default.
304     * <p>The model object class path resolution default enabled flag is controlled by system property
305     * {@code org.jomc.tools.modlet.ToolsModelProvider.defaultModelObjectClasspathResolutionEnabled} holding a value
306     * indicating model object class path resolution is enabled by default. If that property is not set, the
307     * {@code true} default is returned.</p>
308     *
309     * @return {@code true}, if model object class path resolution is enabled by default; {@code false}, if model object
310     * class path resolution is disabled by default.
311     *
312     * @see #setDefaultModelObjectClasspathResolutionEnabled(java.lang.Boolean)
313     */
314    public static boolean isDefaultModelObjectClasspathResolutionEnabled()
315    {
316        if ( defaultModelObjectClasspathResolutionEnabled == null )
317        {
318            defaultModelObjectClasspathResolutionEnabled = Boolean.valueOf( System.getProperty(
319                DEFAULT_MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_PROPERTY_NAME,
320                Boolean.toString( DEFAULT_MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED ) ) );
321 
322        }
323 
324        return defaultModelObjectClasspathResolutionEnabled;
325    }
326 
327    /**
328     * Sets the flag indicating model object class path resolution is enabled by default.
329     *
330     * @param value The new value of the flag indicating model object class path resolution is enabled by default or
331     * {@code null}.
332     *
333     * @see #isDefaultModelObjectClasspathResolutionEnabled()
334     */
335    public static void setDefaultModelObjectClasspathResolutionEnabled( final Boolean value )
336    {
337        defaultModelObjectClasspathResolutionEnabled = value;
338    }
339 
340    /**
341     * Gets a flag indicating model object class path resolution is enabled.
342     *
343     * @return {@code true}, if model object class path resolution is enabled; {@code false}, if model object class path
344     * resolution is disabled.
345     *
346     * @see #isDefaultModelObjectClasspathResolutionEnabled()
347     * @see #setModelObjectClasspathResolutionEnabled(java.lang.Boolean)
348     */
349    public final boolean isModelObjectClasspathResolutionEnabled()
350    {
351        if ( this.modelObjectClasspathResolutionEnabled == null )
352        {
353            this.modelObjectClasspathResolutionEnabled = isDefaultModelObjectClasspathResolutionEnabled();
354        }
355 
356        return this.modelObjectClasspathResolutionEnabled;
357    }
358 
359    /**
360     * Sets the flag indicating model object class path resolution is is enabled.
361     *
362     * @param value The new value of the flag indicating model object class path resolution is enabled or {@code null}.
363     *
364     * @see #isModelObjectClasspathResolutionEnabled()
365     */
366    public final void setModelObjectClasspathResolutionEnabled( final Boolean value )
367    {
368        this.modelObjectClasspathResolutionEnabled = value;
369    }
370 
371    /**
372     * Gets the head comment the provider is providing by default.
373     * <p>The default head comment is controlled by system property
374     * {@code org.jomc.tools.modlet.ToolsModelProvider.defaultHeadComment} holding the head comment the provider is
375     * providing by default. If that property is not set, the {@code //} default is returned.</p>
376     *
377     * @return The head comment the provider is providing by default or {@code null}.
378     *
379     * @see #setDefaultHeadComment(java.lang.String)
380     * @since 1.6
381     */
382    public static String getDefaultHeadComment()
383    {
384        if ( defaultHeadComment == null )
385        {
386            defaultHeadComment = System.getProperty( DEFAULT_HEAD_COMMENT_PROPERTY_NAME, DEFAULT_HEAD_COMMENT );
387        }
388 
389        return defaultHeadComment;
390    }
391 
392    /**
393     * Sets the head comment the provider is providing by default.
394     *
395     * @param value The new head comment the provider is providing by default or {@code null}.
396     *
397     * @see #getDefaultHeadComment()
398     * @since 1.6
399     */
400    public static void setDefaultHeadComment( final String value )
401    {
402        defaultHeadComment = value;
403    }
404 
405    /**
406     * Gets the head comment the provider is providing.
407     *
408     * @return The head comment the provider is providing or {@code null}.
409     *
410     * @see #getDefaultHeadComment()
411     * @see #setDefaultHeadComment(java.lang.String)
412     * @since 1.6
413     */
414    public final String getHeadComment()
415    {
416        if ( this.headComment == null )
417        {
418            this.headComment = getDefaultHeadComment();
419        }
420 
421        return this.headComment;
422    }
423 
424    /**
425     * Sets the head comment the provider is providing.
426     *
427     * @param value The new head comment the provider is providing or {@code null}.
428     *
429     * @see #getHeadComment()
430     * @since 1.6
431     */
432    public final void setHeadComment( final String value )
433    {
434        this.headComment = value;
435    }
436 
437    /**
438     * Gets the tail comment the provider is providing by default.
439     * <p>The default tail comment is controlled by system property
440     * {@code org.jomc.tools.modlet.ToolsModelProvider.defaultTailComment} holding the tail comment the provider is
441     * providing by default. If that property is not set, the {@code null} default is returned.</p>
442     *
443     * @return The tail comment the provider is providing by default or {@code null}.
444     *
445     * @see #setDefaultTailComment(java.lang.String)
446     * @since 1.6
447     */
448    public static String getDefaultTailComment()
449    {
450        if ( defaultTailComment == null )
451        {
452            defaultTailComment = System.getProperty( DEFAULT_TAIL_COMMENT_PROPERTY_NAME, DEFAULT_TAIL_COMMENT );
453        }
454 
455        return defaultTailComment;
456    }
457 
458    /**
459     * Sets the tail comment the provider is providing by default.
460     *
461     * @param value The new tail comment the provider is providing by default or {@code null}.
462     *
463     * @see #getDefaultTailComment()
464     * @since 1.6
465     */
466    public static void setDefaultTailComment( final String value )
467    {
468        defaultTailComment = value;
469    }
470 
471    /**
472     * Gets the tail comment the provider is providing.
473     *
474     * @return The tail comment the provider is providing or {@code null}.
475     *
476     * @see #getDefaultTailComment()
477     * @see #setDefaultTailComment(java.lang.String)
478     * @since 1.6
479     */
480    public final String getTailComment()
481    {
482        if ( this.tailComment == null )
483        {
484            this.tailComment = getDefaultTailComment();
485        }
486 
487        return this.tailComment;
488    }
489 
490    /**
491     * Sets the tail comment the provider is providing.
492     *
493     * @param value The new tail comment the provider is providing or {@code null}.
494     *
495     * @see #getTailComment()
496     * @since 1.6
497     */
498    public final void setTailComment( final String value )
499    {
500        this.tailComment = value;
501    }
502 
503    /**
504     * {@inheritDoc}
505     *
506     * @see #isEnabled()
507     * @see #isModelObjectClasspathResolutionEnabled()
508     * @see #getHeadComment()
509     * @see #getTailComment()
510     * @see #ENABLED_ATTRIBUTE_NAME
511     * @see #MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_ATTRIBUTE_NAME
512     * @see #HEAD_COMMENT_ATTRIBUTE_NAME
513     * @see #TAIL_COMMENT_ATTRIBUTE_NAME
514     */
515    public Model findModel( final ModelContext context, final Model model ) throws ModelException
516    {
517        if ( context == null )
518        {
519            throw new NullPointerException( "context" );
520        }
521        if ( model == null )
522        {
523            throw new NullPointerException( "model" );
524        }
525 
526        Model provided = null;
527 
528        boolean contextEnabled = this.isEnabled();
529        if ( DEFAULT_ENABLED == contextEnabled && context.getAttribute( ENABLED_ATTRIBUTE_NAME ) instanceof Boolean )
530        {
531            contextEnabled = (Boolean) context.getAttribute( ENABLED_ATTRIBUTE_NAME );
532        }
533 
534        boolean contextModelObjectClasspathResolutionEnabled = this.isModelObjectClasspathResolutionEnabled();
535        if ( contextModelObjectClasspathResolutionEnabled == DEFAULT_MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED
536             && context.getAttribute( MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_ATTRIBUTE_NAME ) instanceof Boolean )
537        {
538            contextModelObjectClasspathResolutionEnabled =
539                (Boolean) context.getAttribute( MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_ATTRIBUTE_NAME );
540 
541        }
542 
543        if ( contextEnabled )
544        {
545            provided = model.clone();
546            final Modules modules = ModelHelper.getModules( provided );
547 
548            if ( modules != null )
549            {
550                Module classpathModule = null;
551                if ( contextModelObjectClasspathResolutionEnabled )
552                {
553                    classpathModule = modules.getClasspathModule( Modules.getDefaultClasspathModuleName(),
554                                                                  context.getClassLoader() );
555 
556                    if ( classpathModule != null
557                         && modules.getModule( Modules.getDefaultClasspathModuleName() ) == null )
558                    {
559                        modules.getModule().add( classpathModule );
560                    }
561                    else
562                    {
563                        classpathModule = null;
564                    }
565                }
566 
567                if ( modules.getSpecifications() != null )
568                {
569                    for ( int i = 0, s0 = modules.getSpecifications().getSpecification().size(); i < s0; i++ )
570                    {
571                        final Specification specification = modules.getSpecifications().getSpecification().get( i );
572                        final SourceFileType sourceFileType = specification.getAnyObject( SourceFileType.class );
573                        final SourceFilesType sourceFilesType = specification.getAnyObject( SourceFilesType.class );
574 
575                        if ( sourceFileType == null && specification.isClassDeclaration() )
576                        {
577                            final SourceFilesType defaultSourceFiles =
578                                this.getDefaultSourceFilesType( context, modules, specification );
579 
580                            if ( sourceFilesType != null )
581                            {
582                                this.overwriteSourceFiles( sourceFilesType, defaultSourceFiles, true );
583                            }
584                            else
585                            {
586                                specification.getAny().add(
587                                    new ObjectFactory().createSourceFiles( defaultSourceFiles ) );
588 
589                            }
590                        }
591                    }
592                }
593 
594                if ( modules.getImplementations() != null )
595                {
596                    final Map<Implementation, SourceFilesType> userSourceFiles =
597                        new HashMap<Implementation, SourceFilesType>(
598                            modules.getImplementations().getImplementation().size() );
599 
600                    InheritanceModel imodel = new InheritanceModel( modules );
601 
602                    for ( int i = 0, s0 = modules.getImplementations().getImplementation().size(); i < s0; i++ )
603                    {
604                        final Implementation implementation = modules.getImplementations().getImplementation().get( i );
605                        final SourceFileType sourceFileType = implementation.getAnyObject( SourceFileType.class );
606                        final SourceFilesType sourceFilesType = implementation.getAnyObject( SourceFilesType.class );
607 
608                        if ( sourceFileType == null )
609                        {
610                            if ( sourceFilesType != null )
611                            {
612                                userSourceFiles.put( implementation, sourceFilesType );
613                            }
614                            else if ( implementation.isClassDeclaration() )
615                            {
616                                final SourceFilesType defaultSourceFiles =
617                                    this.getDefaultSourceFilesType( context, modules, implementation );
618 
619                                boolean finalAncestor = false;
620 
621                                final Set<InheritanceModel.Node<JAXBElement<?>>> sourceFilesNodes =
622                                    imodel.getJaxbElementNodes( implementation.getIdentifier(), SOURCE_FILES_QNAME );
623 
624                                for ( final InheritanceModel.Node<JAXBElement<?>> sourceFilesNode : sourceFilesNodes )
625                                {
626                                    if ( sourceFilesNode.getModelObject().getValue() instanceof SourceFilesType )
627                                    {
628                                        final SourceFilesType ancestorSourceFiles =
629                                            (SourceFilesType) sourceFilesNode.getModelObject().getValue();
630 
631                                        this.overwriteSourceFiles( defaultSourceFiles, ancestorSourceFiles, false );
632 
633                                        if ( ancestorSourceFiles.isFinal() )
634                                        {
635                                            finalAncestor = true;
636                                        }
637                                    }
638                                }
639 
640                                if ( !finalAncestor )
641                                {
642                                    implementation.getAny().add(
643                                        new ObjectFactory().createSourceFiles( defaultSourceFiles ) );
644 
645                                }
646                            }
647                        }
648                    }
649 
650                    for ( final Map.Entry<Implementation, SourceFilesType> e : userSourceFiles.entrySet() )
651                    {
652                        this.overwriteSourceFiles(
653                            e.getValue(), this.getDefaultSourceFilesType( context, modules, e.getKey() ), true );
654 
655                    }
656 
657                    imodel = new InheritanceModel( modules );
658 
659                    for ( int i = 0, s0 = modules.getImplementations().getImplementation().size(); i < s0; i++ )
660                    {
661                        final Implementation implementation = modules.getImplementations().getImplementation().get( i );
662                        final SourceFilesType sourceFilesType = implementation.getAnyObject( SourceFilesType.class );
663 
664                        if ( sourceFilesType != null && !userSourceFiles.containsKey( implementation ) )
665                        {
666                            boolean override = false;
667 
668                            final Set<InheritanceModel.Node<JAXBElement<?>>> sourceFilesNodes =
669                                imodel.getJaxbElementNodes( implementation.getIdentifier(), SOURCE_FILES_QNAME );
670 
671                            for ( final InheritanceModel.Node<JAXBElement<?>> e : sourceFilesNodes )
672                            {
673                                if ( !e.getOverriddenNodes().isEmpty() )
674                                {
675                                    override = true;
676                                    break;
677                                }
678                            }
679 
680                            if ( override )
681                            {
682                                sourceFilesType.setOverride( override );
683                            }
684                        }
685                    }
686                }
687 
688                if ( classpathModule != null )
689                {
690                    modules.getModule().remove( classpathModule );
691                }
692            }
693        }
694        else if ( context.isLoggable( Level.FINER ) )
695        {
696            context.log( Level.FINER, getMessage( "disabled", this.getClass().getSimpleName(),
697                                                  model.getIdentifier() ), null );
698 
699        }
700 
701        return provided;
702    }
703 
704    /**
705     * Gets the default source code file location for a given specification.
706     * <p>If the specification provides a Java type name, this method returns a Java source code file location based on
707     * that Java type name.</p>
708     *
709     * @param context The context to get the default location with.
710     * @param modules The model to get the default location with.
711     * @param specification The specification to get the default location for.
712     *
713     * @return The default location for {@code specification} or {@code null}.
714     *
715     * @throws NullPointerExeption if {@code context}, {@code modules} or {@code specification} is {@code null}.
716     *
717     * @see #getDefaultSourceFilesType(org.jomc.modlet.ModelContext, org.jomc.model.Modules, org.jomc.model.Specification)
718     * @see SourceFileType#getLocation()
719     * @see Specification#getJavaTypeName()
720     * @since 1.6
721     */
722    protected String getDefaultSourceFileLocation( final ModelContext context, final Modules modules,
723                                                   final Specification specification )
724    {
725        if ( context == null )
726        {
727            throw new NullPointerException( "context" );
728        }
729        if ( modules == null )
730        {
731            throw new NullPointerException( "modules" );
732        }
733        if ( specification == null )
734        {
735            throw new NullPointerException( "specification" );
736        }
737 
738        String location = null;
739 
740        try
741        {
742            if ( specification.getJavaTypeName() != null )
743            {
744                location = specification.getJavaTypeName().getQualifiedName().replace( '.', '/' ) + ".java";
745            }
746        }
747        catch ( final ModelObjectException e )
748        {
749            context.log( Level.WARNING, getMessage( e ), null );
750        }
751 
752        return location;
753    }
754 
755    /**
756     * Gets the default source code file location for a given implementation.
757     * <p>If the implementation provides a Java type name, this method returns a Java source code file location based on
758     * that Java type name.</p>
759     *
760     * @param context The context to get the default location with.
761     * @param modules The model to get the default location with.
762     * @param implementation The implementation to get the default location for.
763     *
764     * @return The default location for {@code implementation} or {@code null}.
765     *
766     * @throws NullPointerExeption if {@code context}, {@code modules} or {@code implementation} is {@code null}.
767     *
768     * @see #getDefaultSourceFilesType(org.jomc.modlet.ModelContext, org.jomc.model.Modules, org.jomc.model.Implementation)
769     * @see SourceFileType#getLocation()
770     * @see Implementation#getJavaTypeName()
771     * @since 1.6
772     */
773    protected String getDefaultSourceFileLocation( final ModelContext context, final Modules modules,
774                                                   final Implementation implementation )
775    {
776        if ( context == null )
777        {
778            throw new NullPointerException( "context" );
779        }
780        if ( modules == null )
781        {
782            throw new NullPointerException( "modules" );
783        }
784        if ( implementation == null )
785        {
786            throw new NullPointerException( "implementation" );
787        }
788 
789        String location = null;
790 
791        try
792        {
793            if ( implementation.getJavaTypeName() != null )
794            {
795                location = implementation.getJavaTypeName().getQualifiedName().replace( '.', '/' ) + ".java";
796            }
797        }
798        catch ( final ModelObjectException e )
799        {
800            context.log( Level.WARNING, getMessage( e ), null );
801        }
802 
803        return location;
804    }
805 
806    /**
807     * Gets the default source section name for a given specification.
808     * <p>If the specification provides a Java type name, this method returns a section name based on that Java type
809     * name.</p>
810     *
811     * @param context The context to get the default section name with.
812     * @param modules The model to get the default section name with.
813     * @param specification The specification to get the default section name for.
814     *
815     * @return The default source section name for {@code specification} or {@code null}.
816     *
817     * @throws NullPointerExeption if {@code context}, {@code modules} or {@code specification} is {@code null}.
818     *
819     * @see #getDefaultSourceFilesType(org.jomc.modlet.ModelContext, org.jomc.model.Modules, org.jomc.model.Specification)
820     * @see SourceSectionType#getName()
821     * @see Specification#getJavaTypeName()
822     * @since 1.6
823     */
824    protected String getDefaultSourceSectionName( final ModelContext context, final Modules modules,
825                                                  final Specification specification )
826    {
827        if ( context == null )
828        {
829            throw new NullPointerException( "context" );
830        }
831        if ( modules == null )
832        {
833            throw new NullPointerException( "modules" );
834        }
835        if ( specification == null )
836        {
837            throw new NullPointerException( "specification" );
838        }
839 
840        String sectionName = null;
841 
842        try
843        {
844            final JavaTypeName javaTypeName = specification.getJavaTypeName();
845 
846            if ( javaTypeName != null )
847            {
848                sectionName = javaTypeName.getName( false );
849            }
850        }
851        catch ( final ModelObjectException e )
852        {
853            context.log( Level.WARNING, getMessage( e ), null );
854        }
855 
856        return sectionName;
857    }
858 
859    /**
860     * Gets the default source section name for a given implementation.
861     * <p>If the implementation provides a Java type name, this method returns a section name based that Java type
862     * name.</p>
863     *
864     * @param context The context to get the default section name with.
865     * @param modules The model to get the default section name with.
866     * @param implementation The implementation to get the default section name for.
867     *
868     * @return The default source section name for {@code implementation} or {@code null}.
869     *
870     * @throws NullPointerExeption if {@code context}, {@code modules} or {@code implementation} is {@code null}.
871     *
872     * @see #getDefaultSourceFilesType(org.jomc.modlet.ModelContext, org.jomc.model.Modules, org.jomc.model.Implementation)
873     * @see SourceSectionType#getName()
874     * @see Implementation#getJavaTypeName()
875     * @since 1.6
876     */
877    protected String getDefaultSourceSectionName( final ModelContext context, final Modules modules,
878                                                  final Implementation implementation )
879    {
880        if ( context == null )
881        {
882            throw new NullPointerException( "context" );
883        }
884        if ( modules == null )
885        {
886            throw new NullPointerException( "modules" );
887        }
888        if ( implementation == null )
889        {
890            throw new NullPointerException( "implementation" );
891        }
892 
893        String sectionName = null;
894 
895        try
896        {
897            final JavaTypeName javaTypeName = implementation.getJavaTypeName();
898 
899            if ( javaTypeName != null )
900            {
901                sectionName = javaTypeName.getName( false );
902            }
903        }
904        catch ( final ModelObjectException e )
905        {
906            context.log( Level.WARNING, getMessage( e ), null );
907        }
908 
909        return sectionName;
910    }
911 
912    /**
913     * Creates a new default source files model for a given specification.
914     *
915     * @param context The context to create a new default source files model with.
916     * @param modules The model to create a new default source files model with.
917     * @param specification The specification to create a new default source files model for.
918     *
919     * @return A new default source files model for {@code specification}.
920     *
921     * @throws NullPointerExeption if {@code context}, {@code modules} or {@code specification} is {@code null}.
922     *
923     * @see #getDefaultSourceFileLocation(org.jomc.modlet.ModelContext, org.jomc.model.Modules, org.jomc.model.Specification)
924     * @see #getDefaultSourceSectionName(org.jomc.modlet.ModelContext, org.jomc.model.Modules, org.jomc.model.Specification)
925     * @since 1.6
926     */
927    protected SourceFilesType getDefaultSourceFilesType( final ModelContext context, final Modules modules,
928                                                         final Specification specification )
929    {
930        if ( context == null )
931        {
932            throw new NullPointerException( "context" );
933        }
934        if ( modules == null )
935        {
936            throw new NullPointerException( "modules" );
937        }
938        if ( specification == null )
939        {
940            throw new NullPointerException( "specification" );
941        }
942 
943        String contextHeadComment = this.getHeadComment();
944        if ( ( DEFAULT_HEAD_COMMENT != null
945               ? DEFAULT_HEAD_COMMENT.equals( contextHeadComment )
946               : contextHeadComment == null )
947             && context.getAttribute( HEAD_COMMENT_ATTRIBUTE_NAME ) instanceof String )
948        {
949            contextHeadComment = (String) context.getAttribute( HEAD_COMMENT_ATTRIBUTE_NAME );
950        }
951 
952        if ( contextHeadComment != null && contextHeadComment.length() == 0 )
953        {
954            contextHeadComment = null;
955        }
956 
957        String contextTailComment = this.getTailComment();
958        if ( ( DEFAULT_TAIL_COMMENT != null
959               ? DEFAULT_TAIL_COMMENT.equals( contextTailComment )
960               : contextTailComment == null )
961             && context.getAttribute( TAIL_COMMENT_ATTRIBUTE_NAME ) instanceof String )
962        {
963            contextTailComment = (String) context.getAttribute( TAIL_COMMENT_ATTRIBUTE_NAME );
964        }
965 
966        if ( contextTailComment != null && contextTailComment.length() == 0 )
967        {
968            contextTailComment = null;
969        }
970 
971        final Set<String> uniqueSectionNames = new HashSet<String>( 16 );
972        final Set<String> sectionNames = new HashSet<String>( 16 );
973        sectionNames.add( LICENSE_SECTION_NAME );
974        sectionNames.add( ANNOTATIONS_SECTION_NAME );
975        sectionNames.add( DOCUMENTATION_SECTION_NAME );
976 
977        final SourceFilesType sourceFilesType = new SourceFilesType();
978        final SourceFileType sourceFileType = new SourceFileType();
979        sourceFilesType.getSourceFile().add( sourceFileType );
980 
981        sourceFileType.setIdentifier( "Default" );
982        sourceFileType.setLocation( this.getDefaultSourceFileLocation( context, modules, specification ) );
983 
984        sourceFileType.setTemplate( SPECIFICATION_TEMPLATE );
985        sourceFileType.setHeadComment( contextHeadComment );
986        sourceFileType.setTailComment( contextTailComment );
987        sourceFileType.setSourceSections( new SourceSectionsType() );
988 
989        SourceSectionType s = new SourceSectionType();
990        s.setName( LICENSE_SECTION_NAME );
991        s.setHeadTemplate( SPECIFICATION_LICENSE_TEMPLATE );
992        s.setOptional( true );
993        sourceFileType.getSourceSections().getSourceSection().add( s );
994 
995        s = new SourceSectionType();
996        s.setName( ANNOTATIONS_SECTION_NAME );
997        s.setHeadTemplate( SPECIFICATION_ANNOTATIONS_TEMPLATE );
998        sourceFileType.getSourceSections().getSourceSection().add( s );
999 
1000        s = new SourceSectionType();
1001        s.setName( DOCUMENTATION_SECTION_NAME );
1002        s.setHeadTemplate( SPECIFICATION_DOCUMENTATION_TEMPLATE );
1003        s.setOptional( true );
1004        sourceFileType.getSourceSections().getSourceSection().add( s );
1005 
1006        final String sectionName = this.getDefaultSourceSectionName( context, modules, specification );
1007 
1008        if ( sectionName != null )
1009        {
1010            if ( sectionNames.add( sectionName ) )
1011            {
1012                s = new SourceSectionType();
1013                s.setName( sectionName );
1014                s.setIndentationLevel( 1 );
1015                s.setEditable( true );
1016                sourceFileType.getSourceSections().getSourceSection().add( s );
1017            }
1018            else if ( uniqueSectionNames.add( sectionName ) )
1019            {
1020                final Module module = modules.getModuleOfSpecification( specification.getIdentifier() );
1021                context.log( Level.WARNING, getMessage( "specificationSectionNameUniqueness",
1022                                                        specification.getIdentifier(),
1023                                                        module.getName(),
1024                                                        sourceFileType.getIdentifier(),
1025                                                        sectionName ),
1026                             null );
1027 
1028            }
1029        }
1030 
1031        return sourceFilesType;
1032    }
1033 
1034    /**
1035     * Creates a new default source files model for a given implementation.
1036     *
1037     * @param context The context to create a new default source files model with.
1038     * @param modules The model to create a new default source files model with.
1039     * @param implementation The implementation to create a new default source files model for.
1040     *
1041     * @return A new default source files model for {@code implementation}.
1042     *
1043     * @throws NullPointerExeption if {@code context}, {@code modules} or {@code implementation} is {@code null}.
1044     *
1045     * @see #getDefaultSourceFileLocation(org.jomc.modlet.ModelContext, org.jomc.model.Modules, org.jomc.model.Implementation)
1046     * @see #getDefaultSourceSectionName(org.jomc.modlet.ModelContext, org.jomc.model.Modules, org.jomc.model.Implementation)
1047     * @since 1.6
1048     */
1049    protected SourceFilesType getDefaultSourceFilesType( final ModelContext context, final Modules modules,
1050                                                         final Implementation implementation )
1051    {
1052        if ( context == null )
1053        {
1054            throw new NullPointerException( "context" );
1055        }
1056        if ( modules == null )
1057        {
1058            throw new NullPointerException( "modules" );
1059        }
1060        if ( implementation == null )
1061        {
1062            throw new NullPointerException( "implementation" );
1063        }
1064 
1065        String contextHeadComment = this.getHeadComment();
1066        if ( ( DEFAULT_HEAD_COMMENT != null
1067               ? DEFAULT_HEAD_COMMENT.equals( contextHeadComment )
1068               : contextHeadComment == null )
1069             && context.getAttribute( HEAD_COMMENT_ATTRIBUTE_NAME ) instanceof String )
1070        {
1071            contextHeadComment = (String) context.getAttribute( HEAD_COMMENT_ATTRIBUTE_NAME );
1072        }
1073 
1074        if ( contextHeadComment != null && contextHeadComment.length() == 0 )
1075        {
1076            contextHeadComment = null;
1077        }
1078 
1079        String contextTailComment = this.getTailComment();
1080        if ( ( DEFAULT_TAIL_COMMENT != null
1081               ? DEFAULT_TAIL_COMMENT.equals( contextTailComment )
1082               : contextTailComment == null )
1083             && context.getAttribute( TAIL_COMMENT_ATTRIBUTE_NAME ) instanceof String )
1084        {
1085            contextTailComment = (String) context.getAttribute( TAIL_COMMENT_ATTRIBUTE_NAME );
1086        }
1087 
1088        if ( contextTailComment != null && contextTailComment.length() == 0 )
1089        {
1090            contextTailComment = null;
1091        }
1092 
1093        final Set<String> uniqueSectionNames = new HashSet<String>( 16 );
1094        final ArrayList<String> sectionNames = new ArrayList<String>( 16 );
1095        sectionNames.add( LICENSE_SECTION_NAME );
1096        sectionNames.add( ANNOTATIONS_SECTION_NAME );
1097        sectionNames.add( DOCUMENTATION_SECTION_NAME );
1098        sectionNames.add( CONSTRUCTORS_SECTION_NAME );
1099        sectionNames.add( DEFAULT_CONSTRUCTOR_SECTION_NAME );
1100        sectionNames.add( DEPENDENCIES_SECTION_NAME );
1101        sectionNames.add( PROPERTIES_SECTION_NAME );
1102        sectionNames.add( MESSAGES_SECTION_NAME );
1103 
1104        final SourceFilesType sourceFilesType = new SourceFilesType();
1105        final SourceFileType sourceFileType = new SourceFileType();
1106        sourceFilesType.getSourceFile().add( sourceFileType );
1107 
1108        final Specifications specifications = modules.getSpecifications( implementation.getIdentifier() );
1109        final Dependencies dependencies = modules.getDependencies( implementation.getIdentifier() );
1110        final Messages messages = modules.getMessages( implementation.getIdentifier() );
1111        final Properties properties = modules.getProperties( implementation.getIdentifier() );
1112 
1113        sourceFileType.setIdentifier( "Default" );
1114        sourceFileType.setLocation( this.getDefaultSourceFileLocation( context, modules, implementation ) );
1115 
1116        sourceFileType.setTemplate( IMPLEMENTATION_TEMPLATE );
1117        sourceFileType.setHeadComment( contextHeadComment );
1118        sourceFileType.setTailComment( contextTailComment );
1119        sourceFileType.setSourceSections( new SourceSectionsType() );
1120 
1121        SourceSectionType s = new SourceSectionType();
1122        s.setName( LICENSE_SECTION_NAME );
1123        s.setHeadTemplate( IMPLEMENTATION_LICENSE_TEMPLATE );
1124        s.setOptional( true );
1125        sourceFileType.getSourceSections().getSourceSection().add( s );
1126 
1127        s = new SourceSectionType();
1128        s.setName( ANNOTATIONS_SECTION_NAME );
1129        s.setHeadTemplate( IMPLEMENTATION_ANNOTATIONS_TEMPLATE );
1130        sourceFileType.getSourceSections().getSourceSection().add( s );
1131 
1132        s = new SourceSectionType();
1133        s.setName( DOCUMENTATION_SECTION_NAME );
1134        s.setHeadTemplate( IMPLEMENTATION_DOCUMENTATION_TEMPLATE );
1135        s.setOptional( true );
1136        sourceFileType.getSourceSections().getSourceSection().add( s );
1137 
1138        if ( specifications != null )
1139        {
1140            sectionNames.ensureCapacity( sectionNames.size() + specifications.getSpecification().size() );
1141 
1142            for ( final Specification specification : specifications.getSpecification() )
1143            {
1144                final String sectionName = this.getDefaultSourceSectionName( context, modules, specification );
1145 
1146                if ( sectionName != null )
1147                {
1148                    if ( !sectionNames.contains( sectionName ) )
1149                    {
1150                        sectionNames.add( sectionName );
1151 
1152                        s = new SourceSectionType();
1153                        s.setName( sectionName );
1154                        s.setIndentationLevel( 1 );
1155                        s.setEditable( true );
1156                        sourceFileType.getSourceSections().getSourceSection().add( s );
1157                    }
1158                    else if ( uniqueSectionNames.add( sectionName ) )
1159                    {
1160                        final Module module = modules.getModuleOfImplementation( implementation.getIdentifier() );
1161                        context.log( Level.WARNING, getMessage( "implementationSectionNameUniqueness",
1162                                                                implementation.getIdentifier(),
1163                                                                module.getName(),
1164                                                                sourceFileType.getIdentifier(),
1165                                                                sectionName ),
1166                                     null );
1167 
1168                    }
1169                }
1170            }
1171        }
1172 
1173        final String sectionName = this.getDefaultSourceSectionName( context, modules, implementation );
1174 
1175        if ( sectionName != null )
1176        {
1177            if ( !sectionNames.contains( sectionName ) )
1178            {
1179                sectionNames.add( sectionName );
1180 
1181                s = new SourceSectionType();
1182                s.setName( sectionName );
1183                s.setIndentationLevel( 1 );
1184                s.setEditable( true );
1185                sourceFileType.getSourceSections().getSourceSection().add( s );
1186            }
1187            else if ( uniqueSectionNames.add( sectionName ) )
1188            {
1189                final Module module = modules.getModuleOfImplementation( implementation.getIdentifier() );
1190                context.log( Level.WARNING, getMessage( "implementationSectionNameUniqueness",
1191                                                        implementation.getIdentifier(),
1192                                                        module.getName(),
1193                                                        sourceFileType.getIdentifier(),
1194                                                        sectionName ),
1195                             null );
1196 
1197            }
1198        }
1199 
1200        s = new SourceSectionType();
1201        s.setName( CONSTRUCTORS_SECTION_NAME );
1202        s.setIndentationLevel( 1 );
1203        s.setHeadTemplate( CONSTRUCTORS_HEAD_TEMPLATE );
1204        s.setTailTemplate( CONSTRUCTORS_TAIL_TEMPLATE );
1205        s.setOptional( specifications == null || ( specifications.getSpecification().isEmpty()
1206                                                   && specifications.getReference().isEmpty() ) );
1207 
1208        s.setSourceSections( new SourceSectionsType() );
1209        sourceFileType.getSourceSections().getSourceSection().add( s );
1210 
1211        final SourceSectionType defaultCtor = new SourceSectionType();
1212        defaultCtor.setName( DEFAULT_CONSTRUCTOR_SECTION_NAME );
1213        defaultCtor.setIndentationLevel( 2 );
1214        defaultCtor.setHeadTemplate( DEFAULT_CONSTRUCTOR_TEMPLATE );
1215        defaultCtor.setEditable( true );
1216        s.getSourceSections().getSourceSection().add( defaultCtor );
1217 
1218        s = new SourceSectionType();
1219        s.setName( DEPENDENCIES_SECTION_NAME );
1220        s.setIndentationLevel( 1 );
1221        s.setHeadTemplate( DEPENDENCIES_TEMPLATE );
1222        s.setOptional( dependencies == null || dependencies.getDependency().isEmpty() );
1223        sourceFileType.getSourceSections().getSourceSection().add( s );
1224 
1225        s = new SourceSectionType();
1226        s.setName( PROPERTIES_SECTION_NAME );
1227        s.setIndentationLevel( 1 );
1228        s.setHeadTemplate( PROPERTIES_TEMPLATE );
1229        s.setOptional( properties == null || properties.getProperty().isEmpty() );
1230        sourceFileType.getSourceSections().getSourceSection().add( s );
1231 
1232        s = new SourceSectionType();
1233        s.setName( MESSAGES_SECTION_NAME );
1234        s.setIndentationLevel( 1 );
1235        s.setHeadTemplate( MESSAGES_TEMPLATE );
1236        s.setOptional( messages == null || messages.getMessage().isEmpty() );
1237        sourceFileType.getSourceSections().getSourceSection().add( s );
1238 
1239        return sourceFilesType;
1240    }
1241 
1242    /**
1243     * Overwrites a list of source code files with another list of source code files.
1244     *
1245     * @param targetSourceFiles The list to overwrite.
1246     * @param sourceSourceFiles The list to overwrite with.
1247     * @param preserveExisting {@code true}, to preserve existing attributes of source code files and sections;
1248     * {@code false}, to overwrite existing attributes of source code files and sections.
1249     *
1250     * @throws NullPointerException if {@code targetSourceFiles} or {@code sourceSourceFiles} is {@code null}.
1251     */
1252    private void overwriteSourceFiles( final SourceFilesType targetSourceFiles, final SourceFilesType sourceSourceFiles,
1253                                       final boolean preserveExisting )
1254    {
1255        if ( targetSourceFiles == null )
1256        {
1257            throw new NullPointerException( "targetSourceFiles" );
1258        }
1259        if ( sourceSourceFiles == null )
1260        {
1261            throw new NullPointerException( "sourceSourceFiles" );
1262        }
1263 
1264        try
1265        {
1266            for ( final SourceFileType s : sourceSourceFiles.getSourceFile() )
1267            {
1268                final SourceFileType targetSourceFile = targetSourceFiles.getSourceFile( s.getIdentifier() );
1269 
1270                if ( targetSourceFile != null )
1271                {
1272                    this.overwriteSourceFile( targetSourceFile, s, preserveExisting );
1273                }
1274            }
1275        }
1276        catch ( final NoSuchFieldException e )
1277        {
1278            throw new AssertionError( e );
1279        }
1280    }
1281 
1282    /**
1283     * Overwrites a source code file with another source code file.
1284     *
1285     * @param targetSourceFile The source code file to overwrite.
1286     * @param sourceSourceFile The source code file to overwrite with.
1287     * @param preserveExisting {@code true}, to preserve existing attributes of the given source code file and sections;
1288     * {@code false}, to overwrite existing attributes of the given source code file and sections.
1289     *
1290     * @throws NullPointerException if {@code targetSourceFile} or {@code sourceSourceFile} is {@code null}.
1291     */
1292    private void overwriteSourceFile( final SourceFileType targetSourceFile, final SourceFileType sourceSourceFile,
1293                                      final boolean preserveExisting )
1294        throws NoSuchFieldException
1295    {
1296        if ( targetSourceFile == null )
1297        {
1298            throw new NullPointerException( "targetSourceFile" );
1299        }
1300        if ( sourceSourceFile == null )
1301        {
1302            throw new NullPointerException( "sourceSourceFile" );
1303        }
1304 
1305        if ( !preserveExisting )
1306        {
1307            targetSourceFile.setIdentifier( sourceSourceFile.getIdentifier() );
1308            targetSourceFile.setLocation( sourceSourceFile.getLocation() );
1309            targetSourceFile.setTemplate( sourceSourceFile.getTemplate() );
1310            targetSourceFile.setHeadComment( sourceSourceFile.getHeadComment() );
1311            targetSourceFile.setTailComment( sourceSourceFile.getTailComment() );
1312 
1313            if ( isFieldSet( sourceSourceFile, "_final" ) )
1314            {
1315                targetSourceFile.setFinal( sourceSourceFile.isFinal() );
1316            }
1317            if ( isFieldSet( sourceSourceFile, "modelVersion" ) )
1318            {
1319                targetSourceFile.setModelVersion( sourceSourceFile.getModelVersion() );
1320            }
1321            if ( isFieldSet( sourceSourceFile, "override" ) )
1322            {
1323                targetSourceFile.setOverride( sourceSourceFile.isOverride() );
1324            }
1325        }
1326 
1327        if ( sourceSourceFile.getSourceSections() != null )
1328        {
1329            if ( targetSourceFile.getSourceSections() == null )
1330            {
1331                targetSourceFile.setSourceSections( new SourceSectionsType() );
1332            }
1333 
1334            this.overwriteSourceSections( targetSourceFile.getSourceSections(), sourceSourceFile.getSourceSections(),
1335                                          preserveExisting );
1336 
1337        }
1338    }
1339 
1340    /**
1341     * Overwrites source code file sections with other source code file sections.
1342     *
1343     * @param targetSourceSections The source code file sections to overwrite.
1344     * @param sourceSourceSections The source code file sections to overwrite with.
1345     * @param preserveExisting {@code true}, to preserve existing attributes of the given source code file sections;
1346     * {@code false}, to overwrite existing attributes of the given source code file sections.
1347     *
1348     * @throws NullPointerException if {@code targetSourceSections} or {@code sourceSourceSections} is {@code null}.
1349     */
1350    private void overwriteSourceSections( final SourceSectionsType targetSourceSections,
1351                                          final SourceSectionsType sourceSourceSections,
1352                                          final boolean preserveExisting ) throws NoSuchFieldException
1353    {
1354        if ( targetSourceSections == null )
1355        {
1356            throw new NullPointerException( "targetSourceSections" );
1357        }
1358        if ( sourceSourceSections == null )
1359        {
1360            throw new NullPointerException( "sourceSourceSections" );
1361        }
1362 
1363        for ( final SourceSectionType sourceSection : sourceSourceSections.getSourceSection() )
1364        {
1365            SourceSectionType targetSection = null;
1366 
1367            for ( final SourceSectionType t : targetSourceSections.getSourceSection() )
1368            {
1369                if ( sourceSection.getName().equals( t.getName() ) )
1370                {
1371                    targetSection = t;
1372                    break;
1373                }
1374            }
1375 
1376            if ( targetSection != null )
1377            {
1378                if ( !preserveExisting )
1379                {
1380                    targetSection.setName( sourceSection.getName() );
1381                    targetSection.setHeadTemplate( sourceSection.getHeadTemplate() );
1382                    targetSection.setTailTemplate( sourceSection.getTailTemplate() );
1383 
1384                    if ( isFieldSet( sourceSection, "editable" ) )
1385                    {
1386                        targetSection.setEditable( sourceSection.isEditable() );
1387                    }
1388                    if ( isFieldSet( sourceSection, "indentationLevel" ) )
1389                    {
1390                        targetSection.setIndentationLevel( sourceSection.getIndentationLevel() );
1391                    }
1392                    if ( isFieldSet( sourceSection, "modelVersion" ) )
1393                    {
1394                        targetSection.setModelVersion( sourceSection.getModelVersion() );
1395                    }
1396                    if ( isFieldSet( sourceSection, "optional" ) )
1397                    {
1398                        targetSection.setOptional( sourceSection.isOptional() );
1399                    }
1400                }
1401            }
1402            else
1403            {
1404                targetSection = sourceSection.clone();
1405                targetSourceSections.getSourceSection().add( targetSection );
1406            }
1407 
1408            if ( sourceSection.getSourceSections() != null )
1409            {
1410                if ( targetSection.getSourceSections() == null )
1411                {
1412                    targetSection.setSourceSections( new SourceSectionsType() );
1413                }
1414 
1415                this.overwriteSourceSections( targetSection.getSourceSections(), sourceSection.getSourceSections(),
1416                                              preserveExisting );
1417            }
1418        }
1419    }
1420 
1421    private static boolean isFieldSet( final Object object, final String fieldName ) throws NoSuchFieldException
1422    {
1423        final Field field = getField( object.getClass(), fieldName );
1424 
1425        if ( field == null )
1426        {
1427            throw new NoSuchFieldException( fieldName );
1428        }
1429 
1430        final boolean accessible = field.isAccessible();
1431 
1432        try
1433        {
1434            field.setAccessible( true );
1435            return field.get( object ) != null;
1436        }
1437        catch ( final IllegalAccessException e )
1438        {
1439            throw new AssertionError( e );
1440        }
1441        finally
1442        {
1443            field.setAccessible( accessible );
1444        }
1445    }
1446 
1447    private static Field getField( final Class<?> clazz, final String name )
1448    {
1449        if ( clazz != null )
1450        {
1451            try
1452            {
1453                return clazz.getDeclaredField( name );
1454            }
1455            catch ( final NoSuchFieldException e )
1456            {
1457                return getField( clazz.getSuperclass(), name );
1458            }
1459        }
1460 
1461        return null;
1462    }
1463 
1464    private static String getMessage( final Throwable t )
1465    {
1466        return t != null
1467               ? t.getMessage() != null && t.getMessage().trim().length() > 0
1468                 ? t.getMessage()
1469                 : getMessage( t.getCause() )
1470               : null;
1471 
1472    }
1473 
1474    private static String getMessage( final String key, final Object... args )
1475    {
1476        return MessageFormat.format( ResourceBundle.getBundle(
1477            ToolsModelProvider.class.getName().replace( '.', '/' ), Locale.getDefault() ).getString( key ), args );
1478 
1479    }
1480 
1481}

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