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