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;
32
33 import java.io.File;
34 import java.io.IOException;
35 import java.io.RandomAccessFile;
36 import java.io.StringWriter;
37 import java.nio.ByteBuffer;
38 import java.nio.channels.FileChannel;
39 import java.nio.channels.FileLock;
40 import java.text.MessageFormat;
41 import java.util.LinkedList;
42 import java.util.List;
43 import java.util.ResourceBundle;
44 import java.util.logging.Level;
45 import org.apache.commons.lang.StringUtils;
46 import org.apache.velocity.Template;
47 import org.apache.velocity.VelocityContext;
48 import org.apache.velocity.exception.VelocityException;
49 import org.jomc.model.Implementation;
50 import org.jomc.model.Implementations;
51 import org.jomc.model.Instance;
52 import org.jomc.model.Module;
53 import org.jomc.model.Specification;
54 import org.jomc.tools.model.SourceFileType;
55 import org.jomc.tools.model.SourceFilesType;
56 import org.jomc.tools.model.SourceSectionType;
57 import org.jomc.tools.model.SourceSectionsType;
58 import org.jomc.util.LineEditor;
59 import org.jomc.util.Section;
60 import org.jomc.util.SectionEditor;
61 import org.jomc.util.TrailingWhitespaceEditor;
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77 public class SourceFileProcessor extends JomcTool
78 {
79
80
81
82
83 private SourceFileProcessor.SourceFileEditor sourceFileEditor;
84
85
86
87
88 @Deprecated
89 private SourceFilesType sourceFilesType;
90
91
92
93
94 public SourceFileProcessor()
95 {
96 super();
97 }
98
99
100
101
102
103
104
105
106
107
108 public SourceFileProcessor( final SourceFileProcessor tool ) throws IOException
109 {
110 super( tool );
111 this.sourceFilesType = tool.sourceFilesType != null ? tool.sourceFilesType.clone() : null;
112 this.sourceFileEditor = tool.sourceFileEditor;
113 }
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130 @Deprecated
131 public SourceFilesType getSourceFilesType()
132 {
133 if ( this.sourceFilesType == null )
134 {
135 this.sourceFilesType = new SourceFilesType();
136 }
137
138 return this.sourceFilesType;
139 }
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154 @Deprecated
155 public SourceFileType getSourceFileType( final Specification specification )
156 {
157 if ( specification == null )
158 {
159 throw new NullPointerException( "specification" );
160 }
161
162 SourceFileType sourceFileType = null;
163
164 if ( this.getModules() != null
165 && this.getModules().getSpecification( specification.getIdentifier() ) != null )
166 {
167 sourceFileType = this.getSourceFilesType().getSourceFile( specification.getIdentifier() );
168
169 if ( sourceFileType == null )
170 {
171 sourceFileType = specification.getAnyObject( SourceFileType.class );
172 }
173 }
174 else if ( this.isLoggable( Level.WARNING ) )
175 {
176 this.log( Level.WARNING, getMessage( "specificationNotFound", specification.getIdentifier() ), null );
177 }
178
179 return sourceFileType;
180 }
181
182
183
184
185
186
187
188
189
190
191
192
193 public SourceFilesType getSourceFilesType( final Specification specification )
194 {
195 if ( specification == null )
196 {
197 throw new NullPointerException( "specification" );
198 }
199
200 SourceFilesType model = null;
201
202 if ( this.getModules() != null
203 && this.getModules().getSpecification( specification.getIdentifier() ) != null )
204 {
205 final SourceFileType sourceFileType = this.getSourceFileType( specification );
206
207 if ( sourceFileType != null )
208 {
209 model = new SourceFilesType();
210 model.getSourceFile().add( sourceFileType );
211 }
212 else
213 {
214 model = specification.getAnyObject( SourceFilesType.class );
215 }
216 }
217 else if ( this.isLoggable( Level.WARNING ) )
218 {
219 this.log( Level.WARNING, getMessage( "specificationNotFound", specification.getIdentifier() ), null );
220 }
221
222 return model;
223 }
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238 @Deprecated
239 public SourceFileType getSourceFileType( final Implementation implementation )
240 {
241 if ( implementation == null )
242 {
243 throw new NullPointerException( "implementation" );
244 }
245
246 SourceFileType sourceFileType = null;
247
248 if ( this.getModules() != null
249 && this.getModules().getImplementation( implementation.getIdentifier() ) != null )
250 {
251 sourceFileType = this.getSourceFilesType().getSourceFile( implementation.getIdentifier() );
252
253 if ( sourceFileType == null )
254 {
255 sourceFileType = implementation.getAnyObject( SourceFileType.class );
256 }
257 }
258 else if ( this.isLoggable( Level.WARNING ) )
259 {
260 this.log( Level.WARNING, getMessage( "implementationNotFound", implementation.getIdentifier() ), null );
261 }
262
263 return sourceFileType;
264 }
265
266
267
268
269
270
271
272
273
274
275
276
277 public SourceFilesType getSourceFilesType( final Implementation implementation )
278 {
279 if ( implementation == null )
280 {
281 throw new NullPointerException( "implementation" );
282 }
283
284 SourceFilesType model = null;
285
286 if ( this.getModules() != null
287 && this.getModules().getImplementation( implementation.getIdentifier() ) != null )
288 {
289 final SourceFileType sourceFileType = this.getSourceFileType( implementation );
290
291 if ( sourceFileType != null )
292 {
293 model = new SourceFilesType();
294 model.getSourceFile().add( sourceFileType );
295 }
296 else
297 {
298 final Instance instance = this.getModules().getInstance( implementation.getIdentifier() );
299 assert instance != null : "Instance '" + implementation.getIdentifier() + "' not found.";
300 model = instance.getAnyObject( SourceFilesType.class );
301 }
302 }
303 else if ( this.isLoggable( Level.WARNING ) )
304 {
305 this.log( Level.WARNING, getMessage( "implementationNotFound", implementation.getIdentifier() ), null );
306 }
307
308 return model;
309 }
310
311
312
313
314
315
316
317
318
319
320 public final SourceFileProcessor.SourceFileEditor getSourceFileEditor()
321 {
322 if ( this.sourceFileEditor == null )
323 {
324 this.sourceFileEditor =
325 new SourceFileProcessor.SourceFileEditor( new TrailingWhitespaceEditor( this.getLineSeparator() ),
326 this.getLineSeparator() );
327
328 }
329
330 return this.sourceFileEditor;
331 }
332
333
334
335
336
337
338
339
340
341
342 public final void setSourceFileEditor( final SourceFileProcessor.SourceFileEditor value )
343 {
344 this.sourceFileEditor = value;
345 }
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361 @Deprecated
362 public SourceFileProcessor.SourceFileEditor getSourceFileEditor( final Specification specification )
363 {
364 if ( specification == null )
365 {
366 throw new NullPointerException( "specification" );
367 }
368
369 return this.getSourceFileEditor();
370 }
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386 @Deprecated
387 public SourceFileProcessor.SourceFileEditor getSourceFileEditor( final Implementation implementation )
388 {
389 if ( implementation == null )
390 {
391 throw new NullPointerException( "implementation" );
392 }
393
394 return this.getSourceFileEditor();
395 }
396
397
398
399
400
401
402
403
404
405
406
407 public void manageSourceFiles( final File sourcesDirectory ) throws IOException
408 {
409 if ( sourcesDirectory == null )
410 {
411 throw new NullPointerException( "sourcesDirectory" );
412 }
413
414 if ( this.getModules() != null )
415 {
416 for ( int i = this.getModules().getModule().size() - 1; i >= 0; i-- )
417 {
418 this.manageSourceFiles( this.getModules().getModule().get( i ), sourcesDirectory );
419 }
420 }
421 else if ( this.isLoggable( Level.WARNING ) )
422 {
423 this.log( Level.WARNING, getMessage( "modulesNotFound", this.getModel().getIdentifier() ), null );
424 }
425 }
426
427
428
429
430
431
432
433
434
435
436
437
438
439 public void manageSourceFiles( final Module module, final File sourcesDirectory ) throws IOException
440 {
441 if ( module == null )
442 {
443 throw new NullPointerException( "module" );
444 }
445 if ( sourcesDirectory == null )
446 {
447 throw new NullPointerException( "sourcesDirectory" );
448 }
449
450 if ( this.getModules() != null && this.getModules().getModule( module.getName() ) != null )
451 {
452 if ( module.getSpecifications() != null )
453 {
454 for ( int i = 0, s0 = module.getSpecifications().getSpecification().size(); i < s0; i++ )
455 {
456 this.manageSourceFiles( module.getSpecifications().getSpecification().get( i ), sourcesDirectory );
457 }
458 }
459 if ( module.getImplementations() != null )
460 {
461 for ( int i = 0, s0 = module.getImplementations().getImplementation().size(); i < s0; i++ )
462 {
463 this.manageSourceFiles( module.getImplementations().getImplementation().get( i ), sourcesDirectory );
464 }
465 }
466 }
467 else if ( this.isLoggable( Level.WARNING ) )
468 {
469 this.log( Level.WARNING, getMessage( "moduleNotFound", module.getName() ), null );
470 }
471 }
472
473
474
475
476
477
478
479
480
481
482
483
484
485 public void manageSourceFiles( final Specification specification, final File sourcesDirectory ) throws IOException
486 {
487 if ( specification == null )
488 {
489 throw new NullPointerException( "specification" );
490 }
491 if ( sourcesDirectory == null )
492 {
493 throw new NullPointerException( "sourcesDirectory" );
494 }
495
496 if ( this.getModules() != null
497 && this.getModules().getSpecification( specification.getIdentifier() ) != null )
498 {
499 if ( specification.isClassDeclaration() )
500 {
501 boolean manage = true;
502 final Implementations implementations = this.getModules().getImplementations();
503
504 if ( implementations != null )
505 {
506 for ( int i = 0, s0 = implementations.getImplementation().size(); i < s0; i++ )
507 {
508 final Implementation impl = implementations.getImplementation().get( i );
509
510 if ( impl.isClassDeclaration() && specification.getClazz().equals( impl.getClazz() ) )
511 {
512 this.manageSourceFiles( impl, sourcesDirectory );
513 manage = false;
514 break;
515 }
516 }
517 }
518
519 if ( manage )
520 {
521 final SourceFilesType model = this.getSourceFilesType( specification );
522
523 if ( model != null )
524 {
525 for ( int i = 0, s0 = model.getSourceFile().size(); i < s0; i++ )
526 {
527 this.getSourceFileEditor().edit(
528 specification, model.getSourceFile().get( i ), sourcesDirectory );
529
530 }
531 }
532 }
533 }
534 }
535 else if ( this.isLoggable( Level.WARNING ) )
536 {
537 this.log( Level.WARNING, getMessage( "specificationNotFound", specification.getIdentifier() ), null );
538 }
539 }
540
541
542
543
544
545
546
547
548
549
550
551
552
553 public void manageSourceFiles( final Implementation implementation, final File sourcesDirectory )
554 throws IOException
555 {
556 if ( implementation == null )
557 {
558 throw new NullPointerException( "implementation" );
559 }
560 if ( sourcesDirectory == null )
561 {
562 throw new NullPointerException( "sourcesDirectory" );
563 }
564
565 if ( this.getModules() != null
566 && this.getModules().getImplementation( implementation.getIdentifier() ) != null )
567 {
568 if ( implementation.isClassDeclaration() )
569 {
570 final SourceFilesType model = this.getSourceFilesType( implementation );
571
572 if ( model != null )
573 {
574 for ( int i = 0, s0 = model.getSourceFile().size(); i < s0; i++ )
575 {
576 this.getSourceFileEditor().edit(
577 implementation, model.getSourceFile().get( i ), sourcesDirectory );
578
579 }
580 }
581 }
582 }
583 else if ( this.isLoggable( Level.WARNING ) )
584 {
585 this.log( Level.WARNING, getMessage( "implementationNotFound", implementation.getIdentifier() ), null );
586 }
587 }
588
589 private static String getMessage( final String key, final Object... arguments )
590 {
591 if ( key == null )
592 {
593 throw new NullPointerException( "key" );
594 }
595
596 return MessageFormat.format( ResourceBundle.getBundle(
597 SourceFileProcessor.class.getName().replace( '.', '/' ) ).getString( key ), arguments );
598
599 }
600
601 private static String getMessage( final Throwable t )
602 {
603 return t != null
604 ? t.getMessage() != null && t.getMessage().trim().length() > 0
605 ? t.getMessage()
606 : getMessage( t.getCause() )
607 : null;
608
609 }
610
611
612
613
614
615
616
617
618
619
620 public class SourceFileEditor extends SectionEditor
621 {
622
623
624
625
626 private Specification specification;
627
628
629
630
631 private Implementation implementation;
632
633
634
635
636 private SourceFileType sourceFileType;
637
638
639
640
641 private VelocityContext velocityContext;
642
643
644
645
646 @Deprecated
647 private List<Section> addedSections;
648
649
650
651
652 @Deprecated
653 private List<Section> unknownSections;
654
655
656
657
658
659
660 public SourceFileEditor()
661 {
662 this( (LineEditor) null, (String) null );
663 }
664
665
666
667
668
669
670
671
672 public SourceFileEditor( final String lineSeparator )
673 {
674 this( (LineEditor) null, lineSeparator );
675 }
676
677
678
679
680
681
682
683
684 public SourceFileEditor( final LineEditor editor )
685 {
686 this( editor, null );
687 }
688
689
690
691
692
693
694
695
696
697
698 public SourceFileEditor( final LineEditor editor, final String lineSeparator )
699 {
700 super( editor, lineSeparator );
701 }
702
703
704
705
706
707
708
709
710
711 @Deprecated
712 public SourceFileEditor( final Specification specification )
713 {
714 this( specification, null, null );
715 }
716
717
718
719
720
721
722
723
724
725
726
727 @Deprecated
728 public SourceFileEditor( final Specification specification, final String lineSeparator )
729 {
730 this( specification, null, lineSeparator );
731 }
732
733
734
735
736
737
738
739
740
741
742
743 @Deprecated
744 public SourceFileEditor( final Specification specification, final LineEditor lineEditor )
745 {
746 this( specification, lineEditor, null );
747 }
748
749
750
751
752
753
754
755
756
757
758
759
760 @Deprecated
761 public SourceFileEditor( final Specification specification, final LineEditor lineEditor,
762 final String lineSeparator )
763 {
764 super( lineEditor, lineSeparator );
765 this.specification = specification;
766 this.implementation = null;
767
768 assert getModules().getSpecification( specification.getIdentifier() ) != null :
769 "Specification '" + specification.getIdentifier() + "' not found.";
770
771 }
772
773
774
775
776
777
778
779
780
781 @Deprecated
782 public SourceFileEditor( final Implementation implementation )
783 {
784 this( implementation, null, null );
785 }
786
787
788
789
790
791
792
793
794
795
796
797 @Deprecated
798 public SourceFileEditor( final Implementation implementation, final String lineSeparator )
799 {
800 this( implementation, null, lineSeparator );
801 }
802
803
804
805
806
807
808
809
810
811
812
813 @Deprecated
814 public SourceFileEditor( final Implementation implementation, final LineEditor lineEditor )
815 {
816 this( implementation, lineEditor, null );
817 }
818
819
820
821
822
823
824
825
826
827
828
829
830 @Deprecated
831 public SourceFileEditor( final Implementation implementation, final LineEditor lineEditor,
832 final String lineSeparator )
833 {
834 super( lineEditor, lineSeparator );
835 this.implementation = implementation;
836 this.specification = null;
837
838 assert getModules().getImplementation( implementation.getIdentifier() ) != null :
839 "Implementation '" + implementation.getIdentifier() + "' not found.";
840
841 }
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856 public final void edit( final Specification specification, final SourceFileType sourceFileType,
857 final File sourcesDirectory ) throws IOException
858 {
859 if ( specification == null )
860 {
861 throw new NullPointerException( "specification" );
862 }
863 if ( sourceFileType == null )
864 {
865 throw new NullPointerException( "sourceFileType" );
866 }
867 if ( sourcesDirectory == null )
868 {
869 throw new NullPointerException( "sourcesDirectory" );
870 }
871
872 try
873 {
874 if ( getModules() != null
875 && getModules().getSpecification( specification.getIdentifier() ) != null )
876 {
877 this.specification = specification;
878 this.sourceFileType = sourceFileType;
879 this.velocityContext = SourceFileProcessor.this.getVelocityContext();
880 this.velocityContext.put( "specification", specification );
881 this.velocityContext.put( "smodel", sourceFileType );
882
883 this.editSourceFile( sourcesDirectory );
884 }
885 else
886 {
887 throw new IOException( getMessage( "specificationNotFound", specification.getIdentifier() ) );
888 }
889 }
890 finally
891 {
892 this.specification = null;
893 this.implementation = null;
894 this.sourceFileType = null;
895 this.velocityContext = null;
896 }
897 }
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912 public final void edit( final Implementation implementation, final SourceFileType sourceFileType,
913 final File sourcesDirectory ) throws IOException
914 {
915 if ( implementation == null )
916 {
917 throw new NullPointerException( "implementation" );
918 }
919 if ( sourceFileType == null )
920 {
921 throw new NullPointerException( "sourceFileType" );
922 }
923 if ( sourcesDirectory == null )
924 {
925 throw new NullPointerException( "sourcesDirectory" );
926 }
927
928 try
929 {
930 if ( getModules() != null
931 && getModules().getImplementation( implementation.getIdentifier() ) != null )
932 {
933 this.implementation = implementation;
934 this.sourceFileType = sourceFileType;
935 this.velocityContext = SourceFileProcessor.this.getVelocityContext();
936 this.velocityContext.put( "implementation", implementation );
937 this.velocityContext.put( "smodel", sourceFileType );
938
939 this.editSourceFile( sourcesDirectory );
940 }
941 else
942 {
943 throw new IOException( getMessage( "implementationNotFound", implementation.getIdentifier() ) );
944 }
945 }
946 finally
947 {
948 this.specification = null;
949 this.implementation = null;
950 this.sourceFileType = null;
951 this.velocityContext = null;
952 }
953 }
954
955
956
957
958
959
960
961
962
963
964
965
966
967 @Deprecated
968 public List<Section> getAddedSections()
969 {
970 if ( this.addedSections == null )
971 {
972 this.addedSections = new LinkedList<Section>();
973 }
974
975 return this.addedSections;
976 }
977
978
979
980
981
982
983
984
985
986
987
988
989
990 @Deprecated
991 public List<Section> getUnknownSections()
992 {
993 if ( this.unknownSections == null )
994 {
995 this.unknownSections = new LinkedList<Section>();
996 }
997
998 return this.unknownSections;
999 }
1000
1001
1002
1003
1004
1005
1006
1007
1008 @Deprecated
1009 protected SourceFileType getSourceFileType()
1010 {
1011 if ( this.sourceFileType == null )
1012 {
1013 if ( this.specification != null )
1014 {
1015 return SourceFileProcessor.this.getSourceFileType( this.specification );
1016 }
1017
1018 if ( this.implementation != null )
1019 {
1020 return SourceFileProcessor.this.getSourceFileType( this.implementation );
1021 }
1022 }
1023
1024 return this.sourceFileType;
1025 }
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036 @Deprecated
1037 protected VelocityContext getVelocityContext() throws IOException
1038 {
1039 if ( this.velocityContext == null )
1040 {
1041 final VelocityContext ctx = SourceFileProcessor.this.getVelocityContext();
1042
1043 if ( this.specification != null )
1044 {
1045 ctx.put( "specification", this.specification );
1046 }
1047
1048 if ( this.implementation != null )
1049 {
1050 ctx.put( "implementation", this.implementation );
1051 }
1052
1053 return ctx;
1054 }
1055
1056 return this.velocityContext;
1057 }
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070 @Override
1071 protected String getOutput( final Section section ) throws IOException
1072 {
1073 this.getAddedSections().clear();
1074 this.getUnknownSections().clear();
1075
1076 final SourceFileType model = this.getSourceFileType();
1077
1078 if ( model != null )
1079 {
1080 this.createSections( model, model.getSourceSections(), section );
1081 }
1082
1083 return super.getOutput( section );
1084 }
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096 @Override
1097 protected void editSection( final Section s ) throws IOException
1098 {
1099 try
1100 {
1101 super.editSection( s );
1102
1103 final SourceFileType model = this.getSourceFileType();
1104
1105 if ( s.getName() != null && model != null && model.getSourceSections() != null )
1106 {
1107 final SourceSectionType sourceSectionType =
1108 model.getSourceSections().getSourceSection( s.getName() );
1109
1110 if ( sourceSectionType != null )
1111 {
1112 if ( s.getStartingLine() != null )
1113 {
1114 s.setStartingLine( getIndentation( sourceSectionType.getIndentationLevel() )
1115 + s.getStartingLine().trim() );
1116
1117 }
1118 if ( s.getEndingLine() != null )
1119 {
1120 s.setEndingLine( getIndentation( sourceSectionType.getIndentationLevel() )
1121 + s.getEndingLine().trim() );
1122
1123 }
1124
1125 if ( sourceSectionType.getHeadTemplate() != null
1126 && ( !sourceSectionType.isEditable()
1127 || s.getHeadContent().toString().trim().length() == 0 ) )
1128 {
1129 final StringWriter writer = new StringWriter();
1130 final Template template = getVelocityTemplate( sourceSectionType.getHeadTemplate() );
1131 final VelocityContext ctx = getVelocityContext();
1132 ctx.put( "template", template );
1133 ctx.put( "ssection", sourceSectionType );
1134 template.merge( ctx, writer );
1135 writer.close();
1136 s.getHeadContent().setLength( 0 );
1137 s.getHeadContent().append( writer.toString() );
1138 ctx.remove( "template" );
1139 ctx.remove( "ssection" );
1140 }
1141
1142 if ( sourceSectionType.getTailTemplate() != null
1143 && ( !sourceSectionType.isEditable()
1144 || s.getTailContent().toString().trim().length() == 0 ) )
1145 {
1146 final StringWriter writer = new StringWriter();
1147 final Template template = getVelocityTemplate( sourceSectionType.getTailTemplate() );
1148 final VelocityContext ctx = getVelocityContext();
1149 ctx.put( "template", template );
1150 ctx.put( "ssection", sourceSectionType );
1151 template.merge( ctx, writer );
1152 writer.close();
1153 s.getTailContent().setLength( 0 );
1154 s.getTailContent().append( writer.toString() );
1155 ctx.remove( "template" );
1156 ctx.remove( "ssection" );
1157 }
1158 }
1159 else
1160 {
1161 if ( isLoggable( Level.WARNING ) )
1162 {
1163 if ( this.implementation != null )
1164 {
1165 final Module m =
1166 getModules().getModuleOfImplementation( this.implementation.getIdentifier() );
1167
1168 log( Level.WARNING, getMessage(
1169 "unknownImplementationSection", m.getName(), this.implementation.getIdentifier(),
1170 model.getIdentifier(), s.getName() ), null );
1171
1172 }
1173 else if ( this.specification != null )
1174 {
1175 final Module m =
1176 getModules().getModuleOfSpecification( this.specification.getIdentifier() );
1177
1178 log( Level.WARNING, getMessage(
1179 "unknownSpecificationSection", m.getName(), this.specification.getIdentifier(),
1180 model.getIdentifier(), s.getName() ), null );
1181
1182 }
1183 }
1184
1185 this.getUnknownSections().add( s );
1186 }
1187 }
1188 }
1189 catch ( final VelocityException e )
1190 {
1191
1192 throw (IOException) new IOException( getMessage( e ) ).initCause( e );
1193 }
1194 }
1195
1196 private void createSections( final SourceFileType sourceFileType, final SourceSectionsType sourceSectionsType,
1197 final Section section ) throws IOException
1198 {
1199 if ( sourceSectionsType != null && section != null )
1200 {
1201 for ( int i = 0, s0 = sourceSectionsType.getSourceSection().size(); i < s0; i++ )
1202 {
1203 final SourceSectionType sourceSectionType = sourceSectionsType.getSourceSection().get( i );
1204 Section childSection = section.getSection( sourceSectionType.getName() );
1205
1206 if ( childSection == null && !sourceSectionType.isOptional() )
1207 {
1208 childSection = this.createSection( StringUtils.defaultString( sourceFileType.getHeadComment() ),
1209 StringUtils.defaultString( sourceFileType.getTailComment() ),
1210 sourceSectionType );
1211
1212 section.getSections().add( childSection );
1213
1214 if ( isLoggable( Level.FINE ) )
1215 {
1216 log( Level.FINE, getMessage(
1217 "addedSection", sourceFileType.getIdentifier(), childSection.getName() ), null );
1218
1219 }
1220
1221 this.getAddedSections().add( childSection );
1222 }
1223
1224 this.createSections( sourceFileType, sourceSectionType.getSourceSections(), childSection );
1225 }
1226 }
1227 }
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244 private Section createSection( final String headComment, final String tailComment,
1245 final SourceSectionType sourceSectionType ) throws IOException
1246 {
1247 if ( headComment == null )
1248 {
1249 throw new NullPointerException( "headComment" );
1250 }
1251 if ( tailComment == null )
1252 {
1253 throw new NullPointerException( "tailComment" );
1254 }
1255 if ( sourceSectionType == null )
1256 {
1257 throw new NullPointerException( "sourceSectionType" );
1258 }
1259
1260 final Section s = new Section();
1261 s.setName( sourceSectionType.getName() );
1262
1263 final StringBuilder head = new StringBuilder( 255 );
1264 head.append( getIndentation( sourceSectionType.getIndentationLevel() ) ).append( headComment );
1265
1266 s.setStartingLine( head + " SECTION-START[" + sourceSectionType.getName() + ']' + tailComment );
1267 s.setEndingLine( head + " SECTION-END" + tailComment );
1268
1269 return s;
1270 }
1271
1272 private void editSourceFile( final File sourcesDirectory ) throws IOException
1273 {
1274 if ( sourcesDirectory == null )
1275 {
1276 throw new NullPointerException( "sourcesDirectory" );
1277 }
1278 if ( !sourcesDirectory.isDirectory() )
1279 {
1280 throw new IOException( getMessage( "directoryNotFound", sourcesDirectory.getAbsolutePath() ) );
1281 }
1282
1283 final SourceFileType model = this.getSourceFileType();
1284
1285 if ( model != null && model.getLocation() != null )
1286 {
1287 final File f = new File( sourcesDirectory, model.getLocation() );
1288
1289 try
1290 {
1291 String content = "";
1292 String edited = null;
1293 boolean creating = false;
1294
1295 if ( !f.exists() )
1296 {
1297 if ( model.getTemplate() != null )
1298 {
1299 final StringWriter writer = new StringWriter();
1300 final Template template = getVelocityTemplate( model.getTemplate() );
1301 final VelocityContext ctx = this.getVelocityContext();
1302 ctx.put( "template", template );
1303 template.merge( ctx, writer );
1304 writer.close();
1305 content = writer.toString();
1306 ctx.remove( "template" );
1307 creating = true;
1308 }
1309 }
1310 else
1311 {
1312 if ( isLoggable( Level.FINER ) )
1313 {
1314 log( Level.FINER, getMessage( "reading", f.getAbsolutePath() ), null );
1315 }
1316
1317 content = this.readSourceFile( f );
1318 }
1319
1320 try
1321 {
1322 edited = super.edit( content );
1323 }
1324 catch ( final IOException e )
1325 {
1326
1327 throw (IOException) new IOException( getMessage(
1328 "failedEditing", f.getAbsolutePath(), getMessage( e ) ) ).initCause( e );
1329
1330 }
1331
1332 if ( !edited.equals( content ) || edited.length() == 0 )
1333 {
1334 if ( !f.getParentFile().exists() && !f.getParentFile().mkdirs() )
1335 {
1336 throw new IOException( getMessage(
1337 "failedCreatingDirectory", f.getParentFile().getAbsolutePath() ) );
1338
1339 }
1340
1341 if ( isLoggable( Level.INFO ) )
1342 {
1343 log( Level.INFO, getMessage(
1344 creating ? "creating" : "editing", f.getAbsolutePath() ), null );
1345
1346 }
1347
1348 this.writeSourceFile( f, edited );
1349 }
1350 else if ( isLoggable( Level.FINER ) )
1351 {
1352 log( Level.FINER, getMessage( "unchanged", f.getAbsolutePath() ), null );
1353 }
1354 }
1355 catch ( final VelocityException e )
1356 {
1357
1358 throw (IOException) new IOException( getMessage(
1359 "failedEditing", f.getAbsolutePath(), getMessage( e ) ) ).initCause( e );
1360
1361 }
1362 }
1363 }
1364
1365 private String readSourceFile( final File file ) throws IOException
1366 {
1367 if ( file == null )
1368 {
1369 throw new NullPointerException( "file" );
1370 }
1371
1372 RandomAccessFile randomAccessFile = null;
1373 FileChannel fileChannel = null;
1374 FileLock fileLock = null;
1375 boolean suppressExceptionOnClose = true;
1376
1377
1378 final int length = file.length() > 0L ? Long.valueOf( file.length() ).intValue() : 1;
1379 final ByteBuffer buf = ByteBuffer.allocate( length );
1380 final StringBuilder appendable = new StringBuilder( length );
1381
1382 try
1383 {
1384 randomAccessFile = new RandomAccessFile( file, "r" );
1385 fileChannel = randomAccessFile.getChannel();
1386 fileLock = fileChannel.lock( 0L, file.length(), true );
1387 fileChannel.position( 0L );
1388
1389 buf.clear();
1390 int read = fileChannel.read( buf );
1391
1392 while ( read != -1 )
1393 {
1394
1395 appendable.append( new String( buf.array(), buf.arrayOffset(), read, getInputEncoding() ) );
1396 buf.clear();
1397 read = fileChannel.read( buf );
1398 }
1399
1400 suppressExceptionOnClose = false;
1401 return appendable.toString();
1402 }
1403 finally
1404 {
1405 this.releaseAndClose( fileLock, fileChannel, randomAccessFile, suppressExceptionOnClose );
1406 }
1407 }
1408
1409 private void writeSourceFile( final File file, final String content ) throws IOException
1410 {
1411 if ( file == null )
1412 {
1413 throw new NullPointerException( "file" );
1414 }
1415 if ( content == null )
1416 {
1417 throw new NullPointerException( "content" );
1418 }
1419
1420 RandomAccessFile randomAccessFile = null;
1421 FileChannel fileChannel = null;
1422 FileLock fileLock = null;
1423 boolean suppressExceptionOnClose = true;
1424 final byte[] bytes = content.getBytes( getOutputEncoding() );
1425
1426 try
1427 {
1428 randomAccessFile = new RandomAccessFile( file, "rw" );
1429 fileChannel = randomAccessFile.getChannel();
1430 fileLock = fileChannel.lock( 0L, bytes.length, false );
1431 fileChannel.truncate( bytes.length );
1432 fileChannel.position( 0L );
1433 fileChannel.write( ByteBuffer.wrap( bytes ) );
1434 fileChannel.force( true );
1435 suppressExceptionOnClose = false;
1436 }
1437 finally
1438 {
1439 this.releaseAndClose( fileLock, fileChannel, randomAccessFile, suppressExceptionOnClose );
1440 }
1441 }
1442
1443 private void releaseAndClose( final FileLock fileLock, final FileChannel fileChannel,
1444 final RandomAccessFile randomAccessFile, final boolean suppressExceptions )
1445 throws IOException
1446 {
1447 try
1448 {
1449 if ( fileLock != null )
1450 {
1451 fileLock.release();
1452 }
1453 }
1454 catch ( final IOException e )
1455 {
1456 if ( suppressExceptions )
1457 {
1458 log( Level.SEVERE, null, e );
1459 }
1460 else
1461 {
1462 throw e;
1463 }
1464 }
1465 finally
1466 {
1467 try
1468 {
1469 if ( fileChannel != null )
1470 {
1471 fileChannel.close();
1472 }
1473 }
1474 catch ( final IOException e )
1475 {
1476 if ( suppressExceptions )
1477 {
1478 log( Level.SEVERE, null, e );
1479 }
1480 else
1481 {
1482 throw e;
1483 }
1484 }
1485 finally
1486 {
1487 try
1488 {
1489 if ( randomAccessFile != null )
1490 {
1491 randomAccessFile.close();
1492 }
1493 }
1494 catch ( final IOException e )
1495 {
1496 if ( suppressExceptions )
1497 {
1498 log( Level.SEVERE, null, e );
1499 }
1500 else
1501 {
1502 throw e;
1503 }
1504 }
1505 }
1506 }
1507 }
1508
1509 }
1510
1511 }