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 */ 031package org.jomc.tools.modlet; 032 033import java.lang.reflect.Field; 034import java.text.MessageFormat; 035import java.util.List; 036import java.util.Locale; 037import java.util.ResourceBundle; 038import java.util.logging.Level; 039import org.jomc.model.Dependencies; 040import org.jomc.model.Implementation; 041import org.jomc.model.Messages; 042import org.jomc.model.Module; 043import org.jomc.model.Modules; 044import org.jomc.model.Properties; 045import org.jomc.model.Specification; 046import org.jomc.model.Specifications; 047import org.jomc.model.modlet.ModelHelper; 048import org.jomc.modlet.Model; 049import org.jomc.modlet.ModelContext; 050import org.jomc.modlet.ModelException; 051import org.jomc.modlet.ModelProcessor; 052import org.jomc.tools.JomcTool; 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: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 */ 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 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}