1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  package org.jomc.tools.modlet;
32  
33  import java.lang.reflect.Field;
34  import java.text.MessageFormat;
35  import java.util.Locale;
36  import java.util.ResourceBundle;
37  import java.util.logging.Level;
38  import org.jomc.model.Dependencies;
39  import org.jomc.model.Implementation;
40  import org.jomc.model.JavaTypeName;
41  import org.jomc.model.Messages;
42  import org.jomc.model.ModelObjectException;
43  import org.jomc.model.Module;
44  import org.jomc.model.Modules;
45  import org.jomc.model.Properties;
46  import org.jomc.model.Specification;
47  import org.jomc.model.Specifications;
48  import org.jomc.model.modlet.ModelHelper;
49  import org.jomc.modlet.Model;
50  import org.jomc.modlet.ModelContext;
51  import org.jomc.modlet.ModelException;
52  import org.jomc.modlet.ModelProcessor;
53  import org.jomc.tools.model.SourceFileType;
54  import org.jomc.tools.model.SourceFilesType;
55  import org.jomc.tools.model.SourceSectionType;
56  import org.jomc.tools.model.SourceSectionsType;
57  import static org.jomc.tools.modlet.ToolsModletConstants.ANNOTATIONS_SECTION_NAME;
58  import static org.jomc.tools.modlet.ToolsModletConstants.CONSTRUCTORS_HEAD_TEMPLATE;
59  import static org.jomc.tools.modlet.ToolsModletConstants.CONSTRUCTORS_SECTION_NAME;
60  import static org.jomc.tools.modlet.ToolsModletConstants.CONSTRUCTORS_TAIL_TEMPLATE;
61  import static org.jomc.tools.modlet.ToolsModletConstants.DEFAULT_CONSTRUCTOR_SECTION_NAME;
62  import static org.jomc.tools.modlet.ToolsModletConstants.DEFAULT_CONSTRUCTOR_TEMPLATE;
63  import static org.jomc.tools.modlet.ToolsModletConstants.DEPENDENCIES_SECTION_NAME;
64  import static org.jomc.tools.modlet.ToolsModletConstants.DEPENDENCIES_TEMPLATE;
65  import static org.jomc.tools.modlet.ToolsModletConstants.DOCUMENTATION_SECTION_NAME;
66  import static org.jomc.tools.modlet.ToolsModletConstants.IMPLEMENTATION_ANNOTATIONS_TEMPLATE;
67  import static org.jomc.tools.modlet.ToolsModletConstants.IMPLEMENTATION_DOCUMENTATION_TEMPLATE;
68  import static org.jomc.tools.modlet.ToolsModletConstants.IMPLEMENTATION_LICENSE_TEMPLATE;
69  import static org.jomc.tools.modlet.ToolsModletConstants.IMPLEMENTATION_TEMPLATE;
70  import static org.jomc.tools.modlet.ToolsModletConstants.LICENSE_SECTION_NAME;
71  import static org.jomc.tools.modlet.ToolsModletConstants.MESSAGES_SECTION_NAME;
72  import static org.jomc.tools.modlet.ToolsModletConstants.MESSAGES_TEMPLATE;
73  import static org.jomc.tools.modlet.ToolsModletConstants.PROPERTIES_SECTION_NAME;
74  import static org.jomc.tools.modlet.ToolsModletConstants.PROPERTIES_TEMPLATE;
75  import static org.jomc.tools.modlet.ToolsModletConstants.SPECIFICATION_ANNOTATIONS_TEMPLATE;
76  import static org.jomc.tools.modlet.ToolsModletConstants.SPECIFICATION_DOCUMENTATION_TEMPLATE;
77  import static org.jomc.tools.modlet.ToolsModletConstants.SPECIFICATION_LICENSE_TEMPLATE;
78  import static org.jomc.tools.modlet.ToolsModletConstants.SPECIFICATION_TEMPLATE;
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  public class ToolsModelProcessor implements ModelProcessor
89  {
90  
91      
92  
93  
94  
95  
96  
97      public static final String ENABLED_ATTRIBUTE_NAME = "org.jomc.tools.modlet.ToolsModelProcessor.enabledAttribute";
98  
99      
100 
101 
102 
103 
104     private static final String DEFAULT_ENABLED_PROPERTY_NAME =
105         "org.jomc.tools.modlet.ToolsModelProcessor.defaultEnabled";
106 
107     
108 
109 
110 
111 
112     private static final Boolean DEFAULT_ENABLED = Boolean.TRUE;
113 
114     
115 
116 
117     private static volatile Boolean defaultEnabled;
118 
119     
120 
121 
122     private Boolean enabled;
123 
124     
125 
126 
127 
128 
129 
130 
131     public static final String MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_ATTRIBUTE_NAME =
132         "org.jomc.tools.modlet.ToolsModelProcessor.modelObjectClasspathResolutionEnabledAttribute";
133 
134     
135 
136 
137 
138 
139 
140     private static final String DEFAULT_MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_PROPERTY_NAME =
141         "org.jomc.tools.modlet.ToolsModelProcessor.defaultModelObjectClasspathResolutionEnabled";
142 
143     
144 
145 
146 
147 
148     private static final Boolean DEFAULT_MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED = Boolean.TRUE;
149 
150     
151 
152 
153     private static volatile Boolean defaultModelObjectClasspathResolutionEnabled;
154 
155     
156 
157 
158     private Boolean modelObjectClasspathResolutionEnabled;
159 
160     
161 
162 
163 
164 
165 
166 
167     public static final String HEAD_COMMENT_ATTRIBUTE_NAME =
168         "org.jomc.tools.modlet.ToolsModelProcessor.headCommentAttribute";
169 
170     
171 
172 
173 
174 
175 
176     private static final String DEFAULT_HEAD_COMMENT_PROPERTY_NAME =
177         "org.jomc.tools.modlet.ToolsModelProcessor.defaultHeadComment";
178 
179     
180 
181 
182 
183 
184 
185     private static final String DEFAULT_HEAD_COMMENT = "//";
186 
187     
188 
189 
190 
191 
192     private static volatile String defaultHeadComment;
193 
194     
195 
196 
197 
198 
199     private String headComment;
200 
201     
202 
203 
204 
205 
206 
207 
208     public static final String TAIL_COMMENT_ATTRIBUTE_NAME =
209         "org.jomc.tools.modlet.ToolsModelProcessor.tailCommentAttribute";
210 
211     
212 
213 
214 
215 
216 
217     private static final String DEFAULT_TAIL_COMMENT_PROPERTY_NAME =
218         "org.jomc.tools.modlet.ToolsModelProcessor.defaultTailComment";
219 
220     
221 
222 
223 
224 
225 
226     private static final String DEFAULT_TAIL_COMMENT = null;
227 
228     
229 
230 
231 
232 
233     private static volatile String defaultTailComment;
234 
235     
236 
237 
238 
239 
240     private String tailComment;
241 
242     
243 
244 
245     public ToolsModelProcessor()
246     {
247         super();
248     }
249 
250     
251 
252 
253 
254 
255 
256 
257 
258 
259 
260 
261 
262 
263     public static boolean isDefaultEnabled()
264     {
265         if ( defaultEnabled == null )
266         {
267             defaultEnabled = Boolean.valueOf( System.getProperty( DEFAULT_ENABLED_PROPERTY_NAME,
268                                                                   Boolean.toString( DEFAULT_ENABLED ) ) );
269 
270         }
271 
272         return defaultEnabled;
273     }
274 
275     
276 
277 
278 
279 
280 
281 
282     public static void setDefaultEnabled( final Boolean value )
283     {
284         defaultEnabled = value;
285     }
286 
287     
288 
289 
290 
291 
292 
293 
294 
295     public final boolean isEnabled()
296     {
297         if ( this.enabled == null )
298         {
299             this.enabled = isDefaultEnabled();
300         }
301 
302         return this.enabled;
303     }
304 
305     
306 
307 
308 
309 
310 
311 
312     public final void setEnabled( final Boolean value )
313     {
314         this.enabled = value;
315     }
316 
317     
318 
319 
320 
321 
322 
323 
324 
325 
326 
327 
328 
329 
330 
331     public static boolean isDefaultModelObjectClasspathResolutionEnabled()
332     {
333         if ( defaultModelObjectClasspathResolutionEnabled == null )
334         {
335             defaultModelObjectClasspathResolutionEnabled = Boolean.valueOf( System.getProperty(
336                 DEFAULT_MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_PROPERTY_NAME,
337                 Boolean.toString( DEFAULT_MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED ) ) );
338 
339         }
340 
341         return defaultModelObjectClasspathResolutionEnabled;
342     }
343 
344     
345 
346 
347 
348 
349 
350 
351 
352     public static void setDefaultModelObjectClasspathResolutionEnabled( final Boolean value )
353     {
354         defaultModelObjectClasspathResolutionEnabled = value;
355     }
356 
357     
358 
359 
360 
361 
362 
363 
364 
365 
366     public final boolean isModelObjectClasspathResolutionEnabled()
367     {
368         if ( this.modelObjectClasspathResolutionEnabled == null )
369         {
370             this.modelObjectClasspathResolutionEnabled = isDefaultModelObjectClasspathResolutionEnabled();
371         }
372 
373         return this.modelObjectClasspathResolutionEnabled;
374     }
375 
376     
377 
378 
379 
380 
381 
382 
383     public final void setModelObjectClasspathResolutionEnabled( final Boolean value )
384     {
385         this.modelObjectClasspathResolutionEnabled = value;
386     }
387 
388     
389 
390 
391 
392 
393 
394 
395 
396 
397 
398 
399 
400 
401     public static String getDefaultHeadComment()
402     {
403         if ( defaultHeadComment == null )
404         {
405             defaultHeadComment = System.getProperty( DEFAULT_HEAD_COMMENT_PROPERTY_NAME, DEFAULT_HEAD_COMMENT );
406         }
407 
408         return defaultHeadComment;
409     }
410 
411     
412 
413 
414 
415 
416 
417 
418 
419     public static void setDefaultHeadComment( final String value )
420     {
421         defaultHeadComment = value;
422     }
423 
424     
425 
426 
427 
428 
429 
430 
431 
432 
433     public final String getHeadComment()
434     {
435         if ( this.headComment == null )
436         {
437             this.headComment = getDefaultHeadComment();
438         }
439 
440         return this.headComment;
441     }
442 
443     
444 
445 
446 
447 
448 
449 
450 
451     public final void setHeadComment( final String value )
452     {
453         this.headComment = value;
454     }
455 
456     
457 
458 
459 
460 
461 
462 
463 
464 
465 
466 
467 
468 
469     public static String getDefaultTailComment()
470     {
471         if ( defaultTailComment == null )
472         {
473             defaultTailComment = System.getProperty( DEFAULT_TAIL_COMMENT_PROPERTY_NAME, DEFAULT_TAIL_COMMENT );
474         }
475 
476         return defaultTailComment;
477     }
478 
479     
480 
481 
482 
483 
484 
485 
486 
487     public static void setDefaultTailComment( final String value )
488     {
489         defaultTailComment = value;
490     }
491 
492     
493 
494 
495 
496 
497 
498 
499 
500 
501     public final String getTailComment()
502     {
503         if ( this.tailComment == null )
504         {
505             this.tailComment = getDefaultTailComment();
506         }
507 
508         return this.tailComment;
509     }
510 
511     
512 
513 
514 
515 
516 
517 
518 
519     public final void setTailComment( final String value )
520     {
521         this.tailComment = value;
522     }
523 
524     
525 
526 
527 
528 
529 
530 
531 
532 
533 
534 
535 
536     public Model processModel( final ModelContext context, final Model model ) throws ModelException
537     {
538         if ( context == null )
539         {
540             throw new NullPointerException( "context" );
541         }
542         if ( model == null )
543         {
544             throw new NullPointerException( "model" );
545         }
546 
547         Model processed = model;
548 
549         boolean contextEnabled = this.isEnabled();
550         if ( DEFAULT_ENABLED == contextEnabled && context.getAttribute( ENABLED_ATTRIBUTE_NAME ) instanceof Boolean )
551         {
552             contextEnabled = (Boolean) context.getAttribute( ENABLED_ATTRIBUTE_NAME );
553         }
554 
555         boolean contextModelObjectClasspathResolutionEnabled = this.isModelObjectClasspathResolutionEnabled();
556         if ( contextModelObjectClasspathResolutionEnabled == DEFAULT_MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED
557                  && context.getAttribute( MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_ATTRIBUTE_NAME ) instanceof Boolean )
558         {
559             contextModelObjectClasspathResolutionEnabled =
560                 (Boolean) context.getAttribute( MODEL_OBJECT_CLASSPATH_RESOLUTION_ENABLED_ATTRIBUTE_NAME );
561 
562         }
563 
564         if ( contextEnabled )
565         {
566             processed = model.clone();
567             final Modules modules = ModelHelper.getModules( processed );
568 
569             if ( modules != null )
570             {
571                 Module classpathModule = null;
572                 if ( contextModelObjectClasspathResolutionEnabled )
573                 {
574                     classpathModule = modules.getClasspathModule( Modules.getDefaultClasspathModuleName(),
575                                                                   context.getClassLoader() );
576 
577                     if ( classpathModule != null
578                              && modules.getModule( Modules.getDefaultClasspathModuleName() ) == null )
579                     {
580                         modules.getModule().add( classpathModule );
581                     }
582                     else
583                     {
584                         classpathModule = null;
585                     }
586                 }
587 
588                 if ( modules.getSpecifications() != null )
589                 {
590                     for ( int i = 0, s0 = modules.getSpecifications().getSpecification().size(); i < s0; i++ )
591                     {
592                         final Specification specification = modules.getSpecifications().getSpecification().get( i );
593                         final SourceFileType sourceFileType = specification.getAnyObject( SourceFileType.class );
594                         final SourceFilesType sourceFilesType = specification.getAnyObject( SourceFilesType.class );
595 
596                         if ( sourceFileType != null )
597                         {
598                             if ( sourceFileType.getLocation() == null && specification.getClazz() != null )
599                             {
600                                 
601                                 sourceFileType.setLocation( new StringBuilder( specification.getClazz().length() + 5 ).
602                                     append( specification.getClazz().replace( '.', '/' ) ).append( ".java" ).
603                                     toString() );
604 
605                             }
606 
607                             if ( sourceFileType.getHeadComment() == null )
608                             {
609                                 
610                                 sourceFileType.setHeadComment( "//" );
611                             }
612                         }
613 
614                         if ( sourceFilesType != null )
615                         {
616                             this.applyDefaults( context, modules, specification, sourceFilesType );
617                         }
618                     }
619                 }
620 
621                 if ( modules.getImplementations() != null )
622                 {
623                     for ( int i = 0, s0 = modules.getImplementations().getImplementation().size(); i < s0; i++ )
624                     {
625                         final Implementation implementation = modules.getImplementations().getImplementation().get( i );
626                         final SourceFileType sourceFileType = implementation.getAnyObject( SourceFileType.class );
627                         final SourceFilesType sourceFilesType = implementation.getAnyObject( SourceFilesType.class );
628 
629                         if ( sourceFileType != null )
630                         {
631                             if ( sourceFileType.getLocation() == null && implementation.getClazz() != null )
632                             {
633                                 
634                                 sourceFileType.setLocation( new StringBuilder( implementation.getClazz().length() + 5 ).
635                                     append( implementation.getClazz().replace( '.', '/' ) ).append( ".java" ).
636                                     toString() );
637 
638                             }
639 
640                             if ( sourceFileType.getHeadComment() == null )
641                             {
642                                 
643                                 sourceFileType.setHeadComment( "//" );
644                             }
645                         }
646 
647                         if ( sourceFilesType != null )
648                         {
649                             this.applyDefaults( context, modules, implementation, sourceFilesType );
650                         }
651                     }
652                 }
653 
654                 if ( classpathModule != null )
655                 {
656                     modules.getModule().remove( classpathModule );
657                 }
658             }
659         }
660         else if ( context.isLoggable( Level.FINER ) )
661         {
662             context.log( Level.FINER, getMessage( "disabled", this.getClass().getSimpleName(),
663                                                   model.getIdentifier() ), null );
664 
665         }
666 
667         return processed;
668     }
669 
670     
671 
672 
673 
674 
675 
676 
677 
678 
679 
680 
681 
682 
683 
684 
685 
686 
687 
688 
689     protected String getDefaultSourceFileLocation( final ModelContext context, final Modules modules,
690                                                    final Specification specification )
691     {
692         if ( context == null )
693         {
694             throw new NullPointerException( "context" );
695         }
696         if ( modules == null )
697         {
698             throw new NullPointerException( "modules" );
699         }
700         if ( specification == null )
701         {
702             throw new NullPointerException( "specification" );
703         }
704 
705         String location = null;
706 
707         try
708         {
709             if ( specification.getJavaTypeName() != null )
710             {
711                 location = specification.getJavaTypeName().getQualifiedName().replace( '.', '/' ) + ".java";
712             }
713         }
714         catch ( final ModelObjectException e )
715         {
716             context.log( Level.WARNING, getMessage( e ), null );
717         }
718 
719         return location;
720     }
721 
722     
723 
724 
725 
726 
727 
728 
729 
730 
731 
732 
733 
734 
735 
736 
737 
738 
739 
740 
741     protected String getDefaultSourceFileLocation( final ModelContext context, final Modules modules,
742                                                    final Implementation implementation )
743     {
744         if ( context == null )
745         {
746             throw new NullPointerException( "context" );
747         }
748         if ( modules == null )
749         {
750             throw new NullPointerException( "modules" );
751         }
752         if ( implementation == null )
753         {
754             throw new NullPointerException( "implementation" );
755         }
756 
757         String location = null;
758 
759         try
760         {
761             if ( implementation.getJavaTypeName() != null )
762             {
763                 location = implementation.getJavaTypeName().getQualifiedName().replace( '.', '/' ) + ".java";
764             }
765         }
766         catch ( final ModelObjectException e )
767         {
768             context.log( Level.WARNING, getMessage( e ), null );
769         }
770 
771         return location;
772     }
773 
774     
775 
776 
777 
778 
779 
780 
781 
782 
783 
784 
785 
786 
787 
788 
789 
790 
791 
792 
793     protected String getDefaultSourceSectionName( final ModelContext context, final Modules modules,
794                                                   final Specification specification )
795     {
796         if ( context == null )
797         {
798             throw new NullPointerException( "context" );
799         }
800         if ( modules == null )
801         {
802             throw new NullPointerException( "modules" );
803         }
804         if ( specification == null )
805         {
806             throw new NullPointerException( "specification" );
807         }
808 
809         String sectionName = null;
810 
811         try
812         {
813             final JavaTypeName javaTypeName = specification.getJavaTypeName();
814 
815             if ( javaTypeName != null )
816             {
817                 sectionName = javaTypeName.getName( false );
818             }
819         }
820         catch ( final ModelObjectException e )
821         {
822             context.log( Level.WARNING, getMessage( e ), null );
823         }
824 
825         return sectionName;
826     }
827 
828     
829 
830 
831 
832 
833 
834 
835 
836 
837 
838 
839 
840 
841 
842 
843 
844 
845 
846 
847     protected String getDefaultSourceSectionName( final ModelContext context, final Modules modules,
848                                                   final Implementation implementation )
849     {
850         if ( context == null )
851         {
852             throw new NullPointerException( "context" );
853         }
854         if ( modules == null )
855         {
856             throw new NullPointerException( "modules" );
857         }
858         if ( implementation == null )
859         {
860             throw new NullPointerException( "implementation" );
861         }
862 
863         String sectionName = null;
864 
865         try
866         {
867             final JavaTypeName javaTypeName = implementation.getJavaTypeName();
868 
869             if ( javaTypeName != null )
870             {
871                 sectionName = javaTypeName.getName( false );
872             }
873         }
874         catch ( final ModelObjectException e )
875         {
876             context.log( Level.WARNING, getMessage( e ), null );
877         }
878 
879         return sectionName;
880     }
881 
882     
883 
884 
885 
886 
887 
888 
889 
890 
891 
892 
893     private void applyDefaults( final ModelContext context, final Modules modules, final Specification specification,
894                                 final SourceFilesType sourceFilesType )
895     {
896         if ( context == null )
897         {
898             throw new NullPointerException( "context" );
899         }
900         if ( modules == null )
901         {
902             throw new NullPointerException( "modules" );
903         }
904         if ( specification == null )
905         {
906             throw new NullPointerException( "specification" );
907         }
908         if ( sourceFilesType == null )
909         {
910             throw new NullPointerException( "sourceFilesType" );
911         }
912 
913         String contextHeadComment = this.getHeadComment();
914         if ( ( DEFAULT_HEAD_COMMENT != null
915                ? DEFAULT_HEAD_COMMENT.equals( contextHeadComment )
916                : contextHeadComment == null )
917                  && context.getAttribute( HEAD_COMMENT_ATTRIBUTE_NAME ) instanceof String )
918         {
919             contextHeadComment = (String) context.getAttribute( HEAD_COMMENT_ATTRIBUTE_NAME );
920         }
921 
922         if ( contextHeadComment != null && contextHeadComment.length() == 0 )
923         {
924             contextHeadComment = null;
925         }
926 
927         String contextTailComment = this.getTailComment();
928         if ( ( DEFAULT_TAIL_COMMENT != null
929                ? DEFAULT_TAIL_COMMENT.equals( contextTailComment )
930                : contextTailComment == null )
931                  && context.getAttribute( TAIL_COMMENT_ATTRIBUTE_NAME ) instanceof String )
932         {
933             contextTailComment = (String) context.getAttribute( TAIL_COMMENT_ATTRIBUTE_NAME );
934         }
935 
936         if ( contextTailComment != null && contextTailComment.length() == 0 )
937         {
938             contextTailComment = null;
939         }
940 
941         for ( int i = 0, s0 = sourceFilesType.getSourceFile().size(); i < s0; i++ )
942         {
943             final SourceFileType s = sourceFilesType.getSourceFile().get( i );
944 
945             if ( s.getTemplate() == null )
946             {
947                 s.setTemplate( SPECIFICATION_TEMPLATE );
948             }
949             if ( s.getLocation() == null )
950             {
951                 s.setLocation( this.getDefaultSourceFileLocation( context, modules, specification ) );
952             }
953             if ( s.getHeadComment() == null )
954             {
955                 s.setHeadComment( contextHeadComment );
956             }
957             if ( s.getTailComment() == null )
958             {
959                 s.setTailComment( contextTailComment );
960             }
961 
962             this.applyDefaults( context, modules, specification, s.getSourceSections() );
963         }
964     }
965 
966     
967 
968 
969 
970 
971 
972 
973 
974 
975 
976     private void applyDefaults( final ModelContext context, final Modules modules, final Specification specification,
977                                 final SourceSectionsType sourceSectionsType )
978     {
979         if ( context == null )
980         {
981             throw new NullPointerException( "context" );
982         }
983         if ( modules == null )
984         {
985             throw new NullPointerException( "modules" );
986         }
987         if ( specification == null )
988         {
989             throw new NullPointerException( "specification" );
990         }
991 
992         try
993         {
994             if ( sourceSectionsType != null )
995             {
996                 for ( int i = 0, s0 = sourceSectionsType.getSourceSection().size(); i < s0; i++ )
997                 {
998                     final SourceSectionType s = sourceSectionsType.getSourceSection().get( i );
999 
1000                     if ( LICENSE_SECTION_NAME.equals( s.getName() ) )
1001                     {
1002                         if ( !isFieldSet( s, "optional" ) )
1003                         {
1004                             s.setOptional( true );
1005                         }
1006                         if ( s.getHeadTemplate() == null )
1007                         {
1008                             s.setHeadTemplate( SPECIFICATION_LICENSE_TEMPLATE );
1009                         }
1010                     }
1011 
1012                     if ( ANNOTATIONS_SECTION_NAME.equals( s.getName() ) )
1013                     {
1014                         if ( s.getHeadTemplate() == null )
1015                         {
1016                             s.setHeadTemplate( SPECIFICATION_ANNOTATIONS_TEMPLATE );
1017                         }
1018                     }
1019 
1020                     if ( DOCUMENTATION_SECTION_NAME.equals( s.getName() ) )
1021                     {
1022                         if ( !isFieldSet( s, "optional" ) )
1023                         {
1024                             s.setOptional( true );
1025                         }
1026                         if ( s.getHeadTemplate() == null )
1027                         {
1028                             s.setHeadTemplate( SPECIFICATION_DOCUMENTATION_TEMPLATE );
1029                         }
1030                     }
1031 
1032                     final String sectionName = this.getDefaultSourceSectionName( context, modules, specification );
1033 
1034                     if ( sectionName != null && sectionName.equals( s.getName() ) )
1035                     {
1036                         if ( !isFieldSet( s, "editable" ) )
1037                         {
1038                             s.setEditable( true );
1039                         }
1040                         if ( !isFieldSet( s, "indentationLevel" ) )
1041                         {
1042                             s.setIndentationLevel( 1 );
1043                         }
1044                     }
1045 
1046                     this.applyDefaults( context, modules, specification, s.getSourceSections() );
1047                 }
1048             }
1049         }
1050         catch ( final NoSuchFieldException e )
1051         {
1052             throw new AssertionError( e );
1053         }
1054     }
1055 
1056     
1057 
1058 
1059 
1060 
1061 
1062 
1063 
1064 
1065 
1066 
1067     private void applyDefaults( final ModelContext context, final Modules modules, final Implementation implementation,
1068                                 final SourceFilesType sourceFilesType )
1069     {
1070         if ( context == null )
1071         {
1072             throw new NullPointerException( "context" );
1073         }
1074         if ( modules == null )
1075         {
1076             throw new NullPointerException( "modules" );
1077         }
1078         if ( implementation == null )
1079         {
1080             throw new NullPointerException( "implementation" );
1081         }
1082         if ( sourceFilesType == null )
1083         {
1084             throw new NullPointerException( "sourceFilesType" );
1085         }
1086 
1087         String contextHeadComment = this.getHeadComment();
1088         if ( ( DEFAULT_HEAD_COMMENT != null
1089                ? DEFAULT_HEAD_COMMENT.equals( contextHeadComment )
1090                : contextHeadComment == null )
1091                  && context.getAttribute( HEAD_COMMENT_ATTRIBUTE_NAME ) instanceof String )
1092         {
1093             contextHeadComment = (String) context.getAttribute( HEAD_COMMENT_ATTRIBUTE_NAME );
1094         }
1095 
1096         if ( contextHeadComment != null && contextHeadComment.length() == 0 )
1097         {
1098             contextHeadComment = null;
1099         }
1100 
1101         String contextTailComment = this.getTailComment();
1102         if ( ( DEFAULT_TAIL_COMMENT != null
1103                ? DEFAULT_TAIL_COMMENT.equals( contextTailComment )
1104                : contextTailComment == null )
1105                  && context.getAttribute( TAIL_COMMENT_ATTRIBUTE_NAME ) instanceof String )
1106         {
1107             contextTailComment = (String) context.getAttribute( TAIL_COMMENT_ATTRIBUTE_NAME );
1108         }
1109 
1110         if ( contextTailComment != null && contextTailComment.length() == 0 )
1111         {
1112             contextTailComment = null;
1113         }
1114 
1115         for ( int i = 0, s0 = sourceFilesType.getSourceFile().size(); i < s0; i++ )
1116         {
1117             final SourceFileType s = sourceFilesType.getSourceFile().get( i );
1118 
1119             if ( s.getTemplate() == null )
1120             {
1121                 s.setTemplate( IMPLEMENTATION_TEMPLATE );
1122             }
1123             if ( s.getLocation() == null )
1124             {
1125                 s.setLocation( this.getDefaultSourceFileLocation( context, modules, implementation ) );
1126             }
1127             if ( s.getHeadComment() == null )
1128             {
1129                 s.setHeadComment( contextHeadComment );
1130             }
1131             if ( s.getTailComment() == null )
1132             {
1133                 s.setTailComment( contextTailComment );
1134             }
1135 
1136             this.applyDefaults( context, modules, implementation, s.getSourceSections() );
1137         }
1138     }
1139 
1140     
1141 
1142 
1143 
1144 
1145 
1146 
1147 
1148 
1149 
1150     private void applyDefaults( final ModelContext context, final Modules modules, final Implementation implementation,
1151                                 final SourceSectionsType sourceSectionsType )
1152     {
1153         if ( context == null )
1154         {
1155             throw new NullPointerException( "context" );
1156         }
1157         if ( modules == null )
1158         {
1159             throw new NullPointerException( "modules" );
1160         }
1161         if ( implementation == null )
1162         {
1163             throw new NullPointerException( "implementation" );
1164         }
1165 
1166         final Specifications specifications = modules.getSpecifications( implementation.getIdentifier() );
1167         final Dependencies dependencies = modules.getDependencies( implementation.getIdentifier() );
1168         final Messages messages = modules.getMessages( implementation.getIdentifier() );
1169         final Properties properties = modules.getProperties( implementation.getIdentifier() );
1170 
1171         try
1172         {
1173             if ( sourceSectionsType != null )
1174             {
1175                 for ( int i = 0, s0 = sourceSectionsType.getSourceSection().size(); i < s0; i++ )
1176                 {
1177                     final SourceSectionType s = sourceSectionsType.getSourceSection().get( i );
1178 
1179                     if ( LICENSE_SECTION_NAME.equals( s.getName() ) )
1180                     {
1181                         if ( !isFieldSet( s, "optional" ) )
1182                         {
1183                             s.setOptional( true );
1184                         }
1185                         if ( s.getHeadTemplate() == null )
1186                         {
1187                             s.setHeadTemplate( IMPLEMENTATION_LICENSE_TEMPLATE );
1188                         }
1189                     }
1190 
1191                     if ( ANNOTATIONS_SECTION_NAME.equals( s.getName() ) )
1192                     {
1193                         if ( s.getHeadTemplate() == null )
1194                         {
1195                             s.setHeadTemplate( IMPLEMENTATION_ANNOTATIONS_TEMPLATE );
1196                         }
1197                     }
1198 
1199                     if ( DOCUMENTATION_SECTION_NAME.equals( s.getName() ) )
1200                     {
1201                         if ( !isFieldSet( s, "optional" ) )
1202                         {
1203                             s.setOptional( true );
1204                         }
1205                         if ( s.getHeadTemplate() == null )
1206                         {
1207                             s.setHeadTemplate( IMPLEMENTATION_DOCUMENTATION_TEMPLATE );
1208                         }
1209                     }
1210 
1211                     if ( CONSTRUCTORS_SECTION_NAME.equals( s.getName() ) )
1212                     {
1213                         if ( !isFieldSet( s, "indentationLevel" ) )
1214                         {
1215                             s.setIndentationLevel( 1 );
1216                         }
1217                         if ( s.getHeadTemplate() == null )
1218                         {
1219                             s.setHeadTemplate( CONSTRUCTORS_HEAD_TEMPLATE );
1220                         }
1221                         if ( s.getTailTemplate() == null )
1222                         {
1223                             s.setTailTemplate( CONSTRUCTORS_TAIL_TEMPLATE );
1224                         }
1225                         if ( !isFieldSet( s, "optional" ) )
1226                         {
1227                             s.setOptional( specifications == null || ( specifications.getSpecification().isEmpty()
1228                                                                        && specifications.getReference().isEmpty() ) );
1229 
1230                         }
1231                     }
1232 
1233                     if ( DEFAULT_CONSTRUCTOR_SECTION_NAME.equals( s.getName() ) )
1234                     {
1235                         if ( !isFieldSet( s, "editable" ) )
1236                         {
1237                             s.setEditable( true );
1238                         }
1239                         if ( !isFieldSet( s, "indentationLevel" ) )
1240                         {
1241                             s.setIndentationLevel( 2 );
1242                         }
1243                         if ( s.getHeadTemplate() == null )
1244                         {
1245                             s.setHeadTemplate( DEFAULT_CONSTRUCTOR_TEMPLATE );
1246                         }
1247                     }
1248 
1249                     if ( DEPENDENCIES_SECTION_NAME.equals( s.getName() ) )
1250                     {
1251                         if ( !isFieldSet( s, "optional" ) )
1252                         {
1253                             s.setOptional( dependencies == null || dependencies.getDependency().isEmpty() );
1254                         }
1255                         if ( !isFieldSet( s, "indentationLevel" ) )
1256                         {
1257                             s.setIndentationLevel( 1 );
1258                         }
1259                         if ( s.getHeadTemplate() == null )
1260                         {
1261                             s.setHeadTemplate( DEPENDENCIES_TEMPLATE );
1262                         }
1263                     }
1264 
1265                     if ( PROPERTIES_SECTION_NAME.equals( s.getName() ) )
1266                     {
1267                         if ( !isFieldSet( s, "optional" ) )
1268                         {
1269                             s.setOptional( properties == null || properties.getProperty().isEmpty() );
1270                         }
1271                         if ( !isFieldSet( s, "indentationLevel" ) )
1272                         {
1273                             s.setIndentationLevel( 1 );
1274                         }
1275                         if ( s.getHeadTemplate() == null )
1276                         {
1277                             s.setHeadTemplate( PROPERTIES_TEMPLATE );
1278                         }
1279                     }
1280 
1281                     if ( MESSAGES_SECTION_NAME.equals( s.getName() ) )
1282                     {
1283                         if ( !isFieldSet( s, "optional" ) )
1284                         {
1285                             s.setOptional( messages == null || messages.getMessage().isEmpty() );
1286                         }
1287                         if ( !isFieldSet( s, "indentationLevel" ) )
1288                         {
1289                             s.setIndentationLevel( 1 );
1290                         }
1291                         if ( s.getHeadTemplate() == null )
1292                         {
1293                             s.setHeadTemplate( MESSAGES_TEMPLATE );
1294                         }
1295                     }
1296 
1297                     if ( specifications != null )
1298                     {
1299                         for ( final Specification specification : specifications.getSpecification() )
1300                         {
1301                             final String sectionName =
1302                                 this.getDefaultSourceSectionName( context, modules, specification );
1303 
1304                             if ( sectionName != null && sectionName.equals( s.getName() ) )
1305                             {
1306                                 if ( !isFieldSet( s, "editable" ) )
1307                                 {
1308                                     s.setEditable( true );
1309                                 }
1310                                 if ( !isFieldSet( s, "indentationLevel" ) )
1311                                 {
1312                                     s.setIndentationLevel( 1 );
1313                                 }
1314                             }
1315                         }
1316                     }
1317 
1318                     final String sectionName = this.getDefaultSourceSectionName( context, modules, implementation );
1319 
1320                     if ( sectionName != null && sectionName.equals( s.getName() ) )
1321                     {
1322                         if ( !isFieldSet( s, "editable" ) )
1323                         {
1324                             s.setEditable( true );
1325                         }
1326                         if ( !isFieldSet( s, "indentationLevel" ) )
1327                         {
1328                             s.setIndentationLevel( 1 );
1329                         }
1330                     }
1331 
1332                     this.applyDefaults( context, modules, implementation, s.getSourceSections() );
1333                 }
1334             }
1335         }
1336         catch ( final NoSuchFieldException e )
1337         {
1338             throw new AssertionError( e );
1339         }
1340     }
1341 
1342     private static boolean isFieldSet( final Object object, final String fieldName ) throws NoSuchFieldException
1343     {
1344         final Field field = object.getClass().getDeclaredField( fieldName );
1345         final boolean accessible = field.isAccessible();
1346 
1347         try
1348         {
1349             field.setAccessible( true );
1350             return field.get( object ) != null;
1351         }
1352         catch ( final IllegalAccessException e )
1353         {
1354             throw new AssertionError( e );
1355         }
1356         finally
1357         {
1358             field.setAccessible( accessible );
1359         }
1360     }
1361 
1362     private static String getMessage( final Throwable t )
1363     {
1364         return t != null
1365                    ? t.getMessage() != null && t.getMessage().trim().length() > 0
1366                          ? t.getMessage()
1367                          : getMessage( t.getCause() )
1368                    : null;
1369 
1370     }
1371 
1372     private static String getMessage( final String key, final Object... args )
1373     {
1374         return MessageFormat.format( ResourceBundle.getBundle(
1375             ToolsModelProcessor.class.getName().replace( '.', '/' ), Locale.getDefault() ).getString( key ), args );
1376 
1377     }
1378 
1379 }