EMMA Coverage Report (generated Mon Apr 22 06:35:53 CEST 2013)
[all classes][org.jomc.tools.modlet]

COVERAGE SUMMARY FOR SOURCE FILE [ToolsModelProvider.java]

nameclass, %method, %block, %line, %
ToolsModelProvider.java100% (1/1)65%  (13/20)70%  (981/1411)67%  (217.6/323)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ToolsModelProvider100% (1/1)65%  (13/20)70%  (981/1411)67%  (217.6/323)
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)
overwriteSourceFiles (SourceFilesType, SourceFilesType, boolean): void 100% (1/1)54%  (25/46)62%  (8/13)
getDefaultSourceFilesType (ModelContext, Modules, Specification): SourceFiles... 100% (1/1)83%  (139/168)84%  (36/43)
findModel (ModelContext, Model): Model 100% (1/1)88%  (339/387)84%  (64.7/77)
getDefaultSourceFilesType (ModelContext, Modules, Implementation): SourceFile... 100% (1/1)91%  (398/438)91%  (87/96)
<static initializer> 100% (1/1)100% (12/12)100% (3/3)
ToolsModelProvider (): void 100% (1/1)100% (3/3)100% (2/2)
getMessage (String, Object []): String 100% (1/1)100% (12/12)100% (1/1)
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)
setEnabled (Boolean): 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 4760 2013-04-08 17:56:26Z 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.List;
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.*;
67 
68/**
69 * Object management and configuration tools {@code ModelProvider} implementation.
70 *
71 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
72 * @version $JOMC: ToolsModelProvider.java 4760 2013-04-08 17:56:26Z schulte $
73 * @see ModelContext#findModel(java.lang.String)
74 * @since 1.2
75 */
76public class ToolsModelProvider implements ModelProvider
77{
78 
79    /** Constant for the qualified name of {@code source-files} elements. */
80    private static final QName SOURCE_FILES_QNAME = new ObjectFactory().createSourceFiles( null ).getName();
81 
82    /**
83     * Constant for the name of the model context attribute backing property {@code enabled}.
84     * @see #findModel(org.jomc.modlet.ModelContext, org.jomc.modlet.Model)
85     * @see ModelContext#getAttribute(java.lang.String)
86     */
87    public static final String ENABLED_ATTRIBUTE_NAME = "org.jomc.tools.modlet.ToolsModelProvider.enabledAttribute";
88 
89    /**
90     * Constant for the name of the system property controlling property {@code defaultEnabled}.
91     * @see #isDefaultEnabled()
92     */
93    private static final String DEFAULT_ENABLED_PROPERTY_NAME =
94        "org.jomc.tools.modlet.ToolsModelProvider.defaultEnabled";
95 
96    /**
97     * Default value of the flag indicating the provider is enabled by default.
98     * @see #isDefaultEnabled()
99     */
100    private static final Boolean DEFAULT_ENABLED = Boolean.TRUE;
101 
102    /** Flag indicating the provider is enabled by default. */
103    private static volatile Boolean defaultEnabled;
104 
105    /** Flag indicating the provider is enabled. */
106    private Boolean enabled;
107 
108    /**
109     * Constant for the name of the model context attribute backing property
110     * {@code modelObjectClasspathResolutionEnabled}.
111     *
112     * @see #findModel(org.jomc.modlet.ModelContext, org.jomc.modlet.Model)
113     * @see ModelContext#getAttribute(java.lang.String)
114     */
115    public static final String MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_ATTRIBUTE_NAME =
116        "org.jomc.tools.modlet.ToolsModelProvider.modelObjectClasspathResolutionEnabledAttribute";
117 
118    /**
119     * Constant for the name of the system property controlling property
120     * {@code defaultModelObjectClasspathResolutionEnabled}.
121     * @see #isDefaultModelObjectClasspathResolutionEnabled()
122     */
123    private static final String DEFAULT_MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_PROPERTY_NAME =
124        "org.jomc.tools.modlet.ToolsModelProvider.defaultModelObjectClasspathResolutionEnabled";
125 
126    /**
127     * Default value of the flag indicating model object class path resolution is enabled by default.
128     * @see #isDefaultModelObjectClasspathResolutionEnabled()
129     */
130    private static final Boolean DEFAULT_MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED = Boolean.TRUE;
131 
132    /** Flag indicating model object class path resolution is enabled by default. */
133    private static volatile Boolean defaultModelObjectClasspathResolutionEnabled;
134 
135    /** Flag indicating model object class path resolution is enabled. */
136    private Boolean modelObjectClasspathResolutionEnabled;
137 
138    /** Creates a new {@code ToolsModelProvider} instance. */
139    public ToolsModelProvider()
140    {
141        super();
142    }
143 
144    /**
145     * Gets a flag indicating the provider is enabled by default.
146     * <p>The default enabled flag is controlled by system property
147     * {@code org.jomc.tools.modlet.ToolsModelProvider.defaultEnabled} holding a value indicating the provider is
148     * enabled by default. If that property is not set, the {@code true} default is returned.</p>
149     *
150     * @return {@code true}, if the provider is enabled by default; {@code false}, if the provider is disabled by
151     * default.
152     *
153     * @see #setDefaultEnabled(java.lang.Boolean)
154     */
155    public static boolean isDefaultEnabled()
156    {
157        if ( defaultEnabled == null )
158        {
159            defaultEnabled = Boolean.valueOf( System.getProperty( DEFAULT_ENABLED_PROPERTY_NAME,
160                                                                  Boolean.toString( DEFAULT_ENABLED ) ) );
161 
162        }
163 
164        return defaultEnabled;
165    }
166 
167    /**
168     * Sets the flag indicating the provider is enabled by default.
169     *
170     * @param value The new value of the flag indicating the provider is enabled by default or {@code null}.
171     *
172     * @see #isDefaultEnabled()
173     */
174    public static void setDefaultEnabled( final Boolean value )
175    {
176        defaultEnabled = value;
177    }
178 
179    /**
180     * Gets a flag indicating the provider is enabled.
181     *
182     * @return {@code true}, if the provider is enabled; {@code false}, if the provider is disabled.
183     *
184     * @see #isDefaultEnabled()
185     * @see #setEnabled(java.lang.Boolean)
186     */
187    public final boolean isEnabled()
188    {
189        if ( this.enabled == null )
190        {
191            this.enabled = isDefaultEnabled();
192        }
193 
194        return this.enabled;
195    }
196 
197    /**
198     * Sets the flag indicating the provider is enabled.
199     *
200     * @param value The new value of the flag indicating the provider is enabled or {@code null}.
201     *
202     * @see #isEnabled()
203     */
204    public final void setEnabled( final Boolean value )
205    {
206        this.enabled = value;
207    }
208 
209    /**
210     * Gets a flag indicating model object class path resolution is enabled by default.
211     * <p>The model object class path resolution default enabled flag is controlled by system property
212     * {@code org.jomc.tools.modlet.ToolsModelProvider.defaultModelObjectClasspathResolutionEnabled} holding a value
213     * indicating model object class path resolution is enabled by default. If that property is not set, the
214     * {@code true} default is returned.</p>
215     *
216     * @return {@code true}, if model object class path resolution is enabled by default; {@code false}, if model object
217     * class path resolution is disabled by default.
218     *
219     * @see #setDefaultModelObjectClasspathResolutionEnabled(java.lang.Boolean)
220     */
221    public static boolean isDefaultModelObjectClasspathResolutionEnabled()
222    {
223        if ( defaultModelObjectClasspathResolutionEnabled == null )
224        {
225            defaultModelObjectClasspathResolutionEnabled = Boolean.valueOf( System.getProperty(
226                DEFAULT_MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_PROPERTY_NAME,
227                Boolean.toString( DEFAULT_MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED ) ) );
228 
229        }
230 
231        return defaultModelObjectClasspathResolutionEnabled;
232    }
233 
234    /**
235     * Sets the flag indicating model object class path resolution is enabled by default.
236     *
237     * @param value The new value of the flag indicating model object class path resolution is enabled by default or
238     * {@code null}.
239     *
240     * @see #isDefaultModelObjectClasspathResolutionEnabled()
241     */
242    public static void setDefaultModelObjectClasspathResolutionEnabled( final Boolean value )
243    {
244        defaultModelObjectClasspathResolutionEnabled = value;
245    }
246 
247    /**
248     * Gets a flag indicating model object class path resolution is enabled.
249     *
250     * @return {@code true}, if model object class path resolution is enabled; {@code false}, if model object class path
251     * resolution is disabled.
252     *
253     * @see #isDefaultModelObjectClasspathResolutionEnabled()
254     * @see #setModelObjectClasspathResolutionEnabled(java.lang.Boolean)
255     */
256    public final boolean isModelObjectClasspathResolutionEnabled()
257    {
258        if ( this.modelObjectClasspathResolutionEnabled == null )
259        {
260            this.modelObjectClasspathResolutionEnabled = isDefaultModelObjectClasspathResolutionEnabled();
261        }
262 
263        return this.modelObjectClasspathResolutionEnabled;
264    }
265 
266    /**
267     * Sets the flag indicating model object class path resolution is is enabled.
268     *
269     * @param value The new value of the flag indicating model object class path resolution is enabled or {@code null}.
270     *
271     * @see #isModelObjectClasspathResolutionEnabled()
272     */
273    public final void setModelObjectClasspathResolutionEnabled( final Boolean value )
274    {
275        this.modelObjectClasspathResolutionEnabled = value;
276    }
277 
278    /**
279     * {@inheritDoc}
280     *
281     * @see #isEnabled()
282     * @see #isModelObjectClasspathResolutionEnabled()
283     * @see #ENABLED_ATTRIBUTE_NAME
284     * @see #MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_ATTRIBUTE_NAME
285     */
286    public Model findModel( final ModelContext context, final Model model ) throws ModelException
287    {
288        if ( context == null )
289        {
290            throw new NullPointerException( "context" );
291        }
292        if ( model == null )
293        {
294            throw new NullPointerException( "model" );
295        }
296 
297        Model provided = null;
298 
299        boolean contextEnabled = this.isEnabled();
300        if ( DEFAULT_ENABLED == contextEnabled && context.getAttribute( ENABLED_ATTRIBUTE_NAME ) instanceof Boolean )
301        {
302            contextEnabled = (Boolean) context.getAttribute( ENABLED_ATTRIBUTE_NAME );
303        }
304 
305        boolean contextModelObjectClasspathResolutionEnabled = this.isModelObjectClasspathResolutionEnabled();
306        if ( contextModelObjectClasspathResolutionEnabled == DEFAULT_MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED
307             && context.getAttribute( MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_ATTRIBUTE_NAME ) instanceof Boolean )
308        {
309            contextModelObjectClasspathResolutionEnabled =
310                (Boolean) context.getAttribute( MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_ATTRIBUTE_NAME );
311 
312        }
313 
314        if ( contextEnabled )
315        {
316            provided = model.clone();
317            final Modules modules = ModelHelper.getModules( provided );
318 
319            if ( modules != null )
320            {
321                Module classpathModule = null;
322                if ( contextModelObjectClasspathResolutionEnabled )
323                {
324                    classpathModule = modules.getClasspathModule( Modules.getDefaultClasspathModuleName(),
325                                                                  context.getClassLoader() );
326 
327                    if ( classpathModule != null
328                         && modules.getModule( Modules.getDefaultClasspathModuleName() ) == null )
329                    {
330                        modules.getModule().add( classpathModule );
331                    }
332                    else
333                    {
334                        classpathModule = null;
335                    }
336                }
337 
338                if ( modules.getSpecifications() != null )
339                {
340                    for ( int i = 0, s0 = modules.getSpecifications().getSpecification().size(); i < s0; i++ )
341                    {
342                        final Specification specification = modules.getSpecifications().getSpecification().get( i );
343                        final SourceFileType sourceFileType = specification.getAnyObject( SourceFileType.class );
344                        final SourceFilesType sourceFilesType = specification.getAnyObject( SourceFilesType.class );
345 
346                        if ( sourceFileType == null && specification.isClassDeclaration() )
347                        {
348                            final SourceFilesType defaultSourceFiles =
349                                this.getDefaultSourceFilesType( context, modules, specification );
350 
351                            if ( sourceFilesType != null )
352                            {
353                                this.overwriteSourceFiles( sourceFilesType, defaultSourceFiles, true );
354                            }
355                            else
356                            {
357                                specification.getAny().add( new ObjectFactory().createSourceFiles(
358                                    this.getDefaultSourceFilesType( context, modules, specification ) ) );
359 
360                            }
361                        }
362                    }
363                }
364 
365                if ( modules.getImplementations() != null )
366                {
367                    final Map<Implementation, SourceFilesType> userSourceFiles =
368                        new HashMap<Implementation, SourceFilesType>();
369 
370                    InheritanceModel imodel = new InheritanceModel( modules );
371 
372                    for ( int i = 0, s0 = modules.getImplementations().getImplementation().size(); i < s0; i++ )
373                    {
374                        final Implementation implementation = modules.getImplementations().getImplementation().get( i );
375                        final SourceFileType sourceFileType = implementation.getAnyObject( SourceFileType.class );
376                        final SourceFilesType sourceFilesType = implementation.getAnyObject( SourceFilesType.class );
377 
378                        if ( sourceFileType == null )
379                        {
380                            if ( sourceFilesType != null )
381                            {
382                                userSourceFiles.put( implementation, sourceFilesType );
383                            }
384                            else if ( implementation.isClassDeclaration() )
385                            {
386                                final SourceFilesType defaultSourceFiles =
387                                    this.getDefaultSourceFilesType( context, modules, implementation );
388 
389                                boolean finalAncestor = false;
390 
391                                final Set<InheritanceModel.Node<JAXBElement<?>>> sourceFilesNodes =
392                                    imodel.getJaxbElementNodes( implementation.getIdentifier(), SOURCE_FILES_QNAME );
393 
394                                for ( final InheritanceModel.Node<JAXBElement<?>> sourceFilesNode : sourceFilesNodes )
395                                {
396                                    if ( sourceFilesNode.getModelObject().getValue() instanceof SourceFilesType )
397                                    {
398                                        final SourceFilesType ancestorSourceFiles =
399                                            (SourceFilesType) sourceFilesNode.getModelObject().getValue();
400 
401                                        this.overwriteSourceFiles( defaultSourceFiles, ancestorSourceFiles, false );
402 
403                                        if ( ancestorSourceFiles.isFinal() )
404                                        {
405                                            finalAncestor = true;
406                                        }
407                                    }
408                                }
409 
410                                if ( !finalAncestor )
411                                {
412                                    implementation.getAny().add(
413                                        new ObjectFactory().createSourceFiles( defaultSourceFiles ) );
414 
415                                }
416                            }
417                        }
418                    }
419 
420                    for ( final Map.Entry<Implementation, SourceFilesType> e : userSourceFiles.entrySet() )
421                    {
422                        this.overwriteSourceFiles(
423                            e.getValue(), this.getDefaultSourceFilesType( context, modules, e.getKey() ), true );
424 
425                    }
426 
427                    imodel = new InheritanceModel( modules );
428 
429                    for ( int i = 0, s0 = modules.getImplementations().getImplementation().size(); i < s0; i++ )
430                    {
431                        final Implementation implementation = modules.getImplementations().getImplementation().get( i );
432                        final SourceFilesType sourceFilesType = implementation.getAnyObject( SourceFilesType.class );
433 
434                        if ( sourceFilesType != null && !userSourceFiles.containsKey( implementation ) )
435                        {
436                            boolean override = false;
437 
438                            final Set<InheritanceModel.Node<JAXBElement<?>>> sourceFilesNodes =
439                                imodel.getJaxbElementNodes( implementation.getIdentifier(), SOURCE_FILES_QNAME );
440 
441                            for ( final InheritanceModel.Node<JAXBElement<?>> e : sourceFilesNodes )
442                            {
443                                if ( !e.getOverriddenNodes().isEmpty() )
444                                {
445                                    override = true;
446                                    break;
447                                }
448                            }
449 
450                            if ( override )
451                            {
452                                sourceFilesType.setOverride( override );
453                            }
454                        }
455                    }
456                }
457 
458                if ( classpathModule != null )
459                {
460                    modules.getModule().remove( classpathModule );
461                }
462            }
463        }
464        else if ( context.isLoggable( Level.FINER ) )
465        {
466            context.log( Level.FINER, getMessage( "disabled", this.getClass().getSimpleName(),
467                                                  model.getIdentifier() ), null );
468 
469        }
470 
471        return provided;
472    }
473 
474    /**
475     * Creates a new default source files model for a given specification.
476     *
477     * @param context The context to create a new default source files model with.
478     * @param modules The model to create a new default source files model with.
479     * @param specification The specification to create a new default source files model for.
480     *
481     * @return A new default source files model for {@code specification}.
482     *
483     * @throws NullPointerExeption if {@code context}, {@code modules} or {@code specification} is {@code null}.
484     */
485    private SourceFilesType getDefaultSourceFilesType( final ModelContext context, final Modules modules,
486                                                       final Specification specification )
487    {
488        if ( context == null )
489        {
490            throw new NullPointerException( "context" );
491        }
492        if ( modules == null )
493        {
494            throw new NullPointerException( "modules" );
495        }
496        if ( specification == null )
497        {
498            throw new NullPointerException( "specification" );
499        }
500 
501        final SourceFilesType sourceFilesType = new SourceFilesType();
502        final SourceFileType sourceFileType = new SourceFileType();
503        sourceFilesType.getSourceFile().add( sourceFileType );
504 
505        sourceFileType.setIdentifier( "Default" );
506 
507        try
508        {
509            if ( specification.getJavaTypeName() != null )
510            {
511                sourceFileType.setLocation(
512                    specification.getJavaTypeName().getQualifiedName().replace( '.', '/' ) + ".java" );
513 
514            }
515        }
516        catch ( final ModelObjectException e )
517        {
518            context.log( Level.WARNING, getMessage( e ), null );
519        }
520 
521        sourceFileType.setTemplate( SPECIFICATION_TEMPLATE );
522        sourceFileType.setHeadComment( "//" );
523        sourceFileType.setSourceSections( new SourceSectionsType() );
524 
525        SourceSectionType s = new SourceSectionType();
526        s.setName( LICENSE_SECTION_NAME );
527        s.setHeadTemplate( SPECIFICATION_LICENSE_TEMPLATE );
528        s.setOptional( true );
529        sourceFileType.getSourceSections().getSourceSection().add( s );
530 
531        s = new SourceSectionType();
532        s.setName( ANNOTATIONS_SECTION_NAME );
533        s.setHeadTemplate( SPECIFICATION_ANNOTATIONS_TEMPLATE );
534        sourceFileType.getSourceSections().getSourceSection().add( s );
535 
536        s = new SourceSectionType();
537        s.setName( DOCUMENTATION_SECTION_NAME );
538        s.setHeadTemplate( SPECIFICATION_DOCUMENTATION_TEMPLATE );
539        s.setOptional( true );
540        sourceFileType.getSourceSections().getSourceSection().add( s );
541 
542        try
543        {
544            final JavaTypeName javaTypeName = specification.getJavaTypeName();
545 
546            if ( javaTypeName != null )
547            {
548                s = new SourceSectionType();
549                s.setName( javaTypeName.getName( false ) );
550                s.setIndentationLevel( 1 );
551                s.setEditable( true );
552                sourceFileType.getSourceSections().getSourceSection().add( s );
553            }
554        }
555        catch ( final ModelObjectException e )
556        {
557            context.log( Level.WARNING, getMessage( e ), null );
558        }
559 
560        return sourceFilesType;
561    }
562 
563    /**
564     * Creates a new default source files model for a given implementation.
565     *
566     * @param context The context to create a new default source files model with.
567     * @param modules The model to create a new default source files model with.
568     * @param implementation The implementation to create a new default source files model for.
569     *
570     * @return A new default source files model for {@code implementation}.
571     *
572     * @throws NullPointerExeption if {@code context}, {@code modules} or {@code implementation} is {@code null}.
573     */
574    private SourceFilesType getDefaultSourceFilesType( final ModelContext context, final Modules modules,
575                                                       final Implementation implementation )
576    {
577        if ( context == null )
578        {
579            throw new NullPointerException( "context" );
580        }
581        if ( modules == null )
582        {
583            throw new NullPointerException( "modules" );
584        }
585        if ( implementation == null )
586        {
587            throw new NullPointerException( "implementation" );
588        }
589 
590        final SourceFilesType sourceFilesType = new SourceFilesType();
591        final SourceFileType sourceFileType = new SourceFileType();
592        sourceFilesType.getSourceFile().add( sourceFileType );
593 
594        final Specifications specifications = modules.getSpecifications( implementation.getIdentifier() );
595        final Dependencies dependencies = modules.getDependencies( implementation.getIdentifier() );
596        final Messages messages = modules.getMessages( implementation.getIdentifier() );
597        final Properties properties = modules.getProperties( implementation.getIdentifier() );
598 
599        sourceFileType.setIdentifier( "Default" );
600 
601        try
602        {
603            if ( implementation.getJavaTypeName() != null )
604            {
605                sourceFileType.setLocation(
606                    implementation.getJavaTypeName().getQualifiedName().replace( '.', '/' ) + ".java" );
607 
608            }
609        }
610        catch ( final ModelObjectException e )
611        {
612            context.log( Level.WARNING, getMessage( e ), null );
613        }
614 
615        sourceFileType.setTemplate( IMPLEMENTATION_TEMPLATE );
616        sourceFileType.setHeadComment( "//" );
617        sourceFileType.setSourceSections( new SourceSectionsType() );
618 
619        SourceSectionType s = new SourceSectionType();
620        s.setName( LICENSE_SECTION_NAME );
621        s.setHeadTemplate( IMPLEMENTATION_LICENSE_TEMPLATE );
622        s.setOptional( true );
623        sourceFileType.getSourceSections().getSourceSection().add( s );
624 
625        s = new SourceSectionType();
626        s.setName( ANNOTATIONS_SECTION_NAME );
627        s.setHeadTemplate( IMPLEMENTATION_ANNOTATIONS_TEMPLATE );
628        sourceFileType.getSourceSections().getSourceSection().add( s );
629 
630        s = new SourceSectionType();
631        s.setName( DOCUMENTATION_SECTION_NAME );
632        s.setHeadTemplate( IMPLEMENTATION_DOCUMENTATION_TEMPLATE );
633        s.setOptional( true );
634        sourceFileType.getSourceSections().getSourceSection().add( s );
635 
636        List<JavaTypeName> javaTypeNames = null;
637 
638        if ( specifications != null )
639        {
640            javaTypeNames = new ArrayList<JavaTypeName>( specifications.getSpecification().size() );
641 
642            for ( final Specification specification : specifications.getSpecification() )
643            {
644                try
645                {
646                    final JavaTypeName javaTypeName = specification.getJavaTypeName();
647 
648                    if ( javaTypeName != null && !javaTypeNames.contains( javaTypeName ) )
649                    {
650                        javaTypeNames.add( javaTypeName );
651                    }
652                }
653                catch ( final ModelObjectException e )
654                {
655                    context.log( Level.WARNING, getMessage( e ), null );
656                }
657            }
658 
659            for ( int i = 0, s0 = javaTypeNames.size(); i < s0; i++ )
660            {
661                s = new SourceSectionType();
662                s.setName( javaTypeNames.get( i ).getName( false ) );
663                s.setIndentationLevel( 1 );
664                s.setEditable( true );
665                sourceFileType.getSourceSections().getSourceSection().add( s );
666            }
667        }
668 
669        try
670        {
671            final JavaTypeName javaTypeName = implementation.getJavaTypeName();
672 
673            if ( javaTypeName != null && ( javaTypeNames == null || !javaTypeNames.contains( javaTypeName ) ) )
674            {
675                s = new SourceSectionType();
676                s.setName( javaTypeName.getName( false ) );
677                s.setIndentationLevel( 1 );
678                s.setEditable( true );
679                sourceFileType.getSourceSections().getSourceSection().add( s );
680            }
681        }
682        catch ( final ModelObjectException e )
683        {
684            context.log( Level.WARNING, getMessage( e ), null );
685        }
686 
687        s = new SourceSectionType();
688        s.setName( CONSTRUCTORS_SECTION_NAME );
689        s.setIndentationLevel( 1 );
690        s.setHeadTemplate( CONSTRUCTORS_HEAD_TEMPLATE );
691        s.setTailTemplate( CONSTRUCTORS_TAIL_TEMPLATE );
692        s.setOptional( specifications == null || ( specifications.getSpecification().isEmpty()
693                                                   && specifications.getReference().isEmpty() ) );
694 
695        s.setSourceSections( new SourceSectionsType() );
696        sourceFileType.getSourceSections().getSourceSection().add( s );
697 
698        final SourceSectionType defaultCtor = new SourceSectionType();
699        defaultCtor.setName( DEFAULT_CONSTRUCTOR_SECTION_NAME );
700        defaultCtor.setIndentationLevel( 2 );
701        defaultCtor.setHeadTemplate( DEFAULT_CONSTRUCTOR_TEMPLATE );
702        defaultCtor.setEditable( true );
703        s.getSourceSections().getSourceSection().add( defaultCtor );
704 
705        s = new SourceSectionType();
706        s.setName( DEPENDENCIES_SECTION_NAME );
707        s.setIndentationLevel( 1 );
708        s.setHeadTemplate( DEPENDENCIES_TEMPLATE );
709        s.setOptional( dependencies == null || dependencies.getDependency().isEmpty() );
710        sourceFileType.getSourceSections().getSourceSection().add( s );
711 
712        s = new SourceSectionType();
713        s.setName( PROPERTIES_SECTION_NAME );
714        s.setIndentationLevel( 1 );
715        s.setHeadTemplate( PROPERTIES_TEMPLATE );
716        s.setOptional( properties == null || properties.getProperty().isEmpty() );
717        sourceFileType.getSourceSections().getSourceSection().add( s );
718 
719        s = new SourceSectionType();
720        s.setName( MESSAGES_SECTION_NAME );
721        s.setIndentationLevel( 1 );
722        s.setHeadTemplate( MESSAGES_TEMPLATE );
723        s.setOptional( messages == null || messages.getMessage().isEmpty() );
724        sourceFileType.getSourceSections().getSourceSection().add( s );
725 
726        return sourceFilesType;
727    }
728 
729    /**
730     * Overwrites a list of source code files with another list of source code files.
731     *
732     * @param targetSourceFiles The list to overwrite.
733     * @param sourceSourceFiles The list to overwrite with.
734     * @param preserveExisting {@code true}, to preserve existing attributes of source code files and sections;
735     * {@code false}, to overwrite existing attributes of source code files and sections.
736     *
737     * @throws NullPointerException if {@code targetSourceFiles} or {@code sourceSourceFiles} is {@code null}.
738     */
739    private void overwriteSourceFiles( final SourceFilesType targetSourceFiles, final SourceFilesType sourceSourceFiles,
740                                       final boolean preserveExisting )
741    {
742        if ( targetSourceFiles == null )
743        {
744            throw new NullPointerException( "targetSourceFiles" );
745        }
746        if ( sourceSourceFiles == null )
747        {
748            throw new NullPointerException( "sourceSourceFiles" );
749        }
750 
751        try
752        {
753            for ( final SourceFileType s : sourceSourceFiles.getSourceFile() )
754            {
755                final SourceFileType targetSourceFile = targetSourceFiles.getSourceFile( s.getIdentifier() );
756 
757                if ( targetSourceFile != null )
758                {
759                    this.overwriteSourceFile( targetSourceFile, s, preserveExisting );
760                }
761            }
762        }
763        catch ( final NoSuchFieldException e )
764        {
765            throw new AssertionError( e );
766        }
767    }
768 
769    /**
770     * Overwrites a source code file with another source code file.
771     *
772     * @param targetSourceFile The source code file to overwrite.
773     * @param sourceSourceFile The source code file to overwrite with.
774     * @param preserveExisting {@code true}, to preserve existing attributes of the given source code file and sections;
775     * {@code false}, to overwrite existing attributes of the given source code file and sections.
776     *
777     * @throws NullPointerException if {@code targetSourceFile} or {@code sourceSourceFile} is {@code null}.
778     */
779    private void overwriteSourceFile( final SourceFileType targetSourceFile, final SourceFileType sourceSourceFile,
780                                      final boolean preserveExisting )
781        throws NoSuchFieldException
782    {
783        if ( targetSourceFile == null )
784        {
785            throw new NullPointerException( "targetSourceFile" );
786        }
787        if ( sourceSourceFile == null )
788        {
789            throw new NullPointerException( "sourceSourceFile" );
790        }
791 
792        if ( !preserveExisting )
793        {
794            targetSourceFile.setIdentifier( sourceSourceFile.getIdentifier() );
795            targetSourceFile.setLocation( sourceSourceFile.getLocation() );
796            targetSourceFile.setTemplate( sourceSourceFile.getTemplate() );
797            targetSourceFile.setHeadComment( sourceSourceFile.getHeadComment() );
798            targetSourceFile.setTailComment( sourceSourceFile.getTailComment() );
799 
800            if ( isFieldSet( sourceSourceFile, "_final" ) )
801            {
802                targetSourceFile.setFinal( sourceSourceFile.isFinal() );
803            }
804            if ( isFieldSet( sourceSourceFile, "modelVersion" ) )
805            {
806                targetSourceFile.setModelVersion( sourceSourceFile.getModelVersion() );
807            }
808            if ( isFieldSet( sourceSourceFile, "override" ) )
809            {
810                targetSourceFile.setOverride( sourceSourceFile.isOverride() );
811            }
812        }
813 
814        if ( sourceSourceFile.getSourceSections() != null )
815        {
816            if ( targetSourceFile.getSourceSections() == null )
817            {
818                targetSourceFile.setSourceSections( new SourceSectionsType() );
819            }
820 
821            this.overwriteSourceSections( targetSourceFile.getSourceSections(), sourceSourceFile.getSourceSections(),
822                                          preserveExisting );
823 
824        }
825    }
826 
827    /**
828     * Overwrites source code file sections with other source code file sections.
829     *
830     * @param targetSourceSections The source code file sections to overwrite.
831     * @param sourceSourceSections The source code file sections to overwrite with.
832     * @param preserveExisting {@code true}, to preserve existing attributes of the given source code file sections;
833     * {@code false}, to overwrite existing attributes of the given source code file sections.
834     *
835     * @throws NullPointerException if {@code targetSourceSections} or {@code sourceSourceSections} is {@code null}.
836     */
837    private void overwriteSourceSections( final SourceSectionsType targetSourceSections,
838                                          final SourceSectionsType sourceSourceSections,
839                                          final boolean preserveExisting ) throws NoSuchFieldException
840    {
841        if ( targetSourceSections == null )
842        {
843            throw new NullPointerException( "targetSourceSections" );
844        }
845        if ( sourceSourceSections == null )
846        {
847            throw new NullPointerException( "sourceSourceSections" );
848        }
849 
850        for ( final SourceSectionType sourceSection : sourceSourceSections.getSourceSection() )
851        {
852            SourceSectionType targetSection = null;
853 
854            for ( final SourceSectionType t : targetSourceSections.getSourceSection() )
855            {
856                if ( sourceSection.getName().equals( t.getName() ) )
857                {
858                    targetSection = t;
859                    break;
860                }
861            }
862 
863            if ( targetSection != null )
864            {
865                if ( !preserveExisting )
866                {
867                    targetSection.setName( sourceSection.getName() );
868                    targetSection.setHeadTemplate( sourceSection.getHeadTemplate() );
869                    targetSection.setTailTemplate( sourceSection.getTailTemplate() );
870 
871                    if ( isFieldSet( sourceSection, "editable" ) )
872                    {
873                        targetSection.setEditable( sourceSection.isEditable() );
874                    }
875                    if ( isFieldSet( sourceSection, "indentationLevel" ) )
876                    {
877                        targetSection.setIndentationLevel( sourceSection.getIndentationLevel() );
878                    }
879                    if ( isFieldSet( sourceSection, "modelVersion" ) )
880                    {
881                        targetSection.setModelVersion( sourceSection.getModelVersion() );
882                    }
883                    if ( isFieldSet( sourceSection, "optional" ) )
884                    {
885                        targetSection.setOptional( sourceSection.isOptional() );
886                    }
887                }
888            }
889            else
890            {
891                targetSection = sourceSection.clone();
892                targetSourceSections.getSourceSection().add( targetSection );
893            }
894 
895            if ( sourceSection.getSourceSections() != null )
896            {
897                if ( targetSection.getSourceSections() == null )
898                {
899                    targetSection.setSourceSections( new SourceSectionsType() );
900                }
901 
902                this.overwriteSourceSections( targetSection.getSourceSections(), sourceSection.getSourceSections(),
903                                              preserveExisting );
904            }
905        }
906    }
907 
908    private static boolean isFieldSet( final Object object, final String fieldName ) throws NoSuchFieldException
909    {
910        final Field field = getField( object.getClass(), fieldName );
911 
912        if ( field == null )
913        {
914            throw new NoSuchFieldException( fieldName );
915        }
916 
917        final boolean accessible = field.isAccessible();
918 
919        try
920        {
921            field.setAccessible( true );
922            return field.get( object ) != null;
923        }
924        catch ( final IllegalAccessException e )
925        {
926            throw new AssertionError( e );
927        }
928        finally
929        {
930            field.setAccessible( accessible );
931        }
932    }
933 
934    private static Field getField( final Class<?> clazz, final String name )
935    {
936        if ( clazz != null )
937        {
938            try
939            {
940                return clazz.getDeclaredField( name );
941            }
942            catch ( final NoSuchFieldException e )
943            {
944                return getField( clazz.getSuperclass(), name );
945            }
946        }
947 
948        return null;
949    }
950 
951    private static String getMessage( final Throwable t )
952    {
953        return t != null
954               ? t.getMessage() != null && t.getMessage().trim().length() > 0
955                 ? t.getMessage()
956                 : getMessage( t.getCause() )
957               : null;
958 
959    }
960 
961    private static String getMessage( final String key, final Object... args )
962    {
963        return MessageFormat.format( ResourceBundle.getBundle(
964            ToolsModelProvider.class.getName().replace( '.', '/' ), Locale.getDefault() ).getString( key ), args );
965 
966    }
967 
968}

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