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 4760 2013-04-08 17:56:26Z schulte $ 029 * 030 */ 031package org.jomc.tools.modlet; 032 033import java.lang.reflect.Field; 034import java.text.MessageFormat; 035import java.util.Locale; 036import java.util.ResourceBundle; 037import java.util.logging.Level; 038import org.jomc.model.Dependencies; 039import org.jomc.model.Implementation; 040import org.jomc.model.JavaTypeName; 041import org.jomc.model.Messages; 042import org.jomc.model.ModelObjectException; 043import org.jomc.model.Module; 044import org.jomc.model.Modules; 045import org.jomc.model.Properties; 046import org.jomc.model.Specification; 047import org.jomc.model.Specifications; 048import org.jomc.model.modlet.ModelHelper; 049import org.jomc.modlet.Model; 050import org.jomc.modlet.ModelContext; 051import org.jomc.modlet.ModelException; 052import org.jomc.modlet.ModelProcessor; 053import org.jomc.tools.model.SourceFileType; 054import org.jomc.tools.model.SourceFilesType; 055import org.jomc.tools.model.SourceSectionType; 056import org.jomc.tools.model.SourceSectionsType; 057import static org.jomc.tools.modlet.ToolsModletConstants.*; 058 059/** 060 * Object management and configuration tools {@code ModelProcessor} implementation. 061 * 062 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a> 063 * @version $JOMC: ToolsModelProcessor.java 4760 2013-04-08 17:56:26Z schulte $ 064 * @see ModelContext#processModel(org.jomc.modlet.Model) 065 * @since 1.2 066 */ 067public 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 if ( modules.getSpecifications() != null ) 327 { 328 for ( int i = 0, s0 = modules.getSpecifications().getSpecification().size(); i < s0; i++ ) 329 { 330 final Specification specification = modules.getSpecifications().getSpecification().get( i ); 331 final SourceFileType sourceFileType = specification.getAnyObject( SourceFileType.class ); 332 final SourceFilesType sourceFilesType = specification.getAnyObject( SourceFilesType.class ); 333 334 if ( sourceFileType != null ) 335 { 336 if ( sourceFileType.getLocation() == null && specification.getClazz() != null ) 337 { 338 // As of 1.2, the 'location' attribute got updated from 'required' to 'optional'. 339 sourceFileType.setLocation( new StringBuilder( specification.getClazz().length() + 5 ). 340 append( specification.getClazz().replace( '.', '/' ) ).append( ".java" ). 341 toString() ); 342 343 } 344 345 if ( sourceFileType.getHeadComment() == null ) 346 { 347 // As of 1.2, the 'head-comment' and 'tail-comment' attributes got introduced. 348 sourceFileType.setHeadComment( "//" ); 349 } 350 } 351 352 if ( sourceFilesType != null ) 353 { 354 this.applyDefaults( context, modules, specification, sourceFilesType ); 355 } 356 } 357 } 358 359 if ( modules.getImplementations() != null ) 360 { 361 for ( int i = 0, s0 = modules.getImplementations().getImplementation().size(); i < s0; i++ ) 362 { 363 final Implementation implementation = modules.getImplementations().getImplementation().get( i ); 364 final SourceFileType sourceFileType = implementation.getAnyObject( SourceFileType.class ); 365 final SourceFilesType sourceFilesType = implementation.getAnyObject( SourceFilesType.class ); 366 367 if ( sourceFileType != null ) 368 { 369 if ( sourceFileType.getLocation() == null && implementation.getClazz() != null ) 370 { 371 // As of 1.2, the 'location' attribute got updated from 'required' to 'optional'. 372 sourceFileType.setLocation( new StringBuilder( implementation.getClazz().length() + 5 ). 373 append( implementation.getClazz().replace( '.', '/' ) ).append( ".java" ). 374 toString() ); 375 376 } 377 378 if ( sourceFileType.getHeadComment() == null ) 379 { 380 // As of 1.2, the 'head-comment' and 'tail-comment' attributes got introduced. 381 sourceFileType.setHeadComment( "//" ); 382 } 383 } 384 385 if ( sourceFilesType != null ) 386 { 387 this.applyDefaults( context, modules, implementation, sourceFilesType ); 388 } 389 } 390 } 391 392 if ( classpathModule != null ) 393 { 394 modules.getModule().remove( classpathModule ); 395 } 396 } 397 } 398 else if ( context.isLoggable( Level.FINER ) ) 399 { 400 context.log( Level.FINER, getMessage( "disabled", this.getClass().getSimpleName(), 401 model.getIdentifier() ), null ); 402 403 } 404 405 return processed; 406 } 407 408 /** 409 * Updates any optional attributes to default values. 410 * 411 * @param context The context to apply defaults with. 412 * @param modules The model to to apply defaults with. 413 * @param specification The specification corresponding to {@code sourceFilesType}. 414 * @param sourceFilesType The model to update. 415 * 416 * @throws NullPointerException if {@code context}, {@code modules}, {@code specification} or 417 * {@code sourceFilesType} is {@code null}. 418 */ 419 private void applyDefaults( final ModelContext context, final Modules modules, final Specification specification, 420 final SourceFilesType sourceFilesType ) 421 { 422 if ( context == null ) 423 { 424 throw new NullPointerException( "context" ); 425 } 426 if ( modules == null ) 427 { 428 throw new NullPointerException( "modules" ); 429 } 430 if ( specification == null ) 431 { 432 throw new NullPointerException( "specification" ); 433 } 434 if ( sourceFilesType == null ) 435 { 436 throw new NullPointerException( "sourceFilesType" ); 437 } 438 439 for ( int i = 0, s0 = sourceFilesType.getSourceFile().size(); i < s0; i++ ) 440 { 441 final SourceFileType s = sourceFilesType.getSourceFile().get( i ); 442 443 if ( s.getTemplate() == null ) 444 { 445 s.setTemplate( SPECIFICATION_TEMPLATE ); 446 } 447 if ( s.getLocation() == null ) 448 { 449 try 450 { 451 final JavaTypeName javaTypeName = specification.getJavaTypeName(); 452 453 if ( javaTypeName != null ) 454 { 455 s.setLocation( javaTypeName.getQualifiedName().replace( '.', '/' ) + ".java" ); 456 } 457 } 458 catch ( final ModelObjectException e ) 459 { 460 context.log( Level.WARNING, getMessage( e ), null ); 461 } 462 } 463 if ( s.getHeadComment() == null ) 464 { 465 s.setHeadComment( "//" ); 466 } 467 468 this.applyDefaults( context, modules, specification, s.getSourceSections() ); 469 } 470 } 471 472 /** 473 * Updates any optional attributes to default values. 474 * 475 * @param context The context to apply defaults with. 476 * @param modules The model to to apply defaults with. 477 * @param specification The specification corresponding to {@code sourceSectionsType}. 478 * @param sourceSectionsType The model to update or {@code null}. 479 * 480 * @throws NullPointerException if {@code context}, {@code modules} or {@code specification} is {@code null}. 481 */ 482 private void applyDefaults( final ModelContext context, final Modules modules, final Specification specification, 483 final SourceSectionsType sourceSectionsType ) 484 { 485 if ( context == null ) 486 { 487 throw new NullPointerException( "context" ); 488 } 489 if ( modules == null ) 490 { 491 throw new NullPointerException( "modules" ); 492 } 493 if ( specification == null ) 494 { 495 throw new NullPointerException( "specification" ); 496 } 497 498 try 499 { 500 if ( sourceSectionsType != null ) 501 { 502 for ( int i = 0, s0 = sourceSectionsType.getSourceSection().size(); i < s0; i++ ) 503 { 504 final SourceSectionType s = sourceSectionsType.getSourceSection().get( i ); 505 506 if ( LICENSE_SECTION_NAME.equals( s.getName() ) ) 507 { 508 if ( !isFieldSet( s, "optional" ) ) 509 { 510 s.setOptional( true ); 511 } 512 if ( s.getHeadTemplate() == null ) 513 { 514 s.setHeadTemplate( SPECIFICATION_LICENSE_TEMPLATE ); 515 } 516 } 517 518 if ( ANNOTATIONS_SECTION_NAME.equals( s.getName() ) ) 519 { 520 if ( s.getHeadTemplate() == null ) 521 { 522 s.setHeadTemplate( SPECIFICATION_ANNOTATIONS_TEMPLATE ); 523 } 524 } 525 526 if ( DOCUMENTATION_SECTION_NAME.equals( s.getName() ) ) 527 { 528 if ( !isFieldSet( s, "optional" ) ) 529 { 530 s.setOptional( true ); 531 } 532 if ( s.getHeadTemplate() == null ) 533 { 534 s.setHeadTemplate( SPECIFICATION_DOCUMENTATION_TEMPLATE ); 535 } 536 } 537 538 try 539 { 540 final JavaTypeName javaTypeName = specification.getJavaTypeName(); 541 542 if ( javaTypeName != null ) 543 { 544 if ( javaTypeName.getName( false ).equals( s.getName() ) ) 545 { 546 if ( !isFieldSet( s, "editable" ) ) 547 { 548 s.setEditable( true ); 549 } 550 if ( !isFieldSet( s, "indentationLevel" ) ) 551 { 552 s.setIndentationLevel( 1 ); 553 } 554 } 555 } 556 } 557 catch ( final ModelObjectException e ) 558 { 559 context.log( Level.WARNING, getMessage( e ), null ); 560 } 561 562 this.applyDefaults( context, modules, specification, s.getSourceSections() ); 563 } 564 } 565 } 566 catch ( final NoSuchFieldException e ) 567 { 568 throw new AssertionError( e ); 569 } 570 } 571 572 /** 573 * Updates any optional attributes to default values. 574 * 575 * @param context The context to apply defaults with. 576 * @param modules The model to to apply defaults with. 577 * @param implementation The implementation corresponding to {@code sourceFilesType}. 578 * @param sourceFilesType The model to update. 579 * 580 * @throws NullPointerException if {@code context}, {@code modules}, {@code implementation} or 581 * {@code sourceFilesType} is {@code null}. 582 */ 583 private void applyDefaults( final ModelContext context, final Modules modules, final Implementation implementation, 584 final SourceFilesType sourceFilesType ) 585 { 586 if ( context == null ) 587 { 588 throw new NullPointerException( "context" ); 589 } 590 if ( modules == null ) 591 { 592 throw new NullPointerException( "modules" ); 593 } 594 if ( implementation == null ) 595 { 596 throw new NullPointerException( "implementation" ); 597 } 598 if ( sourceFilesType == null ) 599 { 600 throw new NullPointerException( "sourceFilesType" ); 601 } 602 603 for ( int i = 0, s0 = sourceFilesType.getSourceFile().size(); i < s0; i++ ) 604 { 605 final SourceFileType s = sourceFilesType.getSourceFile().get( i ); 606 607 if ( s.getTemplate() == null ) 608 { 609 s.setTemplate( IMPLEMENTATION_TEMPLATE ); 610 } 611 if ( s.getLocation() == null ) 612 { 613 try 614 { 615 final JavaTypeName javaTypeName = implementation.getJavaTypeName(); 616 617 if ( javaTypeName != null ) 618 { 619 s.setLocation( javaTypeName.getQualifiedName().replace( '.', '/' ) + ".java" ); 620 } 621 } 622 catch ( final ModelObjectException e ) 623 { 624 context.log( Level.WARNING, getMessage( e ), null ); 625 } 626 } 627 if ( s.getHeadComment() == null ) 628 { 629 s.setHeadComment( "//" ); 630 } 631 632 this.applyDefaults( context, modules, implementation, s.getSourceSections() ); 633 } 634 } 635 636 /** 637 * Updates any optional attributes to default values. 638 * 639 * @param context The context to apply defaults with. 640 * @param modules The model to to apply defaults with. 641 * @param implementation The implementation corresponding to {@code sourceSectionsType}. 642 * @param sourceSectionsType The model to update or {@code null}. 643 * 644 * @throws NullPointerException if {@code context}, {@code modules} or {@code implementation} is {@code null}. 645 */ 646 private void applyDefaults( final ModelContext context, final Modules modules, final Implementation implementation, 647 final SourceSectionsType sourceSectionsType ) 648 { 649 if ( context == null ) 650 { 651 throw new NullPointerException( "context" ); 652 } 653 if ( modules == null ) 654 { 655 throw new NullPointerException( "modules" ); 656 } 657 if ( implementation == null ) 658 { 659 throw new NullPointerException( "implementation" ); 660 } 661 662 final Specifications specifications = modules.getSpecifications( implementation.getIdentifier() ); 663 final Dependencies dependencies = modules.getDependencies( implementation.getIdentifier() ); 664 final Messages messages = modules.getMessages( implementation.getIdentifier() ); 665 final Properties properties = modules.getProperties( implementation.getIdentifier() ); 666 667 try 668 { 669 if ( sourceSectionsType != null ) 670 { 671 for ( int i = 0, s0 = sourceSectionsType.getSourceSection().size(); i < s0; i++ ) 672 { 673 final SourceSectionType s = sourceSectionsType.getSourceSection().get( i ); 674 675 if ( LICENSE_SECTION_NAME.equals( s.getName() ) ) 676 { 677 if ( !isFieldSet( s, "optional" ) ) 678 { 679 s.setOptional( true ); 680 } 681 if ( s.getHeadTemplate() == null ) 682 { 683 s.setHeadTemplate( IMPLEMENTATION_LICENSE_TEMPLATE ); 684 } 685 } 686 687 if ( ANNOTATIONS_SECTION_NAME.equals( s.getName() ) ) 688 { 689 if ( s.getHeadTemplate() == null ) 690 { 691 s.setHeadTemplate( IMPLEMENTATION_ANNOTATIONS_TEMPLATE ); 692 } 693 } 694 695 if ( DOCUMENTATION_SECTION_NAME.equals( s.getName() ) ) 696 { 697 if ( !isFieldSet( s, "optional" ) ) 698 { 699 s.setOptional( true ); 700 } 701 if ( s.getHeadTemplate() == null ) 702 { 703 s.setHeadTemplate( IMPLEMENTATION_DOCUMENTATION_TEMPLATE ); 704 } 705 } 706 707 if ( CONSTRUCTORS_SECTION_NAME.equals( s.getName() ) ) 708 { 709 if ( !isFieldSet( s, "indentationLevel" ) ) 710 { 711 s.setIndentationLevel( 1 ); 712 } 713 if ( s.getHeadTemplate() == null ) 714 { 715 s.setHeadTemplate( CONSTRUCTORS_HEAD_TEMPLATE ); 716 } 717 if ( s.getTailTemplate() == null ) 718 { 719 s.setTailTemplate( CONSTRUCTORS_TAIL_TEMPLATE ); 720 } 721 if ( !isFieldSet( s, "optional" ) ) 722 { 723 s.setOptional( specifications == null || ( specifications.getSpecification().isEmpty() 724 && specifications.getReference().isEmpty() ) ); 725 726 } 727 } 728 729 if ( DEFAULT_CONSTRUCTOR_SECTION_NAME.equals( s.getName() ) ) 730 { 731 if ( !isFieldSet( s, "editable" ) ) 732 { 733 s.setEditable( true ); 734 } 735 if ( !isFieldSet( s, "indentationLevel" ) ) 736 { 737 s.setIndentationLevel( 2 ); 738 } 739 if ( s.getHeadTemplate() == null ) 740 { 741 s.setHeadTemplate( DEFAULT_CONSTRUCTOR_TEMPLATE ); 742 } 743 } 744 745 if ( DEPENDENCIES_SECTION_NAME.equals( s.getName() ) ) 746 { 747 if ( !isFieldSet( s, "optional" ) ) 748 { 749 s.setOptional( dependencies == null || dependencies.getDependency().isEmpty() ); 750 } 751 if ( !isFieldSet( s, "indentationLevel" ) ) 752 { 753 s.setIndentationLevel( 1 ); 754 } 755 if ( s.getHeadTemplate() == null ) 756 { 757 s.setHeadTemplate( DEPENDENCIES_TEMPLATE ); 758 } 759 } 760 761 if ( PROPERTIES_SECTION_NAME.equals( s.getName() ) ) 762 { 763 if ( !isFieldSet( s, "optional" ) ) 764 { 765 s.setOptional( properties == null || properties.getProperty().isEmpty() ); 766 } 767 if ( !isFieldSet( s, "indentationLevel" ) ) 768 { 769 s.setIndentationLevel( 1 ); 770 } 771 if ( s.getHeadTemplate() == null ) 772 { 773 s.setHeadTemplate( PROPERTIES_TEMPLATE ); 774 } 775 } 776 777 if ( MESSAGES_SECTION_NAME.equals( s.getName() ) ) 778 { 779 if ( !isFieldSet( s, "optional" ) ) 780 { 781 s.setOptional( messages == null || messages.getMessage().isEmpty() ); 782 } 783 if ( !isFieldSet( s, "indentationLevel" ) ) 784 { 785 s.setIndentationLevel( 1 ); 786 } 787 if ( s.getHeadTemplate() == null ) 788 { 789 s.setHeadTemplate( MESSAGES_TEMPLATE ); 790 } 791 } 792 793 if ( specifications != null ) 794 { 795 for ( final Specification specification : specifications.getSpecification() ) 796 { 797 try 798 { 799 final JavaTypeName javaTypeName = specification.getJavaTypeName(); 800 801 if ( javaTypeName != null ) 802 { 803 if ( javaTypeName.getName( false ).equals( s.getName() ) ) 804 { 805 if ( !isFieldSet( s, "editable" ) ) 806 { 807 s.setEditable( true ); 808 } 809 if ( !isFieldSet( s, "indentationLevel" ) ) 810 { 811 s.setIndentationLevel( 1 ); 812 } 813 } 814 } 815 } 816 catch ( final ModelObjectException e ) 817 { 818 context.log( Level.WARNING, getMessage( e ), null ); 819 } 820 } 821 } 822 823 try 824 { 825 final JavaTypeName javaTypeName = implementation.getJavaTypeName(); 826 827 if ( javaTypeName != null ) 828 { 829 if ( javaTypeName.getName( false ).equals( s.getName() ) ) 830 { 831 if ( !isFieldSet( s, "editable" ) ) 832 { 833 s.setEditable( true ); 834 } 835 if ( !isFieldSet( s, "indentationLevel" ) ) 836 { 837 s.setIndentationLevel( 1 ); 838 } 839 } 840 } 841 } 842 catch ( final ModelObjectException e ) 843 { 844 context.log( Level.WARNING, getMessage( e ), null ); 845 } 846 847 this.applyDefaults( context, modules, implementation, s.getSourceSections() ); 848 } 849 } 850 } 851 catch ( final NoSuchFieldException e ) 852 { 853 throw new AssertionError( e ); 854 } 855 } 856 857 private static boolean isFieldSet( final Object object, final String fieldName ) throws NoSuchFieldException 858 { 859 final Field field = object.getClass().getDeclaredField( fieldName ); 860 final boolean accessible = field.isAccessible(); 861 862 try 863 { 864 field.setAccessible( true ); 865 return field.get( object ) != null; 866 } 867 catch ( final IllegalAccessException e ) 868 { 869 throw new AssertionError( e ); 870 } 871 finally 872 { 873 field.setAccessible( accessible ); 874 } 875 } 876 877 private static String getMessage( final Throwable t ) 878 { 879 return t != null 880 ? t.getMessage() != null && t.getMessage().trim().length() > 0 881 ? t.getMessage() 882 : getMessage( t.getCause() ) 883 : null; 884 885 } 886 887 private static String getMessage( final String key, final Object... args ) 888 { 889 return MessageFormat.format( ResourceBundle.getBundle( 890 ToolsModelProcessor.class.getName().replace( '.', '/' ), Locale.getDefault() ).getString( key ), args ); 891 892 } 893 894}