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

COVERAGE SUMMARY FOR SOURCE FILE [ToolsModelProvider.java]

nameclass, %method, %block, %line, %
ToolsModelProvider.java100% (1/1)68%  (13/19)73%  (966/1328)70%  (209.9/301)

COVERAGE BREAKDOWN BY CLASS AND METHOD

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

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