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