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.ByteArrayInputStream;
34 import java.io.ByteArrayOutputStream;
35 import java.io.Closeable;
36 import java.io.File;
37 import java.io.FileInputStream;
38 import java.io.IOException;
39 import java.io.InputStream;
40 import java.io.RandomAccessFile;
41 import java.net.URL;
42 import java.nio.ByteBuffer;
43 import java.nio.channels.FileChannel;
44 import java.nio.channels.FileLock;
45 import java.text.MessageFormat;
46 import java.util.List;
47 import java.util.ResourceBundle;
48 import java.util.logging.Level;
49 import java.util.zip.GZIPInputStream;
50 import java.util.zip.GZIPOutputStream;
51 import javax.xml.bind.JAXBElement;
52 import javax.xml.bind.JAXBException;
53 import javax.xml.bind.Marshaller;
54 import javax.xml.bind.Unmarshaller;
55 import javax.xml.bind.util.JAXBResult;
56 import javax.xml.bind.util.JAXBSource;
57 import javax.xml.transform.Transformer;
58 import javax.xml.transform.TransformerException;
59 import javax.xml.validation.Schema;
60 import org.apache.bcel.classfile.Attribute;
61 import org.apache.bcel.classfile.ClassParser;
62 import org.apache.bcel.classfile.Constant;
63 import org.apache.bcel.classfile.ConstantPool;
64 import org.apache.bcel.classfile.ConstantUtf8;
65 import org.apache.bcel.classfile.JavaClass;
66 import org.apache.bcel.classfile.Unknown;
67 import org.jomc.model.Dependencies;
68 import org.jomc.model.Dependency;
69 import org.jomc.model.Implementation;
70 import org.jomc.model.Implementations;
71 import org.jomc.model.Message;
72 import org.jomc.model.Messages;
73 import org.jomc.model.ModelObject;
74 import org.jomc.model.Module;
75 import org.jomc.model.ObjectFactory;
76 import org.jomc.model.Properties;
77 import org.jomc.model.Property;
78 import org.jomc.model.Specification;
79 import org.jomc.model.SpecificationReference;
80 import org.jomc.model.Specifications;
81 import org.jomc.modlet.ModelContext;
82 import org.jomc.modlet.ModelException;
83 import org.jomc.modlet.ModelValidationReport;
84 import org.jomc.util.ParseException;
85 import org.jomc.util.TokenMgrError;
86 import org.jomc.util.VersionParser;
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115 public class ClassFileProcessor extends JomcTool
116 {
117
118
119 private static final byte[] NO_BYTES =
120 {
121 };
122
123
124 public ClassFileProcessor()
125 {
126 super();
127 }
128
129
130
131
132
133
134
135
136
137
138 public ClassFileProcessor( final ClassFileProcessor tool ) throws IOException
139 {
140 super( tool );
141 }
142
143
144
145
146
147
148
149
150
151
152
153
154 public final void commitModelObjects( final ModelContext context, final File classesDirectory ) throws IOException
155 {
156 if ( context == null )
157 {
158 throw new NullPointerException( "context" );
159 }
160 if ( classesDirectory == null )
161 {
162 throw new NullPointerException( "classesDirectory" );
163 }
164
165 try
166 {
167 if ( this.getModules() != null )
168 {
169 final Marshaller m = context.createMarshaller( this.getModel().getIdentifier() );
170 m.setSchema( context.createSchema( this.getModel().getIdentifier() ) );
171
172 this.commitModelObjects( this.getModules().getSpecifications(), this.getModules().getImplementations(),
173 m, classesDirectory );
174
175 }
176 else if ( this.isLoggable( Level.WARNING ) )
177 {
178 this.log( Level.WARNING, getMessage( "modulesNotFound", this.getModel().getIdentifier() ), null );
179 }
180 }
181 catch ( final ModelException e )
182 {
183
184 throw (IOException) new IOException( getMessage( e ) ).initCause( e );
185 }
186 }
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201 public final void commitModelObjects( final Module module, final ModelContext context, final File classesDirectory )
202 throws IOException
203 {
204 if ( module == null )
205 {
206 throw new NullPointerException( "module" );
207 }
208 if ( context == null )
209 {
210 throw new NullPointerException( "context" );
211 }
212 if ( classesDirectory == null )
213 {
214 throw new NullPointerException( "classesDirectory" );
215 }
216
217 try
218 {
219 if ( this.getModules() != null && this.getModules().getModule( module.getName() ) != null )
220 {
221 final Marshaller m = context.createMarshaller( this.getModel().getIdentifier() );
222 m.setSchema( context.createSchema( this.getModel().getIdentifier() ) );
223
224 this.commitModelObjects( module.getSpecifications(), module.getImplementations(), m, classesDirectory );
225 }
226 else if ( this.isLoggable( Level.WARNING ) )
227 {
228 this.log( Level.WARNING, getMessage( "moduleNotFound", module.getName() ), null );
229 }
230 }
231 catch ( final ModelException e )
232 {
233
234 throw (IOException) new IOException( getMessage( e ) ).initCause( e );
235 }
236 }
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251 public final void commitModelObjects( final Specification specification, final ModelContext context,
252 final File classesDirectory ) throws IOException
253 {
254 if ( specification == null )
255 {
256 throw new NullPointerException( "specification" );
257 }
258 if ( context == null )
259 {
260 throw new NullPointerException( "context" );
261 }
262 if ( classesDirectory == null )
263 {
264 throw new NullPointerException( "classesDirectory" );
265 }
266
267 try
268 {
269 if ( this.getModules() != null
270 && this.getModules().getSpecification( specification.getIdentifier() ) != null )
271 {
272 final Marshaller m = context.createMarshaller( this.getModel().getIdentifier() );
273 m.setSchema( context.createSchema( this.getModel().getIdentifier() ) );
274
275 this.commitModelObjects( specification, m, classesDirectory );
276 }
277 else if ( this.isLoggable( Level.WARNING ) )
278 {
279 this.log( Level.WARNING, getMessage( "specificationNotFound", specification.getIdentifier() ), null );
280 }
281 }
282 catch ( final ModelException e )
283 {
284
285 throw (IOException) new IOException( getMessage( e ) ).initCause( e );
286 }
287 }
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302 public final void commitModelObjects( final Implementation implementation, final ModelContext context,
303 final File classesDirectory ) throws IOException
304 {
305 if ( implementation == null )
306 {
307 throw new NullPointerException( "implementation" );
308 }
309 if ( context == null )
310 {
311 throw new NullPointerException( "context" );
312 }
313 if ( classesDirectory == null )
314 {
315 throw new NullPointerException( "classesDirectory" );
316 }
317
318 try
319 {
320 if ( this.getModules() != null
321 && this.getModules().getImplementation( implementation.getIdentifier() ) != null )
322 {
323 final Marshaller m = context.createMarshaller( this.getModel().getIdentifier() );
324 m.setSchema( context.createSchema( this.getModel().getIdentifier() ) );
325
326 this.commitModelObjects( implementation, m, classesDirectory );
327 }
328 else if ( this.isLoggable( Level.WARNING ) )
329 {
330 this.log( Level.WARNING, getMessage( "implementationNotFound", implementation.getIdentifier() ), null );
331 }
332 }
333 catch ( final ModelException e )
334 {
335
336 throw (IOException) new IOException( getMessage( e ) ).initCause( e );
337 }
338 }
339
340
341
342
343
344
345
346
347
348
349
350 public void commitModelObjects( final Specification specification, final Marshaller marshaller,
351 final JavaClass javaClass ) throws IOException
352 {
353 if ( specification == null )
354 {
355 throw new NullPointerException( "specification" );
356 }
357 if ( marshaller == null )
358 {
359 throw new NullPointerException( "marshaller" );
360 }
361 if ( javaClass == null )
362 {
363 throw new NullPointerException( "javaClass" );
364 }
365
366 if ( this.getModules() != null
367 && this.getModules().getSpecification( specification.getIdentifier() ) != null )
368 {
369 this.setClassfileAttribute( javaClass, Specification.class.getName(), this.encodeModelObject(
370 marshaller, new ObjectFactory().createSpecification( specification ) ) );
371
372 }
373 else if ( this.isLoggable( Level.WARNING ) )
374 {
375 this.log( Level.WARNING, getMessage( "specificationNotFound", specification.getIdentifier() ), null );
376 }
377 }
378
379
380
381
382
383
384
385
386
387
388
389 public void commitModelObjects( final Implementation implementation, final Marshaller marshaller,
390 final JavaClass javaClass ) throws IOException
391 {
392 if ( implementation == null )
393 {
394 throw new NullPointerException( "implementation" );
395 }
396 if ( marshaller == null )
397 {
398 throw new NullPointerException( "marshaller" );
399 }
400 if ( javaClass == null )
401 {
402 throw new NullPointerException( "javaClass" );
403 }
404
405 if ( this.getModules() != null
406 && this.getModules().getImplementation( implementation.getIdentifier() ) != null )
407 {
408 final ObjectFactory of = new ObjectFactory();
409
410 Dependencies dependencies = this.getModules().getDependencies( implementation.getIdentifier() );
411 if ( dependencies == null )
412 {
413 dependencies = new Dependencies();
414 }
415
416 Properties properties = this.getModules().getProperties( implementation.getIdentifier() );
417 if ( properties == null )
418 {
419 properties = new Properties();
420 }
421
422 Messages messages = this.getModules().getMessages( implementation.getIdentifier() );
423 if ( messages == null )
424 {
425 messages = new Messages();
426 }
427
428 Specifications specifications = this.getModules().getSpecifications( implementation.getIdentifier() );
429 if ( specifications == null )
430 {
431 specifications = new Specifications();
432 }
433
434 for ( int i = 0, s0 = specifications.getReference().size(); i < s0; i++ )
435 {
436 final SpecificationReference r = specifications.getReference().get( i );
437
438 if ( specifications.getSpecification( r.getIdentifier() ) == null && this.isLoggable( Level.WARNING ) )
439 {
440 this.log( Level.WARNING, getMessage( "unresolvedSpecification", r.getIdentifier(),
441 implementation.getIdentifier() ), null );
442
443 }
444 }
445
446 for ( int i = 0, s0 = dependencies.getDependency().size(); i < s0; i++ )
447 {
448 final Dependency d = dependencies.getDependency().get( i );
449 final Specification s = this.getModules().getSpecification( d.getIdentifier() );
450
451 if ( s != null )
452 {
453 if ( specifications.getSpecification( s.getIdentifier() ) == null )
454 {
455 specifications.getSpecification().add( s );
456 }
457 }
458 else if ( this.isLoggable( Level.WARNING ) )
459 {
460 this.log( Level.WARNING, getMessage( "unresolvedDependencySpecification", d.getIdentifier(),
461 d.getName(), implementation.getIdentifier() ), null );
462
463 }
464 }
465
466 this.setClassfileAttribute( javaClass, Dependencies.class.getName(), this.encodeModelObject(
467 marshaller, of.createDependencies( dependencies ) ) );
468
469 this.setClassfileAttribute( javaClass, Properties.class.getName(), this.encodeModelObject(
470 marshaller, of.createProperties( properties ) ) );
471
472 this.setClassfileAttribute( javaClass, Messages.class.getName(), this.encodeModelObject(
473 marshaller, of.createMessages( messages ) ) );
474
475 this.setClassfileAttribute( javaClass, Specifications.class.getName(), this.encodeModelObject(
476 marshaller, of.createSpecifications( specifications ) ) );
477
478 }
479 else if ( this.isLoggable( Level.WARNING ) )
480 {
481 this.log( Level.WARNING, getMessage( "implementationNotFound", implementation.getIdentifier() ), null );
482 }
483 }
484
485
486
487
488
489
490
491
492
493
494
495
496
497 public final ModelValidationReport validateModelObjects( final ModelContext context ) throws IOException
498 {
499 if ( context == null )
500 {
501 throw new NullPointerException( "context" );
502 }
503
504 try
505 {
506 ModelValidationReport report = null;
507
508 if ( this.getModules() != null )
509 {
510 final Unmarshaller u = context.createUnmarshaller( this.getModel().getIdentifier() );
511 u.setSchema( context.createSchema( this.getModel().getIdentifier() ) );
512 report = this.validateModelObjects( this.getModules().getSpecifications(),
513 this.getModules().getImplementations(), u, context );
514
515 }
516 else if ( this.isLoggable( Level.WARNING ) )
517 {
518 this.log( Level.WARNING, getMessage( "modulesNotFound", this.getModel().getIdentifier() ), null );
519 }
520
521 return report;
522 }
523 catch ( final ModelException e )
524 {
525
526 throw (IOException) new IOException( getMessage( e ) ).initCause( e );
527 }
528 }
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544 public final ModelValidationReport validateModelObjects( final Module module, final ModelContext context )
545 throws IOException
546 {
547 if ( module == null )
548 {
549 throw new NullPointerException( "module" );
550 }
551 if ( context == null )
552 {
553 throw new NullPointerException( "context" );
554 }
555
556 try
557 {
558 ModelValidationReport report = null;
559
560 if ( this.getModules() != null && this.getModules().getModule( module.getName() ) != null )
561 {
562 final Unmarshaller u = context.createUnmarshaller( this.getModel().getIdentifier() );
563 u.setSchema( context.createSchema( this.getModel().getIdentifier() ) );
564 report = this.validateModelObjects( module.getSpecifications(), module.getImplementations(), u,
565 context );
566
567 }
568 else if ( this.isLoggable( Level.WARNING ) )
569 {
570 this.log( Level.WARNING, getMessage( "moduleNotFound", module.getName() ), null );
571 }
572
573 return report;
574 }
575 catch ( final ModelException e )
576 {
577
578 throw (IOException) new IOException( getMessage( e ) ).initCause( e );
579 }
580 }
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596 public final ModelValidationReport validateModelObjects( final Specification specification,
597 final ModelContext context ) throws IOException
598 {
599 if ( specification == null )
600 {
601 throw new NullPointerException( "specification" );
602 }
603 if ( context == null )
604 {
605 throw new NullPointerException( "context" );
606 }
607
608 try
609 {
610 ModelValidationReport report = null;
611
612 if ( this.getModules() != null
613 && this.getModules().getSpecification( specification.getIdentifier() ) != null )
614 {
615 final Unmarshaller u = context.createUnmarshaller( this.getModel().getIdentifier() );
616 u.setSchema( context.createSchema( this.getModel().getIdentifier() ) );
617 report = this.validateModelObjects( specification, u, context );
618 }
619 else if ( this.isLoggable( Level.WARNING ) )
620 {
621 this.log( Level.WARNING, getMessage( "specificationNotFound", specification.getIdentifier() ), null );
622 }
623
624 return report;
625 }
626 catch ( final ModelException e )
627 {
628
629 throw (IOException) new IOException( getMessage( e ) ).initCause( e );
630 }
631 }
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647 public final ModelValidationReport validateModelObjects( final Implementation implementation,
648 final ModelContext context ) throws IOException
649 {
650 if ( implementation == null )
651 {
652 throw new NullPointerException( "implementation" );
653 }
654 if ( context == null )
655 {
656 throw new NullPointerException( "context" );
657 }
658
659 try
660 {
661 ModelValidationReport report = null;
662
663 if ( this.getModules() != null
664 && this.getModules().getImplementation( implementation.getIdentifier() ) != null )
665 {
666 final Unmarshaller u = context.createUnmarshaller( this.getModel().getIdentifier() );
667 u.setSchema( context.createSchema( this.getModel().getIdentifier() ) );
668 report = this.validateModelObjects( implementation, u, context );
669 }
670 else if ( this.isLoggable( Level.WARNING ) )
671 {
672 this.log( Level.WARNING, getMessage( "implementationNotFound", implementation.getIdentifier() ), null );
673 }
674
675 return report;
676 }
677 catch ( final ModelException e )
678 {
679
680 throw (IOException) new IOException( getMessage( e ) ).initCause( e );
681 }
682 }
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697 public final ModelValidationReport validateModelObjects( final ModelContext context, final File classesDirectory )
698 throws IOException
699 {
700 if ( context == null )
701 {
702 throw new NullPointerException( "context" );
703 }
704 if ( classesDirectory == null )
705 {
706 throw new NullPointerException( "classesDirectory" );
707 }
708
709 try
710 {
711 ModelValidationReport report = null;
712
713 if ( this.getModules() != null )
714 {
715 final Unmarshaller u = context.createUnmarshaller( this.getModel().getIdentifier() );
716 u.setSchema( context.createSchema( this.getModel().getIdentifier() ) );
717 report = this.validateModelObjects( this.getModules().getSpecifications(),
718 this.getModules().getImplementations(), u, classesDirectory );
719
720 }
721 else if ( this.isLoggable( Level.WARNING ) )
722 {
723 this.log( Level.WARNING, getMessage( "modulesNotFound", this.getModel().getIdentifier() ), null );
724 }
725
726 return report;
727 }
728 catch ( final ModelException e )
729 {
730
731 throw (IOException) new IOException( getMessage( e ) ).initCause( e );
732 }
733 }
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750 public final ModelValidationReport validateModelObjects( final Module module, final ModelContext context,
751 final File classesDirectory ) throws IOException
752 {
753 if ( module == null )
754 {
755 throw new NullPointerException( "module" );
756 }
757 if ( context == null )
758 {
759 throw new NullPointerException( "context" );
760 }
761 if ( classesDirectory == null )
762 {
763 throw new NullPointerException( "classesDirectory" );
764 }
765
766 try
767 {
768 ModelValidationReport report = null;
769
770 if ( this.getModules() != null && this.getModules().getModule( module.getName() ) != null )
771 {
772 final Unmarshaller u = context.createUnmarshaller( this.getModel().getIdentifier() );
773 u.setSchema( context.createSchema( this.getModel().getIdentifier() ) );
774 report = this.validateModelObjects( module.getSpecifications(), module.getImplementations(), u,
775 classesDirectory );
776
777 }
778 else if ( this.isLoggable( Level.WARNING ) )
779 {
780 this.log( Level.WARNING, getMessage( "moduleNotFound", module.getName() ), null );
781 }
782
783 return report;
784 }
785 catch ( final ModelException e )
786 {
787
788 throw (IOException) new IOException( getMessage( e ) ).initCause( e );
789 }
790 }
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808 public final ModelValidationReport validateModelObjects( final Specification specification,
809 final ModelContext context, final File classesDirectory )
810 throws IOException
811 {
812 if ( specification == null )
813 {
814 throw new NullPointerException( "specification" );
815 }
816 if ( context == null )
817 {
818 throw new NullPointerException( "context" );
819 }
820 if ( classesDirectory == null )
821 {
822 throw new NullPointerException( "classesDirectory" );
823 }
824
825 try
826 {
827 ModelValidationReport report = null;
828
829 if ( this.getModules() != null
830 && this.getModules().getSpecification( specification.getIdentifier() ) != null )
831 {
832 final Unmarshaller u = context.createUnmarshaller( this.getModel().getIdentifier() );
833 u.setSchema( context.createSchema( this.getModel().getIdentifier() ) );
834 report = this.validateModelObjects( specification, u, classesDirectory );
835 }
836 else if ( this.isLoggable( Level.WARNING ) )
837 {
838 this.log( Level.WARNING, getMessage( "specificationNotFound", specification.getIdentifier() ), null );
839 }
840
841 return report;
842 }
843 catch ( final ModelException e )
844 {
845
846 throw (IOException) new IOException( getMessage( e ) ).initCause( e );
847 }
848 }
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866 public final ModelValidationReport validateModelObjects( final Implementation implementation,
867 final ModelContext context, final File classesDirectory )
868 throws IOException
869 {
870 if ( implementation == null )
871 {
872 throw new NullPointerException( "implementation" );
873 }
874 if ( context == null )
875 {
876 throw new NullPointerException( "context" );
877 }
878 if ( classesDirectory == null )
879 {
880 throw new NullPointerException( "classesDirectory" );
881 }
882
883 try
884 {
885 ModelValidationReport report = null;
886
887 if ( this.getModules() != null
888 && this.getModules().getImplementation( implementation.getIdentifier() ) != null )
889 {
890 final Unmarshaller u = context.createUnmarshaller( this.getModel().getIdentifier() );
891 u.setSchema( context.createSchema( this.getModel().getIdentifier() ) );
892 report = this.validateModelObjects( implementation, u, classesDirectory );
893 }
894 else if ( this.isLoggable( Level.WARNING ) )
895 {
896 this.log( Level.WARNING, getMessage( "implementationNotFound", implementation.getIdentifier() ), null );
897 }
898
899 return report;
900 }
901 catch ( final ModelException e )
902 {
903
904 throw (IOException) new IOException( getMessage( e ) ).initCause( e );
905 }
906 }
907
908
909
910
911
912
913
914
915
916
917
918
919
920 public ModelValidationReport validateModelObjects( final Specification specification,
921 final Unmarshaller unmarshaller, final JavaClass javaClass )
922 throws IOException
923 {
924 if ( specification == null )
925 {
926 throw new NullPointerException( "specification" );
927 }
928 if ( unmarshaller == null )
929 {
930 throw new NullPointerException( "unmarshaller" );
931 }
932 if ( javaClass == null )
933 {
934 throw new NullPointerException( "javaClass" );
935 }
936
937 ModelValidationReport report = null;
938
939 if ( this.getModules() != null && this.getModules().getSpecification( specification.getIdentifier() ) != null )
940 {
941 report = new ModelValidationReport();
942
943 Specification decoded = null;
944 final byte[] bytes = this.getClassfileAttribute( javaClass, Specification.class.getName() );
945 if ( bytes != null )
946 {
947 decoded = this.decodeModelObject( unmarshaller, bytes, Specification.class );
948 }
949
950 if ( decoded != null )
951 {
952 if ( decoded.getMultiplicity() != specification.getMultiplicity() )
953 {
954 report.getDetails().add( new ModelValidationReport.Detail(
955 "CLASS_ILLEGAL_SPECIFICATION_MULTIPLICITY", Level.SEVERE, getMessage(
956 "illegalMultiplicity", specification.getIdentifier(), specification.getMultiplicity().value(),
957 decoded.getMultiplicity().value() ),
958 new ObjectFactory().createSpecification( specification ) ) );
959
960 }
961
962 if ( decoded.getScope() == null
963 ? specification.getScope() != null
964 : !decoded.getScope().equals( specification.getScope() ) )
965 {
966 report.getDetails().add( new ModelValidationReport.Detail(
967 "CLASS_ILLEGAL_SPECIFICATION_SCOPE", Level.SEVERE, getMessage(
968 "illegalScope", specification.getIdentifier(),
969 specification.getScope() == null ? "Multiton" : specification.getScope(),
970 decoded.getScope() == null ? "Multiton" : decoded.getScope() ),
971 new ObjectFactory().createSpecification( specification ) ) );
972
973 }
974
975 if ( decoded.getClazz() == null
976 ? specification.getClazz() != null
977 : !decoded.getClazz().equals( specification.getClazz() ) )
978 {
979 report.getDetails().add( new ModelValidationReport.Detail(
980 "CLASS_ILLEGAL_SPECIFICATION_CLASS", Level.SEVERE, getMessage(
981 "illegalSpecificationClass", decoded.getIdentifier(),
982 specification.getClazz(), decoded.getClazz() ),
983 new ObjectFactory().createSpecification( specification ) ) );
984
985 }
986 }
987 else if ( this.isLoggable( Level.WARNING ) )
988 {
989 this.log( Level.WARNING, getMessage( "cannotValidateSpecification", specification.getIdentifier(),
990 Specification.class.getName() ), null );
991
992 }
993 }
994 else if ( this.isLoggable( Level.WARNING ) )
995 {
996 this.log( Level.WARNING, getMessage( "specificationNotFound", specification.getIdentifier() ), null );
997 }
998
999 return report;
1000 }
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014 public ModelValidationReport validateModelObjects( final Implementation implementation,
1015 final Unmarshaller unmarshaller, final JavaClass javaClass )
1016 throws IOException
1017 {
1018 if ( implementation == null )
1019 {
1020 throw new NullPointerException( "implementation" );
1021 }
1022 if ( unmarshaller == null )
1023 {
1024 throw new NullPointerException( "unmarshaller" );
1025 }
1026 if ( javaClass == null )
1027 {
1028 throw new NullPointerException( "javaClass" );
1029 }
1030
1031 try
1032 {
1033 ModelValidationReport report = null;
1034
1035 if ( this.getModules() != null
1036 && this.getModules().getImplementation( implementation.getIdentifier() ) != null )
1037 {
1038 report = new ModelValidationReport();
1039 Dependencies dependencies = this.getModules().getDependencies( implementation.getIdentifier() );
1040 if ( dependencies == null )
1041 {
1042 dependencies = new Dependencies();
1043 }
1044
1045 Properties properties = this.getModules().getProperties( implementation.getIdentifier() );
1046 if ( properties == null )
1047 {
1048 properties = new Properties();
1049 }
1050
1051 Messages messages = this.getModules().getMessages( implementation.getIdentifier() );
1052 if ( messages == null )
1053 {
1054 messages = new Messages();
1055 }
1056
1057 Specifications specifications = this.getModules().getSpecifications( implementation.getIdentifier() );
1058 if ( specifications == null )
1059 {
1060 specifications = new Specifications();
1061 }
1062
1063 Dependencies decodedDependencies = null;
1064 byte[] bytes = this.getClassfileAttribute( javaClass, Dependencies.class.getName() );
1065 if ( bytes != null )
1066 {
1067 decodedDependencies = this.decodeModelObject( unmarshaller, bytes, Dependencies.class );
1068 }
1069
1070 Properties decodedProperties = null;
1071 bytes = this.getClassfileAttribute( javaClass, Properties.class.getName() );
1072 if ( bytes != null )
1073 {
1074 decodedProperties = this.decodeModelObject( unmarshaller, bytes, Properties.class );
1075 }
1076
1077 Messages decodedMessages = null;
1078 bytes = this.getClassfileAttribute( javaClass, Messages.class.getName() );
1079 if ( bytes != null )
1080 {
1081 decodedMessages = this.decodeModelObject( unmarshaller, bytes, Messages.class );
1082 }
1083
1084 Specifications decodedSpecifications = null;
1085 bytes = this.getClassfileAttribute( javaClass, Specifications.class.getName() );
1086 if ( bytes != null )
1087 {
1088 decodedSpecifications = this.decodeModelObject( unmarshaller, bytes, Specifications.class );
1089 }
1090
1091 if ( decodedDependencies != null )
1092 {
1093 for ( int i = 0, s0 = decodedDependencies.getDependency().size(); i < s0; i++ )
1094 {
1095 final Dependency decodedDependency = decodedDependencies.getDependency().get( i );
1096 final Dependency dependency = dependencies.getDependency( decodedDependency.getName() );
1097 final Specification s = this.getModules().getSpecification( decodedDependency.getIdentifier() );
1098
1099 if ( dependency == null )
1100 {
1101 report.getDetails().add( new ModelValidationReport.Detail(
1102 "CLASS_MISSING_IMPLEMENTATION_DEPENDENCY", Level.SEVERE, getMessage(
1103 "missingDependency", implementation.getIdentifier(), decodedDependency.getName() ),
1104 new ObjectFactory().createImplementation( implementation ) ) );
1105
1106 }
1107 else if ( decodedDependency.getImplementationName() != null
1108 && dependency.getImplementationName() == null )
1109 {
1110 report.getDetails().add( new ModelValidationReport.Detail(
1111 "CLASS_MISSING_DEPENDENCY_IMPLEMENTATION_NAME", Level.SEVERE, getMessage(
1112 "missingDependencyImplementationName", implementation.getIdentifier(),
1113 decodedDependency.getName() ),
1114 new ObjectFactory().createImplementation( implementation ) ) );
1115
1116 }
1117
1118 if ( s != null && s.getVersion() != null && decodedDependency.getVersion() != null
1119 && VersionParser.compare( decodedDependency.getVersion(), s.getVersion() ) > 0 )
1120 {
1121 final Module moduleOfSpecification =
1122 this.getModules().getModuleOfSpecification( s.getIdentifier() );
1123
1124 final Module moduleOfImplementation =
1125 this.getModules().getModuleOfImplementation( implementation.getIdentifier() );
1126
1127 report.getDetails().add( new ModelValidationReport.Detail(
1128 "CLASS_INCOMPATIBLE_IMPLEMENTATION_DEPENDENCY", Level.SEVERE, getMessage(
1129 "incompatibleDependency", javaClass.getClassName(),
1130 moduleOfImplementation == null ? "<>" : moduleOfImplementation.getName(),
1131 s.getIdentifier(),
1132 moduleOfSpecification == null ? "<>" : moduleOfSpecification.getName(),
1133 decodedDependency.getVersion(), s.getVersion() ),
1134 new ObjectFactory().createImplementation( implementation ) ) );
1135
1136 }
1137 }
1138 }
1139 else if ( this.isLoggable( Level.WARNING ) )
1140 {
1141 this.log( Level.WARNING, getMessage( "cannotValidateImplementation", implementation.getIdentifier(),
1142 Dependencies.class.getName() ), null );
1143
1144 }
1145
1146 if ( decodedProperties != null )
1147 {
1148 for ( int i = 0, s0 = decodedProperties.getProperty().size(); i < s0; i++ )
1149 {
1150 final Property decodedProperty = decodedProperties.getProperty().get( i );
1151 final Property property = properties.getProperty( decodedProperty.getName() );
1152
1153 if ( property == null )
1154 {
1155 report.getDetails().add( new ModelValidationReport.Detail(
1156 "CLASS_MISSING_IMPLEMENTATION_PROPERTY", Level.SEVERE, getMessage(
1157 "missingProperty", implementation.getIdentifier(), decodedProperty.getName() ),
1158 new ObjectFactory().createImplementation( implementation ) ) );
1159
1160 }
1161 else if ( decodedProperty.getType() == null
1162 ? property.getType() != null
1163 : !decodedProperty.getType().equals( property.getType() ) )
1164 {
1165 report.getDetails().add( new ModelValidationReport.Detail(
1166 "CLASS_ILLEGAL_IMPLEMENTATION_PROPERTY", Level.SEVERE, getMessage(
1167 "illegalPropertyType", implementation.getIdentifier(), decodedProperty.getName(),
1168 property.getType() == null ? "<>" : property.getType(),
1169 decodedProperty.getType() == null ? "<>" : decodedProperty.getType() ),
1170 new ObjectFactory().createImplementation( implementation ) ) );
1171
1172 }
1173 }
1174 }
1175 else if ( this.isLoggable( Level.WARNING ) )
1176 {
1177 this.log( Level.WARNING, getMessage( "cannotValidateImplementation", implementation.getIdentifier(),
1178 Properties.class.getName() ), null );
1179
1180 }
1181
1182 if ( decodedMessages != null )
1183 {
1184 for ( int i = 0, s0 = decodedMessages.getMessage().size(); i < s0; i++ )
1185 {
1186 final Message decodedMessage = decodedMessages.getMessage().get( i );
1187 final Message message = messages.getMessage( decodedMessage.getName() );
1188
1189 if ( message == null )
1190 {
1191 report.getDetails().add( new ModelValidationReport.Detail(
1192 "CLASS_MISSING_IMPLEMENTATION_MESSAGE", Level.SEVERE, getMessage(
1193 "missingMessage", implementation.getIdentifier(), decodedMessage.getName() ),
1194 new ObjectFactory().createImplementation( implementation ) ) );
1195
1196 }
1197 }
1198 }
1199 else if ( this.isLoggable( Level.WARNING ) )
1200 {
1201 this.log( Level.WARNING, getMessage( "cannotValidateImplementation", implementation.getIdentifier(),
1202 Messages.class.getName() ), null );
1203
1204 }
1205
1206 if ( decodedSpecifications != null )
1207 {
1208 for ( int i = 0, s0 = decodedSpecifications.getSpecification().size(); i < s0; i++ )
1209 {
1210 final Specification decodedSpecification = decodedSpecifications.getSpecification().get( i );
1211 final Specification specification =
1212 this.getModules().getSpecification( decodedSpecification.getIdentifier() );
1213
1214 if ( specification == null )
1215 {
1216 report.getDetails().add( new ModelValidationReport.Detail(
1217 "CLASS_MISSING_SPECIFICATION", Level.SEVERE, getMessage(
1218 "missingSpecification", implementation.getIdentifier(),
1219 decodedSpecification.getIdentifier() ),
1220 new ObjectFactory().createImplementation( implementation ) ) );
1221
1222 }
1223 else
1224 {
1225 if ( decodedSpecification.getMultiplicity() != specification.getMultiplicity() )
1226 {
1227 report.getDetails().add( new ModelValidationReport.Detail(
1228 "CLASS_ILLEGAL_SPECIFICATION_MULTIPLICITY", Level.SEVERE, getMessage(
1229 "illegalMultiplicity", specification.getIdentifier(),
1230 specification.getMultiplicity().value(),
1231 decodedSpecification.getMultiplicity().value() ),
1232 new ObjectFactory().createImplementation( implementation ) ) );
1233
1234 }
1235
1236 if ( decodedSpecification.getScope() == null
1237 ? specification.getScope() != null
1238 : !decodedSpecification.getScope().equals( specification.getScope() ) )
1239 {
1240 report.getDetails().add( new ModelValidationReport.Detail(
1241 "CLASS_ILLEGAL_SPECIFICATION_SCOPE", Level.SEVERE, getMessage(
1242 "illegalScope", decodedSpecification.getIdentifier(),
1243 specification.getScope() == null ? "Multiton" : specification.getScope(),
1244 decodedSpecification.getScope() == null ? "Multiton"
1245 : decodedSpecification.getScope() ),
1246 new ObjectFactory().createImplementation( implementation ) ) );
1247
1248 }
1249
1250 if ( decodedSpecification.getClazz() == null
1251 ? specification.getClazz() != null
1252 : !decodedSpecification.getClazz().equals( specification.getClazz() ) )
1253 {
1254 report.getDetails().add( new ModelValidationReport.Detail(
1255 "CLASS_ILLEGAL_SPECIFICATION_CLASS", Level.SEVERE, getMessage(
1256 "illegalSpecificationClass", decodedSpecification.getIdentifier(),
1257 specification.getClazz(), decodedSpecification.getClazz() ),
1258 new ObjectFactory().createImplementation( implementation ) ) );
1259
1260 }
1261 }
1262 }
1263
1264 for ( int i = 0, s0 = decodedSpecifications.getReference().size(); i < s0; i++ )
1265 {
1266 final SpecificationReference decodedReference = decodedSpecifications.getReference().get( i );
1267 final Specification specification =
1268 specifications.getSpecification( decodedReference.getIdentifier() );
1269
1270 if ( specification == null )
1271 {
1272 report.getDetails().add( new ModelValidationReport.Detail(
1273 "CLASS_MISSING_SPECIFICATION", Level.SEVERE, getMessage(
1274 "missingSpecification", implementation.getIdentifier(),
1275 decodedReference.getIdentifier() ),
1276 new ObjectFactory().createImplementation( implementation ) ) );
1277
1278 }
1279 else if ( decodedReference.getVersion() != null && specification.getVersion() != null
1280 && VersionParser.compare( decodedReference.getVersion(),
1281 specification.getVersion() ) != 0 )
1282 {
1283 final Module moduleOfSpecification =
1284 this.getModules().getModuleOfSpecification( decodedReference.getIdentifier() );
1285
1286 final Module moduleOfImplementation =
1287 this.getModules().getModuleOfImplementation( implementation.getIdentifier() );
1288
1289 report.getDetails().add( new ModelValidationReport.Detail(
1290 "CLASS_INCOMPATIBLE_IMPLEMENTATION", Level.SEVERE, getMessage(
1291 "incompatibleImplementation", javaClass.getClassName(),
1292 moduleOfImplementation == null ? "<>" : moduleOfImplementation.getName(),
1293 specification.getIdentifier(),
1294 moduleOfSpecification == null ? "<>" : moduleOfSpecification.getName(),
1295 decodedReference.getVersion(), specification.getVersion() ),
1296 new ObjectFactory().createImplementation( implementation ) ) );
1297
1298 }
1299 }
1300 }
1301 else if ( this.isLoggable( Level.WARNING ) )
1302 {
1303 this.log( Level.WARNING, getMessage( "cannotValidateImplementation", implementation.getIdentifier(),
1304 Specifications.class.getName() ), null );
1305
1306 }
1307 }
1308 else if ( this.isLoggable( Level.WARNING ) )
1309 {
1310 this.log( Level.WARNING, getMessage( "implementationNotFound", implementation.getIdentifier() ), null );
1311 }
1312
1313 return report;
1314 }
1315 catch ( final ParseException e )
1316 {
1317
1318 throw (IOException) new IOException( getMessage( e ) ).initCause( e );
1319 }
1320 catch ( final TokenMgrError e )
1321 {
1322
1323 throw (IOException) new IOException( getMessage( e ) ).initCause( e );
1324 }
1325 }
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340 public final void transformModelObjects( final ModelContext context, final File classesDirectory,
1341 final List<Transformer> transformers ) throws IOException
1342 {
1343 if ( context == null )
1344 {
1345 throw new NullPointerException( "context" );
1346 }
1347 if ( classesDirectory == null )
1348 {
1349 throw new NullPointerException( "classesDirectory" );
1350 }
1351 if ( transformers == null )
1352 {
1353 throw new NullPointerException( "transformers" );
1354 }
1355 if ( !classesDirectory.isDirectory() )
1356 {
1357 throw new IOException( getMessage( "directoryNotFound", classesDirectory.getAbsolutePath() ) );
1358 }
1359
1360 try
1361 {
1362 if ( this.getModules() != null )
1363 {
1364 final Unmarshaller u = context.createUnmarshaller( this.getModel().getIdentifier() );
1365 final Marshaller m = context.createMarshaller( this.getModel().getIdentifier() );
1366 final Schema s = context.createSchema( this.getModel().getIdentifier() );
1367 u.setSchema( s );
1368 m.setSchema( s );
1369
1370 this.transformModelObjects( this.getModules().getSpecifications(),
1371 this.getModules().getImplementations(),
1372 u, m, classesDirectory, transformers );
1373
1374 }
1375 else if ( this.isLoggable( Level.WARNING ) )
1376 {
1377 this.log( Level.WARNING, getMessage( "modulesNotFound", this.getModel().getIdentifier() ), null );
1378 }
1379 }
1380 catch ( final ModelException e )
1381 {
1382
1383 throw (IOException) new IOException( getMessage( e ) ).initCause( e );
1384 }
1385 }
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402 public final void transformModelObjects( final Module module, final ModelContext context,
1403 final File classesDirectory, final List<Transformer> transformers )
1404 throws IOException
1405 {
1406 if ( module == null )
1407 {
1408 throw new NullPointerException( "module" );
1409 }
1410 if ( context == null )
1411 {
1412 throw new NullPointerException( "context" );
1413 }
1414 if ( classesDirectory == null )
1415 {
1416 throw new NullPointerException( "classesDirectory" );
1417 }
1418 if ( transformers == null )
1419 {
1420 throw new NullPointerException( "transformers" );
1421 }
1422 if ( !classesDirectory.isDirectory() )
1423 {
1424 throw new IOException( getMessage( "directoryNotFound", classesDirectory.getAbsolutePath() ) );
1425 }
1426
1427 try
1428 {
1429 if ( this.getModules() != null && this.getModules().getModule( module.getName() ) != null )
1430 {
1431 final Unmarshaller u = context.createUnmarshaller( this.getModel().getIdentifier() );
1432 final Marshaller m = context.createMarshaller( this.getModel().getIdentifier() );
1433 final Schema s = context.createSchema( this.getModel().getIdentifier() );
1434 u.setSchema( s );
1435 m.setSchema( s );
1436
1437 this.transformModelObjects( module.getSpecifications(), module.getImplementations(), u, m,
1438 classesDirectory, transformers );
1439
1440 }
1441 else if ( this.isLoggable( Level.WARNING ) )
1442 {
1443 this.log( Level.WARNING, getMessage( "moduleNotFound", module.getName() ), null );
1444 }
1445 }
1446 catch ( final ModelException e )
1447 {
1448
1449 throw (IOException) new IOException( getMessage( e ) ).initCause( e );
1450 }
1451 }
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467 public final void transformModelObjects( final Specification specification, final ModelContext context,
1468 final File classesDirectory, final List<Transformer> transformers )
1469 throws IOException
1470 {
1471 if ( specification == null )
1472 {
1473 throw new NullPointerException( "specification" );
1474 }
1475 if ( context == null )
1476 {
1477 throw new NullPointerException( "context" );
1478 }
1479 if ( classesDirectory == null )
1480 {
1481 throw new NullPointerException( "classesDirectory" );
1482 }
1483 if ( transformers == null )
1484 {
1485 throw new NullPointerException( "transformers" );
1486 }
1487 if ( !classesDirectory.isDirectory() )
1488 {
1489 throw new IOException( getMessage( "directoryNotFound", classesDirectory.getAbsolutePath() ) );
1490 }
1491
1492 try
1493 {
1494 if ( this.getModules() != null
1495 && this.getModules().getSpecification( specification.getIdentifier() ) != null )
1496 {
1497 final Unmarshaller u = context.createUnmarshaller( this.getModel().getIdentifier() );
1498 final Marshaller m = context.createMarshaller( this.getModel().getIdentifier() );
1499 final Schema s = context.createSchema( this.getModel().getIdentifier() );
1500 u.setSchema( s );
1501 m.setSchema( s );
1502
1503 this.transformModelObjects( specification, m, u, classesDirectory, transformers );
1504 }
1505 else if ( this.isLoggable( Level.WARNING ) )
1506 {
1507 this.log( Level.WARNING, getMessage( "specificationNotFound", specification.getIdentifier() ), null );
1508 }
1509 }
1510 catch ( final ModelException e )
1511 {
1512
1513 throw (IOException) new IOException( getMessage( e ) ).initCause( e );
1514 }
1515 }
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531 public final void transformModelObjects( final Implementation implementation, final ModelContext context,
1532 final File classesDirectory, final List<Transformer> transformers )
1533 throws IOException
1534 {
1535 if ( implementation == null )
1536 {
1537 throw new NullPointerException( "implementation" );
1538 }
1539 if ( context == null )
1540 {
1541 throw new NullPointerException( "context" );
1542 }
1543 if ( classesDirectory == null )
1544 {
1545 throw new NullPointerException( "classesDirectory" );
1546 }
1547 if ( transformers == null )
1548 {
1549 throw new NullPointerException( "transformers" );
1550 }
1551 if ( !classesDirectory.isDirectory() )
1552 {
1553 throw new IOException( getMessage( "directoryNotFound", classesDirectory.getAbsolutePath() ) );
1554 }
1555
1556 try
1557 {
1558 if ( this.getModules() != null
1559 && this.getModules().getImplementation( implementation.getIdentifier() ) != null )
1560 {
1561 final Unmarshaller u = context.createUnmarshaller( this.getModel().getIdentifier() );
1562 final Marshaller m = context.createMarshaller( this.getModel().getIdentifier() );
1563 final Schema s = context.createSchema( this.getModel().getIdentifier() );
1564 u.setSchema( s );
1565 m.setSchema( s );
1566
1567 this.transformModelObjects( implementation, m, u, classesDirectory, transformers );
1568 }
1569 else if ( this.isLoggable( Level.WARNING ) )
1570 {
1571 this.log( Level.WARNING, getMessage( "implementationNotFound", implementation.getIdentifier() ), null );
1572 }
1573 }
1574 catch ( final ModelException e )
1575 {
1576
1577 throw (IOException) new IOException( getMessage( e ) ).initCause( e );
1578 }
1579 }
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594 public void transformModelObjects( final Specification specification, final Marshaller marshaller,
1595 final Unmarshaller unmarshaller, final JavaClass javaClass,
1596 final List<Transformer> transformers ) throws IOException
1597 {
1598 if ( specification == null )
1599 {
1600 throw new NullPointerException( "specification" );
1601 }
1602 if ( marshaller == null )
1603 {
1604 throw new NullPointerException( "marshaller" );
1605 }
1606 if ( unmarshaller == null )
1607 {
1608 throw new NullPointerException( "unmarshaller" );
1609 }
1610 if ( javaClass == null )
1611 {
1612 throw new NullPointerException( "javaClass" );
1613 }
1614 if ( transformers == null )
1615 {
1616 throw new NullPointerException( "transformers" );
1617 }
1618
1619 try
1620 {
1621 if ( this.getModules() != null
1622 && this.getModules().getSpecification( specification.getIdentifier() ) != null )
1623 {
1624 Specification decodedSpecification = null;
1625 final ObjectFactory objectFactory = new ObjectFactory();
1626 final byte[] bytes = this.getClassfileAttribute( javaClass, Specification.class.getName() );
1627 if ( bytes != null )
1628 {
1629 decodedSpecification = this.decodeModelObject( unmarshaller, bytes, Specification.class );
1630 }
1631
1632 if ( decodedSpecification != null )
1633 {
1634 for ( int i = 0, l = transformers.size(); i < l; i++ )
1635 {
1636 final JAXBSource source =
1637 new JAXBSource( marshaller, objectFactory.createSpecification( decodedSpecification ) );
1638
1639 final JAXBResult result = new JAXBResult( unmarshaller );
1640 transformers.get( i ).transform( source, result );
1641
1642 if ( result.getResult() instanceof JAXBElement<?>
1643 && ( (JAXBElement<?>) result.getResult() ).getValue() instanceof Specification )
1644 {
1645 decodedSpecification = (Specification) ( (JAXBElement<?>) result.getResult() ).getValue();
1646 }
1647 else
1648 {
1649 throw new IOException( getMessage(
1650 "illegalSpecificationTransformationResult", specification.getIdentifier() ) );
1651
1652 }
1653 }
1654
1655 this.setClassfileAttribute( javaClass, Specification.class.getName(), this.encodeModelObject(
1656 marshaller, objectFactory.createSpecification( decodedSpecification ) ) );
1657
1658 }
1659 }
1660 else if ( this.isLoggable( Level.WARNING ) )
1661 {
1662 this.log( Level.WARNING, getMessage( "specificationNotFound", specification.getIdentifier() ), null );
1663 }
1664 }
1665 catch ( final JAXBException e )
1666 {
1667 String message = getMessage( e );
1668 if ( message == null && e.getLinkedException() != null )
1669 {
1670 message = getMessage( e.getLinkedException() );
1671 }
1672
1673
1674 throw (IOException) new IOException( message ).initCause( e );
1675 }
1676 catch ( final TransformerException e )
1677 {
1678 String message = getMessage( e );
1679 if ( message == null && e.getException() != null )
1680 {
1681 message = getMessage( e.getException() );
1682 }
1683
1684
1685 throw (IOException) new IOException( message ).initCause( e );
1686 }
1687 }
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702 public void transformModelObjects( final Implementation implementation, final Marshaller marshaller,
1703 final Unmarshaller unmarshaller, final JavaClass javaClass,
1704 final List<Transformer> transformers ) throws IOException
1705 {
1706 if ( implementation == null )
1707 {
1708 throw new NullPointerException( "implementation" );
1709 }
1710 if ( marshaller == null )
1711 {
1712 throw new NullPointerException( "marshaller" );
1713 }
1714 if ( unmarshaller == null )
1715 {
1716 throw new NullPointerException( "unmarshaller" );
1717 }
1718 if ( javaClass == null )
1719 {
1720 throw new NullPointerException( "javaClass" );
1721 }
1722 if ( transformers == null )
1723 {
1724 throw new NullPointerException( "transformers" );
1725 }
1726
1727 try
1728 {
1729 if ( this.getModules() != null
1730 && this.getModules().getImplementation( implementation.getIdentifier() ) != null )
1731 {
1732 Dependencies decodedDependencies = null;
1733 byte[] bytes = this.getClassfileAttribute( javaClass, Dependencies.class.getName() );
1734 if ( bytes != null )
1735 {
1736 decodedDependencies = this.decodeModelObject( unmarshaller, bytes, Dependencies.class );
1737 }
1738
1739 Messages decodedMessages = null;
1740 bytes = this.getClassfileAttribute( javaClass, Messages.class.getName() );
1741 if ( bytes != null )
1742 {
1743 decodedMessages = this.decodeModelObject( unmarshaller, bytes, Messages.class );
1744 }
1745
1746 Properties decodedProperties = null;
1747 bytes = this.getClassfileAttribute( javaClass, Properties.class.getName() );
1748 if ( bytes != null )
1749 {
1750 decodedProperties = this.decodeModelObject( unmarshaller, bytes, Properties.class );
1751 }
1752
1753 Specifications decodedSpecifications = null;
1754 bytes = this.getClassfileAttribute( javaClass, Specifications.class.getName() );
1755 if ( bytes != null )
1756 {
1757 decodedSpecifications = this.decodeModelObject( unmarshaller, bytes, Specifications.class );
1758 }
1759
1760 final ObjectFactory of = new ObjectFactory();
1761 for ( int i = 0, l = transformers.size(); i < l; i++ )
1762 {
1763 final Transformer transformer = transformers.get( i );
1764
1765 if ( decodedDependencies != null )
1766 {
1767 final JAXBSource source =
1768 new JAXBSource( marshaller, of.createDependencies( decodedDependencies ) );
1769
1770 final JAXBResult result = new JAXBResult( unmarshaller );
1771 transformer.transform( source, result );
1772
1773 if ( result.getResult() instanceof JAXBElement<?>
1774 && ( (JAXBElement<?>) result.getResult() ).getValue() instanceof Dependencies )
1775 {
1776 decodedDependencies = (Dependencies) ( (JAXBElement<?>) result.getResult() ).getValue();
1777 }
1778 else
1779 {
1780 throw new IOException( getMessage(
1781 "illegalImplementationTransformationResult", implementation.getIdentifier() ) );
1782
1783 }
1784 }
1785
1786 if ( decodedMessages != null )
1787 {
1788 final JAXBSource source = new JAXBSource( marshaller, of.createMessages( decodedMessages ) );
1789 final JAXBResult result = new JAXBResult( unmarshaller );
1790 transformer.transform( source, result );
1791
1792 if ( result.getResult() instanceof JAXBElement<?>
1793 && ( (JAXBElement<?>) result.getResult() ).getValue() instanceof Messages )
1794 {
1795 decodedMessages = (Messages) ( (JAXBElement<?>) result.getResult() ).getValue();
1796 }
1797 else
1798 {
1799 throw new IOException( getMessage(
1800 "illegalImplementationTransformationResult", implementation.getIdentifier() ) );
1801
1802 }
1803 }
1804
1805 if ( decodedProperties != null )
1806 {
1807 final JAXBSource source = new JAXBSource( marshaller, of.createProperties( decodedProperties ) );
1808 final JAXBResult result = new JAXBResult( unmarshaller );
1809 transformer.transform( source, result );
1810
1811 if ( result.getResult() instanceof JAXBElement<?>
1812 && ( (JAXBElement<?>) result.getResult() ).getValue() instanceof Properties )
1813 {
1814 decodedProperties = (Properties) ( (JAXBElement<?>) result.getResult() ).getValue();
1815 }
1816 else
1817 {
1818 throw new IOException( getMessage(
1819 "illegalImplementationTransformationResult", implementation.getIdentifier() ) );
1820
1821 }
1822 }
1823
1824 if ( decodedSpecifications != null )
1825 {
1826 final JAXBSource source =
1827 new JAXBSource( marshaller, of.createSpecifications( decodedSpecifications ) );
1828
1829 final JAXBResult result = new JAXBResult( unmarshaller );
1830 transformer.transform( source, result );
1831
1832 if ( result.getResult() instanceof JAXBElement<?>
1833 && ( (JAXBElement<?>) result.getResult() ).getValue() instanceof Specifications )
1834 {
1835 decodedSpecifications = (Specifications) ( (JAXBElement<?>) result.getResult() ).getValue();
1836 }
1837 else
1838 {
1839 throw new IOException( getMessage(
1840 "illegalImplementationTransformationResult", implementation.getIdentifier() ) );
1841
1842 }
1843 }
1844 }
1845
1846 if ( decodedDependencies != null )
1847 {
1848 this.setClassfileAttribute( javaClass, Dependencies.class.getName(), this.encodeModelObject(
1849 marshaller, of.createDependencies( decodedDependencies ) ) );
1850
1851 }
1852
1853 if ( decodedMessages != null )
1854 {
1855 this.setClassfileAttribute( javaClass, Messages.class.getName(), this.encodeModelObject(
1856 marshaller, of.createMessages( decodedMessages ) ) );
1857
1858 }
1859
1860 if ( decodedProperties != null )
1861 {
1862 this.setClassfileAttribute( javaClass, Properties.class.getName(), this.encodeModelObject(
1863 marshaller, of.createProperties( decodedProperties ) ) );
1864
1865 }
1866
1867 if ( decodedSpecifications != null )
1868 {
1869 this.setClassfileAttribute( javaClass, Specifications.class.getName(), this.encodeModelObject(
1870 marshaller, of.createSpecifications( decodedSpecifications ) ) );
1871
1872 }
1873 }
1874 else if ( this.isLoggable( Level.WARNING ) )
1875 {
1876 this.log( Level.WARNING, getMessage( "implementationNotFound", implementation.getIdentifier() ), null );
1877 }
1878 }
1879 catch ( final JAXBException e )
1880 {
1881 String message = getMessage( e );
1882 if ( message == null && e.getLinkedException() != null )
1883 {
1884 message = getMessage( e.getLinkedException() );
1885 }
1886
1887
1888 throw (IOException) new IOException( message ).initCause( e );
1889 }
1890 catch ( final TransformerException e )
1891 {
1892 String message = getMessage( e );
1893 if ( message == null && e.getException() != null )
1894 {
1895 message = getMessage( e.getException() );
1896 }
1897
1898
1899 throw (IOException) new IOException( message ).initCause( e );
1900 }
1901 }
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917 public byte[] getClassfileAttribute( final JavaClass clazz, final String attributeName ) throws IOException
1918 {
1919 if ( clazz == null )
1920 {
1921 throw new NullPointerException( "clazz" );
1922 }
1923 if ( attributeName == null )
1924 {
1925 throw new NullPointerException( "attributeName" );
1926 }
1927
1928 final Attribute[] attributes = clazz.getAttributes();
1929
1930 for ( int i = attributes.length - 1; i >= 0; i-- )
1931 {
1932 final Constant constant = clazz.getConstantPool().getConstant( attributes[i].getNameIndex() );
1933
1934 if ( constant instanceof ConstantUtf8 && attributeName.equals( ( (ConstantUtf8) constant ).getBytes() ) )
1935 {
1936 final Unknown unknown = (Unknown) attributes[i];
1937 return unknown.getBytes();
1938 }
1939 }
1940
1941 return null;
1942 }
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956 public void setClassfileAttribute( final JavaClass clazz, final String attributeName, final byte[] data )
1957 throws IOException
1958 {
1959 if ( clazz == null )
1960 {
1961 throw new NullPointerException( "clazz" );
1962 }
1963 if ( attributeName == null )
1964 {
1965 throw new NullPointerException( "attributeName" );
1966 }
1967
1968 final byte[] attributeData = data != null ? data : NO_BYTES;
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979 Attribute[] attributes = clazz.getAttributes();
1980
1981 int attributeIndex = -1;
1982 int nameIndex = -1;
1983
1984 for ( int i = attributes.length - 1; i >= 0; i-- )
1985 {
1986 final Constant constant = clazz.getConstantPool().getConstant( attributes[i].getNameIndex() );
1987
1988 if ( constant instanceof ConstantUtf8 && attributeName.equals( ( (ConstantUtf8) constant ).getBytes() ) )
1989 {
1990 attributeIndex = i;
1991 nameIndex = attributes[i].getNameIndex();
1992 }
1993 }
1994
1995 if ( nameIndex == -1 )
1996 {
1997 final Constant[] pool = clazz.getConstantPool().getConstantPool();
1998 final Constant[] tmp = new Constant[ pool.length + 1 ];
1999 System.arraycopy( pool, 0, tmp, 0, pool.length );
2000 tmp[pool.length] = new ConstantUtf8( attributeName );
2001 nameIndex = pool.length;
2002 clazz.setConstantPool( new ConstantPool( tmp ) );
2003 }
2004
2005 final Unknown unknown = new Unknown( nameIndex, attributeData.length, attributeData, clazz.getConstantPool() );
2006
2007 if ( attributeIndex == -1 )
2008 {
2009 final Attribute[] tmp = new Attribute[ attributes.length + 1 ];
2010 System.arraycopy( attributes, 0, tmp, 0, attributes.length );
2011 tmp[attributes.length] = unknown;
2012 attributes = tmp;
2013 }
2014 else
2015 {
2016 attributes[attributeIndex] = unknown;
2017 }
2018
2019 clazz.setAttributes( attributes );
2020 }
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035 public byte[] encodeModelObject( final Marshaller marshaller, final JAXBElement<? extends ModelObject> modelObject )
2036 throws IOException
2037 {
2038 if ( marshaller == null )
2039 {
2040 throw new NullPointerException( "marshaller" );
2041 }
2042 if ( modelObject == null )
2043 {
2044 throw new NullPointerException( "modelObject" );
2045 }
2046
2047 try
2048 {
2049 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
2050 final GZIPOutputStream out = new GZIPOutputStream( baos );
2051 marshaller.marshal( modelObject, out );
2052 out.close();
2053 return baos.toByteArray();
2054 }
2055 catch ( final JAXBException e )
2056 {
2057 String message = getMessage( e );
2058 if ( message == null && e.getLinkedException() != null )
2059 {
2060 message = getMessage( e.getLinkedException() );
2061 }
2062
2063
2064 throw (IOException) new IOException( message ).initCause( e );
2065 }
2066 }
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083 public <T extends ModelObject> T decodeModelObject( final Unmarshaller unmarshaller, final byte[] bytes,
2084 final Class<T> type ) throws IOException
2085 {
2086 if ( unmarshaller == null )
2087 {
2088 throw new NullPointerException( "unmarshaller" );
2089 }
2090 if ( bytes == null )
2091 {
2092 throw new NullPointerException( "bytes" );
2093 }
2094 if ( type == null )
2095 {
2096 throw new NullPointerException( "type" );
2097 }
2098
2099 try
2100 {
2101 final ByteArrayInputStream bais = new ByteArrayInputStream( bytes );
2102 final GZIPInputStream in = new GZIPInputStream( bais );
2103 final JAXBElement<T> element = (JAXBElement<T>) unmarshaller.unmarshal( in );
2104 in.close();
2105 return element.getValue();
2106 }
2107 catch ( final JAXBException e )
2108 {
2109 String message = getMessage( e );
2110 if ( message == null && e.getLinkedException() != null )
2111 {
2112 message = getMessage( e.getLinkedException() );
2113 }
2114
2115
2116 throw (IOException) new IOException( message ).initCause( e );
2117 }
2118 }
2119
2120 private void commitModelObjects( final Specifications specifications, final Implementations implementations,
2121 final Marshaller marshaller, final File classesDirectory ) throws IOException
2122 {
2123 if ( specifications != null )
2124 {
2125 for ( int i = specifications.getSpecification().size() - 1; i >= 0; i-- )
2126 {
2127 this.commitModelObjects( specifications.getSpecification().get( i ), marshaller, classesDirectory );
2128 }
2129 }
2130
2131 if ( implementations != null )
2132 {
2133 for ( int i = implementations.getImplementation().size() - 1; i >= 0; i-- )
2134 {
2135 this.commitModelObjects( implementations.getImplementation().get( i ), marshaller, classesDirectory );
2136 }
2137 }
2138 }
2139
2140 private void commitModelObjects( final Specification specification, final Marshaller marshaller,
2141 final File classesDirectory ) throws IOException
2142 {
2143 if ( specification.isClassDeclaration() )
2144 {
2145 final String classLocation = specification.getClazz().replace( '.', File.separatorChar ) + ".class";
2146 final File classFile = new File( classesDirectory, classLocation );
2147
2148 if ( !classesDirectory.isDirectory() )
2149 {
2150 throw new IOException( getMessage( "directoryNotFound", classesDirectory.getAbsolutePath() ) );
2151 }
2152 if ( !classFile.isFile() )
2153 {
2154 throw new IOException( getMessage( "fileNotFound", classFile.getAbsolutePath() ) );
2155 }
2156 if ( !( classFile.canRead() && classFile.canWrite() ) )
2157 {
2158 throw new IOException( getMessage( "fileAccessDenied", classFile.getAbsolutePath() ) );
2159 }
2160
2161 if ( this.isLoggable( Level.INFO ) )
2162 {
2163 this.log( Level.INFO, getMessage( "committing", classFile.getAbsolutePath() ), null );
2164 }
2165
2166 final JavaClass javaClass = this.readJavaClass( classFile );
2167 this.commitModelObjects( specification, marshaller, javaClass );
2168 this.writeJavaClass( javaClass, classFile );
2169 }
2170 }
2171
2172 private void commitModelObjects( final Implementation implementation, final Marshaller marshaller,
2173 final File classesDirectory ) throws IOException
2174 {
2175 if ( implementation.isClassDeclaration() )
2176 {
2177 final String classLocation = implementation.getClazz().replace( '.', File.separatorChar ) + ".class";
2178 final File classFile = new File( classesDirectory, classLocation );
2179
2180 if ( !classesDirectory.isDirectory() )
2181 {
2182 throw new IOException( getMessage( "directoryNotFound", classesDirectory.getAbsolutePath() ) );
2183 }
2184 if ( !classFile.isFile() )
2185 {
2186 throw new IOException( getMessage( "fileNotFound", classFile.getAbsolutePath() ) );
2187 }
2188 if ( !( classFile.canRead() && classFile.canWrite() ) )
2189 {
2190 throw new IOException( getMessage( "fileAccessDenied", classFile.getAbsolutePath() ) );
2191 }
2192
2193 if ( this.isLoggable( Level.INFO ) )
2194 {
2195 this.log( Level.INFO, getMessage( "committing", classFile.getAbsolutePath() ), null );
2196 }
2197
2198 final JavaClass javaClass = this.readJavaClass( classFile );
2199 this.commitModelObjects( implementation, marshaller, javaClass );
2200 this.writeJavaClass( javaClass, classFile );
2201 }
2202 }
2203
2204 private ModelValidationReport validateModelObjects( final Specifications specifications,
2205 final Implementations implementations,
2206 final Unmarshaller unmarshaller, final File classesDirectory )
2207 throws IOException
2208 {
2209 final ModelValidationReport report = new ModelValidationReport();
2210
2211 if ( specifications != null )
2212 {
2213 for ( int i = 0, s0 = specifications.getSpecification().size(); i < s0; i++ )
2214 {
2215 final ModelValidationReport current = this.validateModelObjects(
2216 specifications.getSpecification().get( i ), unmarshaller, classesDirectory );
2217
2218 report.getDetails().addAll( current.getDetails() );
2219 }
2220 }
2221
2222 if ( implementations != null )
2223 {
2224 for ( int i = 0, s0 = implementations.getImplementation().size(); i < s0; i++ )
2225 {
2226 final ModelValidationReport current = this.validateModelObjects(
2227 implementations.getImplementation().get( i ), unmarshaller, classesDirectory );
2228
2229 report.getDetails().addAll( current.getDetails() );
2230 }
2231 }
2232
2233 return report;
2234 }
2235
2236 private ModelValidationReport validateModelObjects( final Specification specification,
2237 final Unmarshaller unmarshaller,
2238 final File classesDirectory ) throws IOException
2239 {
2240 final ModelValidationReport report = new ModelValidationReport();
2241
2242 if ( specification.isClassDeclaration() )
2243 {
2244 final String classLocation = specification.getClazz().replace( '.', File.separatorChar ) + ".class";
2245 final File classFile = new File( classesDirectory, classLocation );
2246
2247 if ( !classesDirectory.isDirectory() )
2248 {
2249 throw new IOException( getMessage( "directoryNotFound", classesDirectory.getAbsolutePath() ) );
2250 }
2251 if ( !classFile.isFile() )
2252 {
2253 throw new IOException( getMessage( "fileNotFound", classFile.getAbsolutePath() ) );
2254 }
2255 if ( !classFile.canRead() )
2256 {
2257 throw new IOException( getMessage( "fileAccessDenied", classFile.getAbsolutePath() ) );
2258 }
2259
2260 if ( this.isLoggable( Level.INFO ) )
2261 {
2262 this.log( Level.INFO, getMessage( "validating", classFile.getAbsolutePath() ), null );
2263 }
2264
2265 final JavaClass javaClass = this.readJavaClass( classFile );
2266
2267 report.getDetails().addAll(
2268 this.validateModelObjects( specification, unmarshaller, javaClass ).getDetails() );
2269
2270 }
2271
2272 return report;
2273 }
2274
2275 private ModelValidationReport validateModelObjects( final Implementation implementation,
2276 final Unmarshaller unmarshaller,
2277 final File classesDirectory ) throws IOException
2278 {
2279 final ModelValidationReport report = new ModelValidationReport();
2280
2281 if ( implementation.isClassDeclaration() )
2282 {
2283 final String classLocation = implementation.getClazz().replace( '.', File.separatorChar ) + ".class";
2284 final File classFile = new File( classesDirectory, classLocation );
2285
2286 if ( !classesDirectory.isDirectory() )
2287 {
2288 throw new IOException( getMessage( "directoryNotFound", classesDirectory.getAbsolutePath() ) );
2289 }
2290 if ( !classFile.isFile() )
2291 {
2292 throw new IOException( getMessage( "fileNotFound", classFile.getAbsolutePath() ) );
2293 }
2294 if ( !classFile.canRead() )
2295 {
2296 throw new IOException( getMessage( "fileAccessDenied", classFile.getAbsolutePath() ) );
2297 }
2298
2299 if ( this.isLoggable( Level.INFO ) )
2300 {
2301 this.log( Level.INFO, getMessage( "validating", classFile.getAbsolutePath() ), null );
2302 }
2303
2304 final JavaClass javaClass = this.readJavaClass( classFile );
2305
2306 report.getDetails().addAll(
2307 this.validateModelObjects( implementation, unmarshaller, javaClass ).getDetails() );
2308
2309 }
2310
2311 return report;
2312 }
2313
2314 private ModelValidationReport validateModelObjects( final Specifications specifications,
2315 final Implementations implementations,
2316 final Unmarshaller unmarshaller, final ModelContext context )
2317 throws IOException, ModelException
2318 {
2319 final ModelValidationReport report = new ModelValidationReport();
2320
2321 if ( specifications != null )
2322 {
2323 for ( int i = 0, s0 = specifications.getSpecification().size(); i < s0; i++ )
2324 {
2325 final ModelValidationReport current = this.validateModelObjects(
2326 specifications.getSpecification().get( i ), unmarshaller, context );
2327
2328 report.getDetails().addAll( current.getDetails() );
2329 }
2330 }
2331
2332 if ( implementations != null )
2333 {
2334 for ( int i = 0, s0 = implementations.getImplementation().size(); i < s0; i++ )
2335 {
2336 final ModelValidationReport current = this.validateModelObjects(
2337 implementations.getImplementation().get( i ), unmarshaller, context );
2338
2339 report.getDetails().addAll( current.getDetails() );
2340 }
2341 }
2342
2343 return report;
2344 }
2345
2346 private ModelValidationReport validateModelObjects( final Specification specification,
2347 final Unmarshaller unmarshaller,
2348 final ModelContext context ) throws IOException, ModelException
2349 {
2350 final ModelValidationReport report = new ModelValidationReport();
2351
2352 if ( specification.isClassDeclaration() )
2353 {
2354 final String classLocation = specification.getClazz().replace( '.', '/' ) + ".class";
2355
2356 final URL classUrl = context.findResource( classLocation );
2357
2358 if ( classUrl == null )
2359 {
2360 throw new IOException( getMessage( "resourceNotFound", classLocation ) );
2361 }
2362
2363 if ( this.isLoggable( Level.INFO ) )
2364 {
2365 this.log( Level.INFO, getMessage( "validatingSpecification", specification.getIdentifier() ), null );
2366 }
2367
2368 InputStream in = null;
2369 JavaClass javaClass = null;
2370 boolean suppressExceptionOnClose = true;
2371
2372 try
2373 {
2374 in = classUrl.openStream();
2375 javaClass = new ClassParser( in, classUrl.toExternalForm() ).parse();
2376 suppressExceptionOnClose = false;
2377 }
2378 finally
2379 {
2380 try
2381 {
2382 if ( in != null )
2383 {
2384 in.close();
2385 }
2386 }
2387 catch ( final IOException e )
2388 {
2389 if ( suppressExceptionOnClose )
2390 {
2391 this.log( Level.SEVERE, getMessage( e ), e );
2392 }
2393 else
2394 {
2395 throw e;
2396 }
2397 }
2398 }
2399
2400 report.getDetails().addAll(
2401 this.validateModelObjects( specification, unmarshaller, javaClass ).getDetails() );
2402
2403 }
2404
2405 return report;
2406 }
2407
2408 private ModelValidationReport validateModelObjects( final Implementation implementation,
2409 final Unmarshaller unmarshaller,
2410 final ModelContext context ) throws IOException, ModelException
2411 {
2412 final ModelValidationReport report = new ModelValidationReport();
2413
2414 if ( implementation.isClassDeclaration() )
2415 {
2416 final String classLocation = implementation.getClazz().replace( '.', '/' ) + ".class";
2417
2418 final URL classUrl = context.findResource( classLocation );
2419
2420 if ( classUrl == null )
2421 {
2422 throw new IOException( getMessage( "resourceNotFound", classLocation ) );
2423 }
2424
2425 if ( this.isLoggable( Level.INFO ) )
2426 {
2427 this.log( Level.INFO, getMessage( "validatingImplementation", implementation.getIdentifier() ), null );
2428 }
2429
2430 InputStream in = null;
2431 JavaClass javaClass = null;
2432 boolean suppressExceptionOnClose = true;
2433
2434 try
2435 {
2436 in = classUrl.openStream();
2437 javaClass = new ClassParser( in, classUrl.toExternalForm() ).parse();
2438 suppressExceptionOnClose = false;
2439 }
2440 finally
2441 {
2442 try
2443 {
2444 if ( in != null )
2445 {
2446 in.close();
2447 }
2448 }
2449 catch ( final IOException e )
2450 {
2451 if ( suppressExceptionOnClose )
2452 {
2453 this.log( Level.SEVERE, getMessage( e ), e );
2454 }
2455 else
2456 {
2457 throw e;
2458 }
2459 }
2460 }
2461
2462 report.getDetails().addAll(
2463 this.validateModelObjects( implementation, unmarshaller, javaClass ).getDetails() );
2464
2465 }
2466
2467 return report;
2468 }
2469
2470 private void transformModelObjects( final Specifications specifications, final Implementations implementations,
2471 final Unmarshaller unmarshaller, final Marshaller marshaller,
2472 final File classesDirectory, final List<Transformer> transformers )
2473 throws IOException
2474 {
2475 if ( specifications != null )
2476 {
2477 for ( int i = 0, s0 = specifications.getSpecification().size(); i < s0; i++ )
2478 {
2479 this.transformModelObjects( specifications.getSpecification().get( i ), marshaller, unmarshaller,
2480 classesDirectory, transformers );
2481
2482 }
2483 }
2484
2485 if ( implementations != null )
2486 {
2487 for ( int i = 0, s0 = implementations.getImplementation().size(); i < s0; i++ )
2488 {
2489 this.transformModelObjects( implementations.getImplementation().get( i ), marshaller, unmarshaller,
2490 classesDirectory, transformers );
2491
2492 }
2493 }
2494 }
2495
2496 private void transformModelObjects( final Specification specification, final Marshaller marshaller,
2497 final Unmarshaller unmarshaller, final File classesDirectory,
2498 final List<Transformer> transformers ) throws IOException
2499 {
2500 if ( specification.isClassDeclaration() )
2501 {
2502 final String classLocation = specification.getClazz().replace( '.', File.separatorChar ) + ".class";
2503 final File classFile = new File( classesDirectory, classLocation );
2504
2505 if ( !classesDirectory.isDirectory() )
2506 {
2507 throw new IOException( getMessage( "directoryNotFound", classesDirectory.getAbsolutePath() ) );
2508 }
2509 if ( !classFile.isFile() )
2510 {
2511 throw new IOException( getMessage( "fileNotFound", classFile.getAbsolutePath() ) );
2512 }
2513 if ( !( classFile.canRead() && classFile.canWrite() ) )
2514 {
2515 throw new IOException( getMessage( "fileAccessDenied", classFile.getAbsolutePath() ) );
2516 }
2517
2518 if ( this.isLoggable( Level.INFO ) )
2519 {
2520 this.log( Level.INFO, getMessage( "transforming", classFile.getAbsolutePath() ), null );
2521 }
2522
2523 final JavaClass javaClass = this.readJavaClass( classFile );
2524 this.transformModelObjects( specification, marshaller, unmarshaller, javaClass, transformers );
2525 this.writeJavaClass( javaClass, classFile );
2526 }
2527 }
2528
2529 private void transformModelObjects( final Implementation implementation, final Marshaller marshaller,
2530 final Unmarshaller unmarshaller, final File classesDirectory,
2531 final List<Transformer> transformers ) throws IOException
2532 {
2533 if ( implementation.isClassDeclaration() )
2534 {
2535 final String classLocation = implementation.getClazz().replace( '.', File.separatorChar ) + ".class";
2536 final File classFile = new File( classesDirectory, classLocation );
2537
2538 if ( !classesDirectory.isDirectory() )
2539 {
2540 throw new IOException( getMessage( "directoryNotFound", classesDirectory.getAbsolutePath() ) );
2541 }
2542 if ( !classFile.isFile() )
2543 {
2544 throw new IOException( getMessage( "fileNotFound", classFile.getAbsolutePath() ) );
2545 }
2546 if ( !( classFile.canRead() && classFile.canWrite() ) )
2547 {
2548 throw new IOException( getMessage( "fileAccessDenied", classFile.getAbsolutePath() ) );
2549 }
2550
2551 if ( this.isLoggable( Level.INFO ) )
2552 {
2553 this.log( Level.INFO, getMessage( "transforming", classFile.getAbsolutePath() ), null );
2554 }
2555
2556 final JavaClass javaClass = this.readJavaClass( classFile );
2557 this.transformModelObjects( implementation, marshaller, unmarshaller, javaClass, transformers );
2558 this.writeJavaClass( javaClass, classFile );
2559 }
2560 }
2561
2562 private JavaClass readJavaClass( final File classFile ) throws IOException
2563 {
2564 FileInputStream in = null;
2565 FileChannel fileChannel = null;
2566 FileLock fileLock = null;
2567 boolean suppressExceptionOnClose = true;
2568
2569 try
2570 {
2571 in = new FileInputStream( classFile );
2572 fileChannel = in.getChannel();
2573 fileLock = fileChannel.lock( 0, classFile.length(), true );
2574
2575 final JavaClass javaClass = new ClassParser( in, classFile.getAbsolutePath() ).parse();
2576 suppressExceptionOnClose = false;
2577 return javaClass;
2578 }
2579 finally
2580 {
2581 this.releaseAndClose( fileLock, fileChannel, in, suppressExceptionOnClose );
2582 }
2583 }
2584
2585 private void writeJavaClass( final JavaClass javaClass, final File classFile ) throws IOException
2586 {
2587 RandomAccessFile randomAccessFile = null;
2588 FileChannel fileChannel = null;
2589 FileLock fileLock = null;
2590 boolean suppressExceptionOnClose = true;
2591
2592 final ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
2593 javaClass.dump( byteStream );
2594 byteStream.close();
2595
2596 final byte[] bytes = byteStream.toByteArray();
2597
2598 try
2599 {
2600 randomAccessFile = new RandomAccessFile( classFile, "rw" );
2601 fileChannel = randomAccessFile.getChannel();
2602 fileLock = fileChannel.lock();
2603 fileChannel.truncate( bytes.length );
2604 fileChannel.position( 0L );
2605 fileChannel.write( ByteBuffer.wrap( bytes ) );
2606 fileChannel.force( true );
2607 suppressExceptionOnClose = false;
2608 }
2609 finally
2610 {
2611 this.releaseAndClose( fileLock, fileChannel, randomAccessFile, suppressExceptionOnClose );
2612 }
2613 }
2614
2615 private void releaseAndClose( final FileLock fileLock, final FileChannel fileChannel,
2616 final Closeable closeable, final boolean suppressExceptions )
2617 throws IOException
2618 {
2619 try
2620 {
2621 if ( fileLock != null )
2622 {
2623 fileLock.release();
2624 }
2625 }
2626 catch ( final IOException e )
2627 {
2628 if ( suppressExceptions )
2629 {
2630 this.log( Level.SEVERE, null, e );
2631 }
2632 else
2633 {
2634 throw e;
2635 }
2636 }
2637 finally
2638 {
2639 try
2640 {
2641 if ( fileChannel != null )
2642 {
2643 fileChannel.close();
2644 }
2645 }
2646 catch ( final IOException e )
2647 {
2648 if ( suppressExceptions )
2649 {
2650 this.log( Level.SEVERE, null, e );
2651 }
2652 else
2653 {
2654 throw e;
2655 }
2656 }
2657 finally
2658 {
2659 try
2660 {
2661 if ( closeable != null )
2662 {
2663 closeable.close();
2664 }
2665 }
2666 catch ( final IOException e )
2667 {
2668 if ( suppressExceptions )
2669 {
2670 this.log( Level.SEVERE, null, e );
2671 }
2672 else
2673 {
2674 throw e;
2675 }
2676 }
2677 }
2678 }
2679 }
2680
2681 private static String getMessage( final String key, final Object... arguments )
2682 {
2683 return MessageFormat.format( ResourceBundle.getBundle(
2684 ClassFileProcessor.class.getName().replace( '.', '/' ) ).getString( key ), arguments );
2685
2686 }
2687
2688 private static String getMessage( final Throwable t )
2689 {
2690 return t != null ? t.getMessage() != null ? t.getMessage() : getMessage( t.getCause() ) : null;
2691 }
2692
2693 }