001 /*
002 * Copyright (C) Christian Schulte, 2005-206
003 * All rights reserved.
004 *
005 * Redistribution and use in source and binary forms, with or without
006 * modification, are permitted provided that the following conditions
007 * are met:
008 *
009 * o Redistributions of source code must retain the above copyright
010 * notice, this list of conditions and the following disclaimer.
011 *
012 * o Redistributions in binary form must reproduce the above copyright
013 * notice, this list of conditions and the following disclaimer in
014 * the documentation and/or other materials provided with the
015 * distribution.
016 *
017 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
018 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
019 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
020 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
021 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
022 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
023 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
024 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
025 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
026 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
027 *
028 * $JOMC: ToolsModelProcessor.java 4201 2012-01-25 09:47:12Z schulte2005 $
029 *
030 */
031 package org.jomc.tools.modlet;
032
033 import java.lang.reflect.Field;
034 import java.text.MessageFormat;
035 import java.util.List;
036 import java.util.Locale;
037 import java.util.ResourceBundle;
038 import java.util.logging.Level;
039 import org.jomc.model.Dependencies;
040 import org.jomc.model.Implementation;
041 import org.jomc.model.Messages;
042 import org.jomc.model.Module;
043 import org.jomc.model.Modules;
044 import org.jomc.model.Properties;
045 import org.jomc.model.Specification;
046 import org.jomc.model.Specifications;
047 import org.jomc.model.modlet.ModelHelper;
048 import org.jomc.modlet.Model;
049 import org.jomc.modlet.ModelContext;
050 import org.jomc.modlet.ModelException;
051 import org.jomc.modlet.ModelProcessor;
052 import org.jomc.tools.JomcTool;
053 import org.jomc.tools.model.SourceFileType;
054 import org.jomc.tools.model.SourceFilesType;
055 import org.jomc.tools.model.SourceSectionType;
056 import org.jomc.tools.model.SourceSectionsType;
057 import static org.jomc.tools.modlet.ToolsModletConstants.*;
058
059 /**
060 * Object management and configuration tools {@code ModelProcessor} implementation.
061 *
062 * @author <a href="mailto:schulte2005@users.sourceforge.net">Christian Schulte</a>
063 * @version $JOMC: ToolsModelProcessor.java 4201 2012-01-25 09:47:12Z schulte2005 $
064 * @see ModelContext#processModel(org.jomc.modlet.Model)
065 * @since 1.2
066 */
067 public class ToolsModelProcessor implements ModelProcessor
068 {
069
070 /**
071 * Constant for the name of the model context attribute backing property {@code enabled}.
072 * @see #processModel(org.jomc.modlet.ModelContext, org.jomc.modlet.Model)
073 * @see ModelContext#getAttribute(java.lang.String)
074 */
075 public static final String ENABLED_ATTRIBUTE_NAME = "org.jomc.tools.modlet.ToolsModelProcessor.enabledAttribute";
076
077 /**
078 * Constant for the name of the system property controlling property {@code defaultEnabled}.
079 * @see #isDefaultEnabled()
080 */
081 private static final String DEFAULT_ENABLED_PROPERTY_NAME =
082 "org.jomc.tools.modlet.ToolsModelProcessor.defaultEnabled";
083
084 /**
085 * Default value of the flag indicating the processor is enabled by default.
086 * @see #isDefaultEnabled()
087 */
088 private static final Boolean DEFAULT_ENABLED = Boolean.TRUE;
089
090 /** Flag indicating the processor is enabled by default. */
091 private static volatile Boolean defaultEnabled;
092
093 /** Flag indicating the processor is enabled. */
094 private Boolean enabled;
095
096 /**
097 * Constant for the name of the model context attribute backing property
098 * {@code modelObjectClasspathResolutionEnabled}.
099 *
100 * @see #processModel(org.jomc.modlet.ModelContext, org.jomc.modlet.Model)
101 * @see ModelContext#getAttribute(java.lang.String)
102 */
103 public static final String MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_ATTRIBUTE_NAME =
104 "org.jomc.tools.modlet.ToolsModelProcessor.modelObjectClasspathResolutionEnabledAttribute";
105
106 /**
107 * Constant for the name of the system property controlling property
108 * {@code defaultModelObjectClasspathResolutionEnabled}.
109 * @see #isDefaultModelObjectClasspathResolutionEnabled()
110 */
111 private static final String DEFAULT_MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_PROPERTY_NAME =
112 "org.jomc.tools.modlet.ToolsModelProcessor.defaultModelObjectClasspathResolutionEnabled";
113
114 /**
115 * Default value of the flag indicating model object class path resolution is enabled by default.
116 * @see #isDefaultModelObjectClasspathResolutionEnabled()
117 */
118 private static final Boolean DEFAULT_MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED = Boolean.TRUE;
119
120 /** Flag indicating model object class path resolution is enabled by default. */
121 private static volatile Boolean defaultModelObjectClasspathResolutionEnabled;
122
123 /** Flag indicating model object class path resolution is enabled. */
124 private Boolean modelObjectClasspathResolutionEnabled;
125
126 /** Creates a new {@code ToolsModelProcessor} instance. */
127 public ToolsModelProcessor()
128 {
129 super();
130 }
131
132 /**
133 * Gets a flag indicating the processor is enabled by default.
134 * <p>The default enabled flag is controlled by system property
135 * {@code org.jomc.tools.modlet.ToolsModelProcessor.defaultEnabled} holding a value indicating the processor is
136 * enabled by default. If that property is not set, the {@code true} default is returned.</p>
137 *
138 * @return {@code true}, if the processor is enabled by default; {@code false}, if the processor is disabled by
139 * default.
140 *
141 * @see #setDefaultEnabled(java.lang.Boolean)
142 */
143 public static boolean isDefaultEnabled()
144 {
145 if ( defaultEnabled == null )
146 {
147 defaultEnabled = Boolean.valueOf( System.getProperty( DEFAULT_ENABLED_PROPERTY_NAME,
148 Boolean.toString( DEFAULT_ENABLED ) ) );
149
150 }
151
152 return defaultEnabled;
153 }
154
155 /**
156 * Sets the flag indicating the processor is enabled by default.
157 *
158 * @param value The new value of the flag indicating the processor is enabled by default or {@code null}.
159 *
160 * @see #isDefaultEnabled()
161 */
162 public static void setDefaultEnabled( final Boolean value )
163 {
164 defaultEnabled = value;
165 }
166
167 /**
168 * Gets a flag indicating the processor is enabled.
169 *
170 * @return {@code true}, if the processor is enabled; {@code false}, if the processor is disabled.
171 *
172 * @see #isDefaultEnabled()
173 * @see #setEnabled(java.lang.Boolean)
174 */
175 public final boolean isEnabled()
176 {
177 if ( this.enabled == null )
178 {
179 this.enabled = isDefaultEnabled();
180 }
181
182 return this.enabled;
183 }
184
185 /**
186 * Sets the flag indicating the processor is enabled.
187 *
188 * @param value The new value of the flag indicating the processor is enabled or {@code null}.
189 *
190 * @see #isEnabled()
191 */
192 public final void setEnabled( final Boolean value )
193 {
194 this.enabled = value;
195 }
196
197 /**
198 * Gets a flag indicating model object class path resolution is enabled by default.
199 * <p>The model object class path resolution default enabled flag is controlled by system property
200 * {@code org.jomc.tools.modlet.ToolsModelProcessor.defaultModelObjectClasspathResolutionEnabled} holding a value
201 * indicating model object class path resolution is enabled by default. If that property is not set, the
202 * {@code true} default is returned.</p>
203 *
204 * @return {@code true}, if model object class path resolution is enabled by default; {@code false}, if model object
205 * class path resolution is disabled by default.
206 *
207 * @see #setDefaultModelObjectClasspathResolutionEnabled(java.lang.Boolean)
208 */
209 public static boolean isDefaultModelObjectClasspathResolutionEnabled()
210 {
211 if ( defaultModelObjectClasspathResolutionEnabled == null )
212 {
213 defaultModelObjectClasspathResolutionEnabled = Boolean.valueOf( System.getProperty(
214 DEFAULT_MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_PROPERTY_NAME,
215 Boolean.toString( DEFAULT_MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED ) ) );
216
217 }
218
219 return defaultModelObjectClasspathResolutionEnabled;
220 }
221
222 /**
223 * Sets the flag indicating model object class path resolution is enabled by default.
224 *
225 * @param value The new value of the flag indicating model object class path resolution is enabled by default or
226 * {@code null}.
227 *
228 * @see #isDefaultModelObjectClasspathResolutionEnabled()
229 */
230 public static void setDefaultModelObjectClasspathResolutionEnabled( final Boolean value )
231 {
232 defaultModelObjectClasspathResolutionEnabled = value;
233 }
234
235 /**
236 * Gets a flag indicating model object class path resolution is enabled.
237 *
238 * @return {@code true}, if model object class path resolution is enabled; {@code false}, if model object class path
239 * resolution is disabled.
240 *
241 * @see #isDefaultModelObjectClasspathResolutionEnabled()
242 * @see #setModelObjectClasspathResolutionEnabled(java.lang.Boolean)
243 */
244 public final boolean isModelObjectClasspathResolutionEnabled()
245 {
246 if ( this.modelObjectClasspathResolutionEnabled == null )
247 {
248 this.modelObjectClasspathResolutionEnabled = isDefaultModelObjectClasspathResolutionEnabled();
249 }
250
251 return this.modelObjectClasspathResolutionEnabled;
252 }
253
254 /**
255 * Sets the flag indicating model object class path resolution is is enabled.
256 *
257 * @param value The new value of the flag indicating model object class path resolution is enabled or {@code null}.
258 *
259 * @see #isModelObjectClasspathResolutionEnabled()
260 */
261 public final void setModelObjectClasspathResolutionEnabled( final Boolean value )
262 {
263 this.modelObjectClasspathResolutionEnabled = value;
264 }
265
266 /**
267 * {@inheritDoc}
268 *
269 * @see #isEnabled()
270 * @see #isModelObjectClasspathResolutionEnabled()
271 * @see #ENABLED_ATTRIBUTE_NAME
272 * @see #MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_ATTRIBUTE_NAME
273 */
274 public Model processModel( final ModelContext context, final Model model ) throws ModelException
275 {
276 if ( context == null )
277 {
278 throw new NullPointerException( "context" );
279 }
280 if ( model == null )
281 {
282 throw new NullPointerException( "model" );
283 }
284
285 Model processed = model;
286
287 boolean contextEnabled = this.isEnabled();
288 if ( DEFAULT_ENABLED == contextEnabled && context.getAttribute( ENABLED_ATTRIBUTE_NAME ) instanceof Boolean )
289 {
290 contextEnabled = (Boolean) context.getAttribute( ENABLED_ATTRIBUTE_NAME );
291 }
292
293 boolean contextModelObjectClasspathResolutionEnabled = this.isModelObjectClasspathResolutionEnabled();
294 if ( contextModelObjectClasspathResolutionEnabled == DEFAULT_MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED
295 && context.getAttribute( MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_ATTRIBUTE_NAME ) instanceof Boolean )
296 {
297 contextModelObjectClasspathResolutionEnabled =
298 (Boolean) context.getAttribute( MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_ATTRIBUTE_NAME );
299
300 }
301
302 if ( contextEnabled )
303 {
304 processed = model.clone();
305 final Modules modules = ModelHelper.getModules( processed );
306
307 if ( modules != null )
308 {
309 Module classpathModule = null;
310 if ( contextModelObjectClasspathResolutionEnabled )
311 {
312 classpathModule = modules.getClasspathModule( Modules.getDefaultClasspathModuleName(),
313 context.getClassLoader() );
314
315 if ( classpathModule != null
316 && modules.getModule( Modules.getDefaultClasspathModuleName() ) == null )
317 {
318 modules.getModule().add( classpathModule );
319 }
320 else
321 {
322 classpathModule = null;
323 }
324 }
325
326 final JomcTool tool = new JomcTool();
327 tool.setModel( processed );
328
329 if ( modules.getSpecifications() != null )
330 {
331 for ( int i = 0, s0 = modules.getSpecifications().getSpecification().size(); i < s0; i++ )
332 {
333 final Specification specification = modules.getSpecifications().getSpecification().get( i );
334 final SourceFileType sourceFileType = specification.getAnyObject( SourceFileType.class );
335 final SourceFilesType sourceFilesType = specification.getAnyObject( SourceFilesType.class );
336
337 if ( sourceFileType != null )
338 {
339 if ( sourceFileType.getLocation() == null && specification.getClazz() != null )
340 {
341 // As of 1.2, the 'location' attribute got updated from 'required' to 'optional'.
342 sourceFileType.setLocation( new StringBuilder( specification.getClazz().length() + 5 ).
343 append( specification.getClazz().replace( '.', '/' ) ).append( ".java" ).
344 toString() );
345
346 }
347
348 if ( sourceFileType.getHeadComment() == null )
349 {
350 // As of 1.2, the 'head-comment' and 'tail-comment' attributes got introduced.
351 sourceFileType.setHeadComment( "//" );
352 }
353 }
354
355 if ( sourceFilesType != null )
356 {
357 this.applyDefaults( tool, specification, sourceFilesType );
358 }
359 }
360 }
361
362 if ( modules.getImplementations() != null )
363 {
364 for ( int i = 0, s0 = modules.getImplementations().getImplementation().size(); i < s0; i++ )
365 {
366 final Implementation implementation = modules.getImplementations().getImplementation().get( i );
367 final SourceFileType sourceFileType = implementation.getAnyObject( SourceFileType.class );
368 final SourceFilesType sourceFilesType = implementation.getAnyObject( SourceFilesType.class );
369
370 if ( sourceFileType != null )
371 {
372 if ( sourceFileType.getLocation() == null && implementation.getClazz() != null )
373 {
374 // As of 1.2, the 'location' attribute got updated from 'required' to 'optional'.
375 sourceFileType.setLocation( new StringBuilder( implementation.getClazz().length() + 5 ).
376 append( implementation.getClazz().replace( '.', '/' ) ).append( ".java" ).
377 toString() );
378
379 }
380
381 if ( sourceFileType.getHeadComment() == null )
382 {
383 // As of 1.2, the 'head-comment' and 'tail-comment' attributes got introduced.
384 sourceFileType.setHeadComment( "//" );
385 }
386 }
387
388 if ( sourceFilesType != null )
389 {
390 this.applyDefaults( tool, implementation, sourceFilesType );
391 }
392 }
393 }
394
395 if ( classpathModule != null )
396 {
397 modules.getModule().remove( classpathModule );
398 }
399 }
400 }
401 else if ( context.isLoggable( Level.FINER ) )
402 {
403 context.log( Level.FINER, getMessage( "disabled", this.getClass().getSimpleName(),
404 model.getIdentifier() ), null );
405
406 }
407
408 return processed;
409 }
410
411 /**
412 * Updates any optional attributes to default values.
413 *
414 * @param tool The tool to use for creating type names.
415 * @param specification The specification corresponding to {@code sourceFilesType}.
416 * @param sourceFilesType The model to update.
417 *
418 * @throws NullPointerException if {@code tool}, {@code specification} or {@code sourceFilesType} is {@code null}.
419 */
420 private void applyDefaults( final JomcTool tool, final Specification specification,
421 final SourceFilesType sourceFilesType )
422 {
423 if ( tool == null )
424 {
425 throw new NullPointerException( "tool" );
426 }
427 if ( specification == null )
428 {
429 throw new NullPointerException( "specification" );
430 }
431 if ( sourceFilesType == null )
432 {
433 throw new NullPointerException( "sourceFilesType" );
434 }
435
436 for ( int i = 0, s0 = sourceFilesType.getSourceFile().size(); i < s0; i++ )
437 {
438 final SourceFileType s = sourceFilesType.getSourceFile().get( i );
439
440 if ( s.getTemplate() == null )
441 {
442 s.setTemplate( SPECIFICATION_TEMPLATE );
443 }
444 if ( s.getLocation() == null && specification.getClazz() != null )
445 {
446 s.setLocation( new StringBuilder( specification.getClazz().length() + 5 ).append(
447 specification.getClazz().replace( '.', '/' ) ).append( ".java" ).toString() );
448
449 }
450 if ( s.getHeadComment() == null )
451 {
452 s.setHeadComment( "//" );
453 }
454
455 this.applyDefaults( tool, specification, s.getSourceSections() );
456 }
457 }
458
459 /**
460 * Updates any optional attributes to default values.
461 *
462 * @param tool The tool to use for creating type names.
463 * @param specification The specification corresponding to {@code sourceSectionsType}.
464 * @param sourceSectionsType The model to update or {@code null}.
465 *
466 * @throws NullPointerException if {@code tool} or {@code specification} is {@code null}.
467 */
468 private void applyDefaults( final JomcTool tool, final Specification specification,
469 final SourceSectionsType sourceSectionsType )
470 {
471 if ( tool == null )
472 {
473 throw new NullPointerException( "tool" );
474 }
475 if ( specification == null )
476 {
477 throw new NullPointerException( "specification" );
478 }
479
480 try
481 {
482 if ( sourceSectionsType != null )
483 {
484 for ( int i = 0, s0 = sourceSectionsType.getSourceSection().size(); i < s0; i++ )
485 {
486 final SourceSectionType s = sourceSectionsType.getSourceSection().get( i );
487
488 if ( LICENSE_SECTION_NAME.equals( s.getName() ) )
489 {
490 if ( !isFieldSet( s, "optional" ) )
491 {
492 s.setOptional( true );
493 }
494 if ( s.getHeadTemplate() == null )
495 {
496 s.setHeadTemplate( SPECIFICATION_LICENSE_TEMPLATE );
497 }
498 }
499
500 if ( ANNOTATIONS_SECTION_NAME.equals( s.getName() ) )
501 {
502 if ( s.getHeadTemplate() == null )
503 {
504 s.setHeadTemplate( SPECIFICATION_ANNOTATIONS_TEMPLATE );
505 }
506 }
507
508 if ( DOCUMENTATION_SECTION_NAME.equals( s.getName() ) )
509 {
510 if ( !isFieldSet( s, "optional" ) )
511 {
512 s.setOptional( true );
513 }
514 if ( s.getHeadTemplate() == null )
515 {
516 s.setHeadTemplate( SPECIFICATION_DOCUMENTATION_TEMPLATE );
517 }
518 }
519
520 final String javaTypeName = tool.getJavaTypeName( specification, false );
521 if ( javaTypeName != null )
522 {
523 if ( javaTypeName.equals( s.getName() ) )
524 {
525 if ( !isFieldSet( s, "editable" ) )
526 {
527 s.setEditable( true );
528 }
529 if ( !isFieldSet( s, "indentationLevel" ) )
530 {
531 s.setIndentationLevel( 1 );
532 }
533 }
534 }
535
536 this.applyDefaults( tool, specification, s.getSourceSections() );
537 }
538 }
539 }
540 catch ( final NoSuchFieldException e )
541 {
542 throw new AssertionError( e );
543 }
544 }
545
546 /**
547 * Updates any optional attributes to default values.
548 *
549 * @param tool The tool to use for creating type names.
550 * @param implementation The implementation corresponding to {@code sourceFilesType}.
551 * @param sourceFilesType The model to update.
552 *
553 * @throws NullPointerException if {@code tool}, {@code implementation} or {@code sourceFilesType} is {@code null}.
554 */
555 private void applyDefaults( final JomcTool tool, final Implementation implementation,
556 final SourceFilesType sourceFilesType )
557 {
558 if ( tool == null )
559 {
560 throw new NullPointerException( "tool" );
561 }
562 if ( implementation == null )
563 {
564 throw new NullPointerException( "implementation" );
565 }
566 if ( sourceFilesType == null )
567 {
568 throw new NullPointerException( "sourceFilesType" );
569 }
570
571 for ( int i = 0, s0 = sourceFilesType.getSourceFile().size(); i < s0; i++ )
572 {
573 final SourceFileType s = sourceFilesType.getSourceFile().get( i );
574
575 if ( s.getTemplate() == null )
576 {
577 s.setTemplate( IMPLEMENTATION_TEMPLATE );
578 }
579 if ( s.getLocation() == null && implementation.getClazz() != null )
580 {
581 s.setLocation( new StringBuilder( implementation.getClazz().length() + 5 ).append(
582 implementation.getClazz().replace( '.', '/' ) ).append( ".java" ).toString() );
583
584 }
585 if ( s.getHeadComment() == null )
586 {
587 s.setHeadComment( "//" );
588 }
589
590 this.applyDefaults( tool, implementation, s.getSourceSections() );
591 }
592 }
593
594 /**
595 * Updates any optional attributes to default values.
596 *
597 * @param tool The tool to use for creating type names.
598 * @param implementation The implementation corresponding to {@code sourceSectionsType}.
599 * @param sourceSectionsType The model to update or {@code null}.
600 *
601 * @throws NullPointerException if {@code tool} or {@code implementation} is {@code null}.
602 */
603 private void applyDefaults( final JomcTool tool, final Implementation implementation,
604 final SourceSectionsType sourceSectionsType )
605 {
606 if ( tool == null )
607 {
608 throw new NullPointerException( "tool" );
609 }
610 if ( implementation == null )
611 {
612 throw new NullPointerException( "implementation" );
613 }
614
615 try
616 {
617 if ( sourceSectionsType != null )
618 {
619 final Modules modules = ModelHelper.getModules( tool.getModel() );
620
621 for ( int i = 0, s0 = sourceSectionsType.getSourceSection().size(); i < s0; i++ )
622 {
623 final SourceSectionType s = sourceSectionsType.getSourceSection().get( i );
624
625 if ( LICENSE_SECTION_NAME.equals( s.getName() ) )
626 {
627 if ( !isFieldSet( s, "optional" ) )
628 {
629 s.setOptional( true );
630 }
631 if ( s.getHeadTemplate() == null )
632 {
633 s.setHeadTemplate( IMPLEMENTATION_LICENSE_TEMPLATE );
634 }
635 }
636
637 if ( ANNOTATIONS_SECTION_NAME.equals( s.getName() ) )
638 {
639 if ( s.getHeadTemplate() == null )
640 {
641 s.setHeadTemplate( IMPLEMENTATION_ANNOTATIONS_TEMPLATE );
642 }
643 }
644
645 if ( DOCUMENTATION_SECTION_NAME.equals( s.getName() ) )
646 {
647 if ( !isFieldSet( s, "optional" ) )
648 {
649 s.setOptional( true );
650 }
651 if ( s.getHeadTemplate() == null )
652 {
653 s.setHeadTemplate( IMPLEMENTATION_DOCUMENTATION_TEMPLATE );
654 }
655 }
656
657 if ( CONSTRUCTORS_SECTION_NAME.equals( s.getName() ) )
658 {
659 if ( !isFieldSet( s, "indentationLevel" ) )
660 {
661 s.setIndentationLevel( 1 );
662 }
663 if ( s.getHeadTemplate() == null )
664 {
665 s.setHeadTemplate( CONSTRUCTORS_HEAD_TEMPLATE );
666 }
667 if ( s.getTailTemplate() == null )
668 {
669 s.setTailTemplate( CONSTRUCTORS_TAIL_TEMPLATE );
670 }
671 if ( !isFieldSet( s, "optional" ) )
672 {
673 final Specifications specifications =
674 modules != null ? modules.getSpecifications( implementation.getIdentifier() ) : null;
675
676 s.setOptional( specifications == null || ( specifications.getSpecification().isEmpty()
677 && specifications.getReference().isEmpty() ) );
678
679 }
680 }
681
682 if ( DEFAULT_CONSTRUCTOR_SECTION_NAME.equals( s.getName() ) )
683 {
684 if ( !isFieldSet( s, "editable" ) )
685 {
686 s.setEditable( true );
687 }
688 if ( !isFieldSet( s, "indentationLevel" ) )
689 {
690 s.setIndentationLevel( 2 );
691 }
692 if ( s.getHeadTemplate() == null )
693 {
694 s.setHeadTemplate( DEFAULT_CONSTRUCTOR_TEMPLATE );
695 }
696 }
697
698 if ( DEPENDENCIES_SECTION_NAME.equals( s.getName() ) )
699 {
700 if ( !isFieldSet( s, "optional" ) )
701 {
702 final Dependencies dependencies =
703 modules != null ? modules.getDependencies( implementation.getIdentifier() ) : null;
704
705 s.setOptional( dependencies == null || dependencies.getDependency().isEmpty() );
706 }
707 if ( !isFieldSet( s, "indentationLevel" ) )
708 {
709 s.setIndentationLevel( 1 );
710 }
711 if ( s.getHeadTemplate() == null )
712 {
713 s.setHeadTemplate( DEPENDENCIES_TEMPLATE );
714 }
715 }
716
717 if ( PROPERTIES_SECTION_NAME.equals( s.getName() ) )
718 {
719 if ( !isFieldSet( s, "optional" ) )
720 {
721 final Properties properties =
722 modules != null ? modules.getProperties( implementation.getIdentifier() ) : null;
723
724 s.setOptional( properties == null || properties.getProperty().isEmpty() );
725 }
726 if ( !isFieldSet( s, "indentationLevel" ) )
727 {
728 s.setIndentationLevel( 1 );
729 }
730 if ( s.getHeadTemplate() == null )
731 {
732 s.setHeadTemplate( PROPERTIES_TEMPLATE );
733 }
734 }
735
736 if ( MESSAGES_SECTION_NAME.equals( s.getName() ) )
737 {
738 if ( !isFieldSet( s, "optional" ) )
739 {
740 final Messages messages =
741 modules != null ? modules.getMessages( implementation.getIdentifier() ) : null;
742
743 s.setOptional( messages == null || messages.getMessage().isEmpty() );
744 }
745 if ( !isFieldSet( s, "indentationLevel" ) )
746 {
747 s.setIndentationLevel( 1 );
748 }
749 if ( s.getHeadTemplate() == null )
750 {
751 s.setHeadTemplate( MESSAGES_TEMPLATE );
752 }
753 }
754
755 final List<String> implementedJavaTypeNames =
756 tool.getImplementedJavaTypeNames( implementation, false );
757
758 for ( int j = 0, s1 = implementedJavaTypeNames.size(); j < s1; j++ )
759 {
760 final String interfaceName = implementedJavaTypeNames.get( j );
761
762 if ( interfaceName.equals( s.getName() ) )
763 {
764 if ( !isFieldSet( s, "editable" ) )
765 {
766 s.setEditable( true );
767 }
768 if ( !isFieldSet( s, "indentationLevel" ) )
769 {
770 s.setIndentationLevel( 1 );
771 }
772 }
773 }
774
775 final String javaTypeName = tool.getJavaTypeName( implementation, false );
776 if ( javaTypeName != null )
777 {
778 if ( javaTypeName.equals( s.getName() ) )
779 {
780 if ( !isFieldSet( s, "editable" ) )
781 {
782 s.setEditable( true );
783 }
784 if ( !isFieldSet( s, "indentationLevel" ) )
785 {
786 s.setIndentationLevel( 1 );
787 }
788 }
789 }
790
791 this.applyDefaults( tool, implementation, s.getSourceSections() );
792 }
793 }
794 }
795 catch ( final NoSuchFieldException e )
796 {
797 throw new AssertionError( e );
798 }
799 }
800
801 private static boolean isFieldSet( final Object object, final String fieldName ) throws NoSuchFieldException
802 {
803 final Field field = object.getClass().getDeclaredField( fieldName );
804 final boolean accessible = field.isAccessible();
805
806 try
807 {
808 field.setAccessible( true );
809 return field.get( object ) != null;
810 }
811 catch ( final IllegalAccessException e )
812 {
813 throw new AssertionError( e );
814 }
815 finally
816 {
817 field.setAccessible( accessible );
818 }
819 }
820
821 private static String getMessage( final String key, final Object... args )
822 {
823 return MessageFormat.format( ResourceBundle.getBundle(
824 ToolsModelProcessor.class.getName().replace( '.', '/' ), Locale.getDefault() ).getString( key ), args );
825
826 }
827
828 }