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