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