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.model;
32
33 import java.util.Collection;
34 import java.util.Collections;
35 import java.util.HashMap;
36 import java.util.HashSet;
37 import java.util.Iterator;
38 import java.util.LinkedList;
39 import java.util.List;
40 import java.util.Map;
41 import java.util.Set;
42 import javax.xml.bind.JAXBElement;
43 import javax.xml.namespace.QName;
44 import org.w3c.dom.Element;
45
46
47
48
49
50
51
52
53 public class InheritanceModel
54 {
55
56
57
58
59
60
61
62
63
64
65 public static class Node<T>
66 {
67
68
69
70
71 private final Implementation implementation;
72
73
74
75
76 private final Specification specification;
77
78
79
80
81 private final Implementation classDeclaration;
82
83
84
85
86 private final Node<Implementation> descendant;
87
88
89
90
91 private final T modelObject;
92
93
94
95
96 private final boolean _final;
97
98
99
100
101 private final boolean override;
102
103
104
105
106 private final LinkedList<Node<Implementation>> path = new LinkedList<Node<Implementation>>();
107
108
109
110
111 private final Set<Node<T>> overriddenNodes = new HashSet<Node<T>>();
112
113
114
115
116
117
118
119
120
121
122
123
124
125 public Node( final Implementation implementation, final Specification specification,
126 final Implementation classDeclaration, final Node<Implementation> descendant, final T modelObject,
127 final boolean finalNode, final boolean overrideNode )
128 {
129 super();
130 this.implementation = implementation;
131 this.specification = specification;
132 this.classDeclaration = classDeclaration;
133 this.descendant = descendant;
134 this.modelObject = modelObject;
135 this._final = finalNode;
136 this.override = overrideNode;
137 }
138
139
140
141
142
143
144 public final Implementation getImplementation()
145 {
146 return this.implementation;
147 }
148
149
150
151
152
153
154
155 public final Specification getSpecification()
156 {
157 return this.specification;
158 }
159
160
161
162
163
164
165
166 public final Implementation getClassDeclaration()
167 {
168 return this.classDeclaration;
169 }
170
171
172
173
174
175
176
177
178 public final Node<Implementation> getDescendant()
179 {
180 return this.descendant;
181 }
182
183
184
185
186
187
188 public final T getModelObject()
189 {
190 return this.modelObject;
191 }
192
193
194
195
196
197
198 public final boolean isFinal()
199 {
200 return this._final;
201 }
202
203
204
205
206
207
208 public final boolean isOverride()
209 {
210 return this.override;
211 }
212
213
214
215
216
217
218 public final Set<Node<T>> getOverriddenNodes()
219 {
220 return Collections.unmodifiableSet( this.overriddenNodes );
221 }
222
223
224
225
226
227
228 public final List<Node<Implementation>> getPath()
229 {
230 return Collections.unmodifiableList( this.path );
231 }
232
233
234
235
236
237
238
239
240 private Set<Node<T>> getModifiableOverriddenNodes()
241 {
242 return this.overriddenNodes;
243 }
244
245
246
247
248
249
250
251
252 private LinkedList<Node<Implementation>> getModifiablePath()
253 {
254 return this.path;
255 }
256
257 }
258
259
260
261
262 private enum ContextState
263 {
264
265 PREPARING,
266 PREPARED
267
268 }
269
270
271
272
273 private final Modules modules;
274
275
276
277
278 private final Map<String, Map<String, Set<Node<Dependency>>>> dependencies = newMap();
279
280
281
282
283 private final Map<String, Map<String, Map<String, Set<Node<Dependency>>>>> effDependencies = newMap();
284
285
286
287
288 private final Map<String, Map<String, Set<Node<Message>>>> messages = newMap();
289
290
291
292
293 private final Map<String, Map<String, Map<String, Set<Node<Message>>>>> effMessages = newMap();
294
295
296
297
298 private final Map<String, Map<String, Set<Node<Property>>>> properties = newMap();
299
300
301
302
303 private final Map<String, Map<String, Map<String, Set<Node<Property>>>>> effProperties = newMap();
304
305
306
307
308 private final Map<String, Map<String, Set<Node<SpecificationReference>>>> specReferences = newMap();
309
310
311
312
313 private final Map<String, Map<String, Map<String, Set<Node<SpecificationReference>>>>> effSpecReferences =
314 newMap();
315
316
317
318
319 private final Map<String, Map<String, Set<Node<ImplementationReference>>>> implReferences = newMap();
320
321
322
323
324 private final Map<String, Set<Node<ImplementationReference>>> cyclicImplReferences = newMap();
325
326
327
328
329 private final Map<String, Map<String, Map<String, Set<Node<ImplementationReference>>>>> effImplReferences =
330 newMap();
331
332
333
334
335 private final Map<String, Map<QName, Set<Node<Element>>>> xmlElements = newMap();
336
337
338
339
340 private final Map<String, Map<String, Map<QName, Set<Node<Element>>>>> effXmlElements = newMap();
341
342
343
344
345 private final Map<String, Map<QName, Set<Node<JAXBElement<?>>>>> jaxbElements = newMap();
346
347
348
349
350 private final Map<String, Map<String, Map<QName, Set<Node<JAXBElement<?>>>>>> effJaxbElements =
351 newMap();
352
353
354
355
356 private final Map<String, Map<String, Node<Implementation>>> implementations = newMap();
357
358
359
360
361 private final Map<String, Map<String, Node<Implementation>>> sourceNodes = newMap();
362
363
364
365
366 private final Map<String, ContextState> contextStates = newMap();
367
368
369
370
371
372
373
374
375
376
377 public InheritanceModel( final Modules modules )
378 {
379 super();
380
381 if ( modules == null )
382 {
383 throw new NullPointerException( "modules" );
384 }
385
386 this.modules = modules.clone();
387 }
388
389
390
391
392
393
394
395
396
397
398
399
400 public Set<Node<Implementation>> getSourceNodes( final String implementation )
401 {
402 if ( implementation == null )
403 {
404 throw new NullPointerException( "implementation" );
405 }
406
407 this.prepareContext( implementation );
408 final Collection<Node<Implementation>> col = map( this.sourceNodes, implementation ).values();
409 return unmodifiableSet( newSet( col ) );
410 }
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427 public Set<Node<ImplementationReference>> getCycleNodes( final String implementation )
428 {
429 if ( implementation == null )
430 {
431 throw new NullPointerException( "implementation" );
432 }
433
434 this.prepareContext( implementation );
435 return unmodifiableSet( nodes( this.cyclicImplReferences, implementation ) );
436 }
437
438
439
440
441
442
443
444
445
446
447
448 public Set<String> getDependencyNames( final String implementation )
449 {
450 if ( implementation == null )
451 {
452 throw new NullPointerException( "implementation" );
453 }
454
455 this.prepareContext( implementation );
456 return Collections.unmodifiableSet( map( this.dependencies, implementation ).keySet() );
457 }
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472 public Set<Node<Dependency>> getDependencyNodes( final String implementation, final String name )
473 {
474 if ( implementation == null )
475 {
476 throw new NullPointerException( "implementation" );
477 }
478 if ( name == null )
479 {
480 throw new NullPointerException( "name" );
481 }
482
483 this.prepareContext( implementation );
484 Set<Node<Dependency>> set = null;
485
486 final Map<String, Set<Node<Dependency>>> map =
487 getEffectiveNodes( this.effDependencies, implementation, implementation );
488
489 if ( map != null )
490 {
491 set = map.get( name );
492 }
493
494 return unmodifiableSet( set );
495 }
496
497
498
499
500
501
502
503
504
505
506
507
508 public Set<String> getImplementationReferenceIdentifiers( final String implementation )
509 {
510 if ( implementation == null )
511 {
512 throw new NullPointerException( "implementation" );
513 }
514
515 this.prepareContext( implementation );
516 return Collections.unmodifiableSet( map( this.implReferences, implementation ).keySet() );
517 }
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532 public Set<Node<ImplementationReference>> getImplementationReferenceNodes( final String implementation,
533 final String identifier )
534 {
535 if ( implementation == null )
536 {
537 throw new NullPointerException( "implementation" );
538 }
539 if ( identifier == null )
540 {
541 throw new NullPointerException( "identifier" );
542 }
543
544 this.prepareContext( implementation );
545 Set<Node<ImplementationReference>> set = null;
546 final Map<String, Set<Node<ImplementationReference>>> map =
547 getEffectiveNodes( this.effImplReferences, implementation, implementation );
548
549 if ( map != null )
550 {
551 set = map.get( identifier );
552 }
553
554 return unmodifiableSet( set );
555 }
556
557
558
559
560
561
562
563
564
565
566
567 public Set<QName> getJaxbElementNames( final String implementation )
568 {
569 if ( implementation == null )
570 {
571 throw new NullPointerException( "implementation" );
572 }
573
574 this.prepareContext( implementation );
575 return Collections.unmodifiableSet( map( this.jaxbElements, implementation ).keySet() );
576 }
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591 public Set<Node<JAXBElement<?>>> getJaxbElementNodes( final String implementation, final QName name )
592 {
593 if ( implementation == null )
594 {
595 throw new NullPointerException( "implementation" );
596 }
597 if ( name == null )
598 {
599 throw new NullPointerException( "name" );
600 }
601
602 this.prepareContext( implementation );
603 Set<Node<JAXBElement<?>>> set = null;
604 final Map<QName, Set<Node<JAXBElement<?>>>> map =
605 getEffectiveNodes( this.effJaxbElements, implementation, implementation );
606
607 if ( map != null )
608 {
609 set = map.get( name );
610 }
611
612 return unmodifiableSet( set );
613 }
614
615
616
617
618
619
620
621
622
623
624
625 public Set<String> getMessageNames( final String implementation )
626 {
627 if ( implementation == null )
628 {
629 throw new NullPointerException( "implementation" );
630 }
631
632 this.prepareContext( implementation );
633 return Collections.unmodifiableSet( map( this.messages, implementation ).keySet() );
634 }
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649 public Set<Node<Message>> getMessageNodes( final String implementation, final String name )
650 {
651 if ( implementation == null )
652 {
653 throw new NullPointerException( "implementation" );
654 }
655 if ( name == null )
656 {
657 throw new NullPointerException( "name" );
658 }
659
660 this.prepareContext( implementation );
661 Set<Node<Message>> set = null;
662 final Map<String, Set<Node<Message>>> map =
663 getEffectiveNodes( this.effMessages, implementation, implementation );
664
665 if ( map != null )
666 {
667 set = map.get( name );
668 }
669
670 return unmodifiableSet( set );
671 }
672
673
674
675
676
677
678
679
680
681
682
683 public Set<String> getPropertyNames( final String implementation )
684 {
685 if ( implementation == null )
686 {
687 throw new NullPointerException( "implementation" );
688 }
689
690 this.prepareContext( implementation );
691 return Collections.unmodifiableSet( map( this.properties, implementation ).keySet() );
692 }
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707 public Set<Node<Property>> getPropertyNodes( final String implementation, final String name )
708 {
709 if ( implementation == null )
710 {
711 throw new NullPointerException( "implementation" );
712 }
713 if ( name == null )
714 {
715 throw new NullPointerException( "name" );
716 }
717
718 this.prepareContext( implementation );
719 Set<Node<Property>> set = null;
720 final Map<String, Set<Node<Property>>> map =
721 getEffectiveNodes( this.effProperties, implementation, implementation );
722
723 if ( map != null )
724 {
725 set = map.get( name );
726 }
727
728 return unmodifiableSet( set );
729 }
730
731
732
733
734
735
736
737
738
739
740
741
742 public Set<String> getSpecificationReferenceIdentifiers( final String implementation )
743 {
744 if ( implementation == null )
745 {
746 throw new NullPointerException( "implementation" );
747 }
748
749 this.prepareContext( implementation );
750 return Collections.unmodifiableSet( map( this.specReferences, implementation ).keySet() );
751 }
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766 public Set<Node<SpecificationReference>> getSpecificationReferenceNodes( final String implementation,
767 final String identifier )
768 {
769 if ( implementation == null )
770 {
771 throw new NullPointerException( "implementation" );
772 }
773 if ( identifier == null )
774 {
775 throw new NullPointerException( "identifier" );
776 }
777
778 this.prepareContext( implementation );
779 Set<Node<SpecificationReference>> set = null;
780 final Map<String, Set<Node<SpecificationReference>>> map =
781 getEffectiveNodes( this.effSpecReferences, implementation, implementation );
782
783 if ( map != null )
784 {
785 set = map.get( identifier );
786 }
787
788 return unmodifiableSet( set );
789 }
790
791
792
793
794
795
796
797
798
799
800
801 public Set<QName> getXmlElementNames( final String implementation )
802 {
803 if ( implementation == null )
804 {
805 throw new NullPointerException( "implementation" );
806 }
807
808 this.prepareContext( implementation );
809 return Collections.unmodifiableSet( map( this.xmlElements, implementation ).keySet() );
810 }
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825 public Set<Node<Element>> getXmlElementNodes( final String implementation, final QName name )
826 {
827 if ( implementation == null )
828 {
829 throw new NullPointerException( "implementation" );
830 }
831 if ( name == null )
832 {
833 throw new NullPointerException( "name" );
834 }
835
836 this.prepareContext( implementation );
837 Set<Node<Element>> set = null;
838 final Map<QName, Set<Node<Element>>> map =
839 getEffectiveNodes( this.effXmlElements, implementation, implementation );
840
841 if ( map != null )
842 {
843 set = map.get( name );
844 }
845
846 return unmodifiableSet( set );
847 }
848
849 private void prepareContext( final String context )
850 {
851 ContextState state = this.contextStates.get( context );
852
853 if ( state == null )
854 {
855 state = ContextState.PREPARING;
856 this.contextStates.put( context, state );
857
858 final Implementation i = this.modules.getImplementation( context );
859
860 if ( i != null )
861 {
862 this.collectNodes( context, i, null, null );
863
864 for ( final Node<Implementation> source : map( this.sourceNodes, context ).values() )
865 {
866 this.collectEffectiveNodes( context, source );
867 }
868 }
869
870 state = ContextState.PREPARED;
871 this.contextStates.put( context, state );
872 }
873
874 assert state == ContextState.PREPARED :
875 "Unexpected context state '" + state + "' for context '" + context + "'.";
876
877 }
878
879 private void collectNodes( final String context, final Implementation declaration,
880 final Node<Implementation> descendant, LinkedList<Node<Implementation>> path )
881 {
882 if ( path == null )
883 {
884 path = new LinkedList<Node<Implementation>>();
885 }
886
887 final Map<String, Node<Implementation>> contextImplementations = map( this.implementations, context );
888
889 if ( declaration != null && !contextImplementations.containsKey( declaration.getIdentifier() ) )
890 {
891 final Node<Implementation> declarationNode = new Node<Implementation>(
892 declaration, null, null, descendant, declaration, declaration.isFinal(), false );
893
894 declarationNode.getModifiablePath().addAll( path );
895
896 contextImplementations.put( declaration.getIdentifier(), declarationNode );
897
898 path.addLast( declarationNode );
899
900 if ( declaration.getDependencies() != null )
901 {
902 for ( int i = 0, s0 = declaration.getDependencies().getDependency().size(); i < s0; i++ )
903 {
904 final Dependency d = declaration.getDependencies().getDependency().get( i );
905 final Node<Dependency> node =
906 new Node<Dependency>( declaration, null, null, descendant, d, d.isFinal(), d.isOverride() );
907
908 node.getModifiablePath().addAll( path );
909
910 addNode( map( this.dependencies, context ), node, node.getModelObject().getName() );
911 }
912 }
913
914 if ( declaration.getMessages() != null )
915 {
916 for ( int i = 0, s0 = declaration.getMessages().getMessage().size(); i < s0; i++ )
917 {
918 final Message m = declaration.getMessages().getMessage().get( i );
919 final Node<Message> node =
920 new Node<Message>( declaration, null, null, descendant, m, m.isFinal(), m.isOverride() );
921
922 node.getModifiablePath().addAll( path );
923
924 addNode( map( this.messages, context ), node, node.getModelObject().getName() );
925 }
926
927 if ( !declaration.getMessages().getReference().isEmpty() )
928 {
929 final Module m = this.modules.getModuleOfImplementation( declaration.getIdentifier() );
930
931 if ( m != null && m.getMessages() != null )
932 {
933 for ( int i = 0, s0 = declaration.getMessages().getReference().size(); i < s0; i++ )
934 {
935 final MessageReference r = declaration.getMessages().getReference().get( i );
936 Message msg = m.getMessages().getMessage( r.getName() );
937
938 if ( msg != null )
939 {
940 msg = msg.clone();
941 msg.setFinal( r.isFinal() );
942 msg.setOverride( r.isOverride() );
943
944 final Node<Message> node = new Node<Message>(
945 declaration, null, null, descendant, msg, msg.isFinal(), msg.isOverride() );
946
947 node.getModifiablePath().addAll( path );
948
949 addNode( map( this.messages, context ), node, node.getModelObject().getName() );
950 }
951 }
952 }
953 }
954 }
955
956 if ( declaration.getProperties() != null )
957 {
958 for ( int i = 0, s0 = declaration.getProperties().getProperty().size(); i < s0; i++ )
959 {
960 final Property p = declaration.getProperties().getProperty().get( i );
961 final Node<Property> node =
962 new Node<Property>( declaration, null, null, descendant, p, p.isFinal(), p.isOverride() );
963
964 node.getModifiablePath().addAll( path );
965
966 addNode( map( this.properties, context ), node, node.getModelObject().getName() );
967 }
968
969 if ( !declaration.getProperties().getReference().isEmpty() )
970 {
971 final Module m = this.modules.getModuleOfImplementation( declaration.getIdentifier() );
972
973 if ( m != null && m.getProperties() != null )
974 {
975 for ( int i = 0, s0 = declaration.getProperties().getReference().size(); i < s0; i++ )
976 {
977 final PropertyReference r = declaration.getProperties().getReference().get( i );
978 Property p = m.getProperties().getProperty( r.getName() );
979
980 if ( p != null )
981 {
982 p = p.clone();
983 p.setFinal( r.isFinal() );
984 p.setOverride( r.isOverride() );
985
986 final Node<Property> node = new Node<Property>(
987 declaration, null, null, descendant, p, p.isFinal(), p.isOverride() );
988
989 node.getModifiablePath().addAll( path );
990
991 addNode( map( this.properties, context ), node, node.getModelObject().getName() );
992 }
993 }
994 }
995 }
996 }
997
998 if ( declaration.getSpecifications() != null )
999 {
1000 for ( int i = 0, s0 = declaration.getSpecifications().getReference().size(); i < s0; i++ )
1001 {
1002 final SpecificationReference r = declaration.getSpecifications().getReference().get( i );
1003 final Node<SpecificationReference> node = new Node<SpecificationReference>(
1004 declaration, null, null, descendant, r, r.isFinal(), r.isOverride() );
1005
1006 node.getModifiablePath().addAll( path );
1007
1008 addNode( map( this.specReferences, context ), node, node.getModelObject().getIdentifier() );
1009
1010 final Specification s = this.modules.getSpecification( r.getIdentifier() );
1011
1012 if ( s != null && s.getProperties() != null )
1013 {
1014 for ( int j = 0, s1 = s.getProperties().getProperty().size(); j < s1; j++ )
1015 {
1016 final Property p = s.getProperties().getProperty().get( j );
1017 final Node<Property> n =
1018 new Node<Property>( declaration, s, null, descendant, p, p.isFinal(), p.isOverride() );
1019
1020 n.getModifiablePath().addAll( path );
1021
1022 addNode( map( this.properties, context ), n, n.getModelObject().getName() );
1023 }
1024 }
1025 }
1026 }
1027
1028 if ( !declaration.getAny().isEmpty() )
1029 {
1030 for ( int i = 0, s0 = declaration.getAny().size(); i < s0; i++ )
1031 {
1032 final Object any = declaration.getAny().get( i );
1033
1034 if ( any instanceof Element )
1035 {
1036 final Element e = (Element) any;
1037 final Node<Element> node =
1038 new Node<Element>( declaration, null, null, descendant, e, false, false );
1039
1040 node.getModifiablePath().addAll( path );
1041
1042 addNode( map( this.xmlElements, context ), node, getXmlElementName( e ) );
1043 continue;
1044 }
1045
1046 if ( any instanceof JAXBElement<?> )
1047 {
1048 final JAXBElement<?> e = (JAXBElement<?>) any;
1049 boolean _final = false;
1050 boolean override = false;
1051
1052 if ( e.getValue() instanceof Inheritable )
1053 {
1054 _final = ( (Inheritable) e.getValue() ).isFinal();
1055 override = ( (Inheritable) e.getValue() ).isOverride();
1056 }
1057
1058 final Node<JAXBElement<?>> node =
1059 new Node<JAXBElement<?>>( declaration, null, null, descendant, e, _final, override );
1060
1061 node.getModifiablePath().addAll( path );
1062
1063 addNode( map( this.jaxbElements, context ), node, e.getName() );
1064 continue;
1065 }
1066 }
1067 }
1068
1069 if ( declaration.getImplementations() != null
1070 && !declaration.getImplementations().getReference().isEmpty() )
1071 {
1072 boolean all_cyclic = true;
1073
1074 for ( int i = 0, s0 = declaration.getImplementations().getReference().size(); i < s0; i++ )
1075 {
1076 final ImplementationReference r = declaration.getImplementations().getReference().get( i );
1077 final Node<ImplementationReference> node = new Node<ImplementationReference>(
1078 declaration, null, null, descendant, r, r.isFinal(), r.isOverride() );
1079
1080 node.getModifiablePath().addAll( path );
1081
1082 final Implementation ancestor = this.modules.getImplementation( r.getIdentifier() );
1083
1084 boolean cycle = false;
1085 if ( ancestor != null && contextImplementations.containsKey( ancestor.getIdentifier() ) )
1086 {
1087 for ( int j = 0, s1 = path.size(); j < s1; j++ )
1088 {
1089 final Node<Implementation> n = path.get( j );
1090
1091 if ( n.getModelObject().getIdentifier().equals( ancestor.getIdentifier() ) )
1092 {
1093 cycle = true;
1094 node.getModifiablePath().add( n );
1095 break;
1096 }
1097 }
1098 }
1099
1100 if ( cycle )
1101 {
1102 addNode( this.cyclicImplReferences, node, context );
1103 }
1104 else
1105 {
1106 all_cyclic = false;
1107 addNode( map( this.implReferences, context ), node, node.getModelObject().getIdentifier() );
1108 this.collectNodes( context, ancestor, declarationNode, path );
1109 }
1110 }
1111
1112 if ( all_cyclic )
1113 {
1114 map( this.sourceNodes, context ).
1115 put( declarationNode.getModelObject().getIdentifier(), declarationNode );
1116
1117 }
1118 }
1119 else
1120 {
1121 map( this.sourceNodes, context ).
1122 put( declarationNode.getModelObject().getIdentifier(), declarationNode );
1123
1124 }
1125
1126 path.removeLast();
1127 }
1128 }
1129
1130 private void collectEffectiveNodes( final String context, final Node<Implementation> node )
1131 {
1132 final Map<String, Set<Node<SpecificationReference>>> directSpecificationReferences =
1133 getDirectEffectiveNodes( map( this.specReferences, context ), node.getModelObject().getIdentifier() );
1134
1135 final Map<String, Set<Node<Dependency>>> directDependencies =
1136 getDirectEffectiveNodes( map( this.dependencies, context ), node.getModelObject().getIdentifier() );
1137
1138 final Map<String, Set<Node<Message>>> directMessages =
1139 getDirectEffectiveNodes( map( this.messages, context ), node.getModelObject().getIdentifier() );
1140
1141 final Map<String, Set<Node<Property>>> directProperties =
1142 getDirectEffectiveNodes( map( this.properties, context ), node.getModelObject().getIdentifier() );
1143
1144 final Map<String, Set<Node<ImplementationReference>>> directImplementationReferences =
1145 getDirectEffectiveNodes( map( this.implReferences, context ), node.getModelObject().getIdentifier() );
1146
1147 final Map<QName, Set<Node<Element>>> directXmlElements =
1148 getDirectEffectiveNodes( map( this.xmlElements, context ), node.getModelObject().getIdentifier() );
1149
1150 final Map<QName, Set<Node<JAXBElement<?>>>> directJaxbElements =
1151 getDirectEffectiveNodes( map( this.jaxbElements, context ), node.getModelObject().getIdentifier() );
1152
1153 overrideNodes( map( this.effSpecReferences, context ), node, directSpecificationReferences );
1154 overrideNodes( map( this.effImplReferences, context ), node, directImplementationReferences );
1155 overrideNodes( map( this.effDependencies, context ), node, directDependencies );
1156 overrideNodes( map( this.effMessages, context ), node, directMessages );
1157 overrideNodes( map( this.effProperties, context ), node, directProperties );
1158 overrideNodes( map( this.effJaxbElements, context ), node, directJaxbElements );
1159 overrideNodes( map( this.effXmlElements, context ), node, directXmlElements );
1160
1161 this.addClassDeclarationNodes( context, node );
1162
1163 final Map<String, Set<Node<SpecificationReference>>> ancestorSpecificationReferences =
1164 getEffectiveNodes( this.effSpecReferences, context, node.getModelObject().getIdentifier() );
1165
1166 final Map<String, Set<Node<Dependency>>> ancestorDependencies =
1167 getEffectiveNodes( this.effDependencies, context, node.getModelObject().getIdentifier() );
1168
1169 final Map<String, Set<Node<Message>>> ancestorMessages =
1170 getEffectiveNodes( this.effMessages, context, node.getModelObject().getIdentifier() );
1171
1172 final Map<String, Set<Node<Property>>> ancestorProperties =
1173 getEffectiveNodes( this.effProperties, context, node.getModelObject().getIdentifier() );
1174
1175 final Map<String, Set<Node<ImplementationReference>>> ancestorImplementationReferences =
1176 getEffectiveNodes( this.effImplReferences, context, node.getModelObject().getIdentifier() );
1177
1178 final Map<QName, Set<Node<Element>>> ancestorXmlElements =
1179 getEffectiveNodes( this.effXmlElements, context, node.getModelObject().getIdentifier() );
1180
1181 final Map<QName, Set<Node<JAXBElement<?>>>> ancestorJaxbElements =
1182 getEffectiveNodes( this.effJaxbElements, context, node.getModelObject().getIdentifier() );
1183
1184 if ( node.getDescendant() != null )
1185 {
1186 if ( ancestorSpecificationReferences != null )
1187 {
1188 inheritNodes( map( this.effSpecReferences, context ), ancestorSpecificationReferences,
1189 node.getDescendant() );
1190
1191 }
1192
1193 if ( ancestorDependencies != null )
1194 {
1195 inheritNodes( map( this.effDependencies, context ), ancestorDependencies,
1196 node.getDescendant() );
1197
1198 }
1199
1200 if ( ancestorProperties != null )
1201 {
1202 inheritNodes( map( this.effProperties, context ), ancestorProperties, node.getDescendant() );
1203 }
1204
1205 if ( ancestorMessages != null )
1206 {
1207 inheritNodes( map( this.effMessages, context ), ancestorMessages, node.getDescendant() );
1208 }
1209
1210 if ( ancestorImplementationReferences != null )
1211 {
1212 inheritNodes( map( this.effImplReferences, context ), ancestorImplementationReferences,
1213 node.getDescendant() );
1214
1215 }
1216
1217 if ( ancestorXmlElements != null )
1218 {
1219 inheritNodes( map( this.effXmlElements, context ), ancestorXmlElements,
1220 node.getDescendant() );
1221
1222 }
1223
1224 if ( ancestorJaxbElements != null )
1225 {
1226 inheritNodes( map( this.effJaxbElements, context ), ancestorJaxbElements,
1227 node.getDescendant() );
1228
1229 }
1230
1231 collectEffectiveNodes( context, node.getDescendant() );
1232 }
1233 }
1234
1235 private void addClassDeclarationNodes( final String context, final Node<Implementation> node )
1236 {
1237 final Implementation classDeclaration = this.getClassDeclaration( node.getModelObject() );
1238
1239 if ( classDeclaration != null )
1240 {
1241 this.prepareContext( classDeclaration.getIdentifier() );
1242
1243 Map<String, Set<Node<Dependency>>> effectiveDependencies =
1244 getEffectiveNodes( this.effDependencies, context, node.getModelObject().getIdentifier() );
1245
1246 Map<String, Set<Node<Message>>> effectiveMessages =
1247 getEffectiveNodes( this.effMessages, context, node.getModelObject().getIdentifier() );
1248
1249 Map<String, Set<Node<Property>>> effectiveProperties =
1250 getEffectiveNodes( this.effProperties, context, node.getModelObject().getIdentifier() );
1251
1252 Map<String, Set<Node<SpecificationReference>>> effectiveSpecificationReferences =
1253 getEffectiveNodes( this.effSpecReferences, context, node.getModelObject().getIdentifier() );
1254
1255 Map<QName, Set<Node<Element>>> effectiveXmlElements =
1256 getEffectiveNodes( this.effXmlElements, context, node.getModelObject().getIdentifier() );
1257
1258 Map<QName, Set<Node<JAXBElement<?>>>> effectiveJaxbElements =
1259 getEffectiveNodes( this.effJaxbElements, context, node.getModelObject().getIdentifier() );
1260
1261 final Map<String, Set<Node<Dependency>>> declDependencies =
1262 getEffectiveNodes( this.effDependencies, classDeclaration.getIdentifier(),
1263 classDeclaration.getIdentifier() );
1264
1265 final Map<String, Set<Node<Message>>> declMessages =
1266 getEffectiveNodes( this.effMessages, classDeclaration.getIdentifier(),
1267 classDeclaration.getIdentifier() );
1268
1269 final Map<String, Set<Node<Property>>> declProperties =
1270 getEffectiveNodes( this.effProperties, classDeclaration.getIdentifier(),
1271 classDeclaration.getIdentifier() );
1272
1273 final Map<String, Set<Node<SpecificationReference>>> declSpecReferences =
1274 getEffectiveNodes( this.effSpecReferences, classDeclaration.getIdentifier(),
1275 classDeclaration.getIdentifier() );
1276
1277 final Map<QName, Set<Node<Element>>> declXmlElements =
1278 getEffectiveNodes( this.effXmlElements, classDeclaration.getIdentifier(),
1279 classDeclaration.getIdentifier() );
1280
1281 final Map<QName, Set<Node<JAXBElement<?>>>> declJaxbElements =
1282 getEffectiveNodes( this.effJaxbElements, classDeclaration.getIdentifier(),
1283 classDeclaration.getIdentifier() );
1284
1285 if ( declDependencies != null )
1286 {
1287 if ( effectiveDependencies == null )
1288 {
1289 effectiveDependencies = newMap();
1290 map( this.effDependencies, context ).
1291 put( node.getModelObject().getIdentifier(), effectiveDependencies );
1292
1293 }
1294
1295 for ( final Map.Entry<String, Set<Node<Dependency>>> e : declDependencies.entrySet() )
1296 {
1297 final Set<Node<Dependency>> set = newSet( e.getValue().size() );
1298
1299 for ( final Node<Dependency> n : e.getValue() )
1300 {
1301 final Node<Dependency> effNode = new Node<Dependency>(
1302 node.getModelObject(), n.getSpecification(), classDeclaration, null, n.getModelObject(),
1303 n.isFinal(), n.isOverride() );
1304
1305 effNode.getModifiablePath().addAll( n.getPath() );
1306 set.add( effNode );
1307
1308 addNode( map( this.dependencies, context ), effNode, e.getKey() );
1309 }
1310
1311 if ( effectiveDependencies.containsKey( e.getKey() ) )
1312 {
1313 for ( final Node<Dependency> effNode : effectiveDependencies.get( e.getKey() ) )
1314 {
1315 effNode.getModifiableOverriddenNodes().addAll( set );
1316 }
1317 }
1318 else
1319 {
1320 effectiveDependencies.put( e.getKey(), set );
1321 }
1322 }
1323 }
1324
1325 if ( declSpecReferences != null )
1326 {
1327 if ( effectiveSpecificationReferences == null )
1328 {
1329 effectiveSpecificationReferences = newMap();
1330 map( this.effSpecReferences, context ).
1331 put( node.getModelObject().getIdentifier(), effectiveSpecificationReferences );
1332
1333 }
1334
1335 for ( final Map.Entry<String, Set<Node<SpecificationReference>>> e : declSpecReferences.entrySet() )
1336 {
1337 final Set<Node<SpecificationReference>> set = newSet( e.getValue().size() );
1338
1339 for ( final Node<SpecificationReference> n : e.getValue() )
1340 {
1341 final Node<SpecificationReference> effNode = new Node<SpecificationReference>(
1342 node.getModelObject(), n.getSpecification(), classDeclaration, null, n.getModelObject(),
1343 n.isFinal(), n.isOverride() );
1344
1345 effNode.getModifiablePath().addAll( n.getPath() );
1346 set.add( effNode );
1347
1348 addNode( map( this.specReferences, context ), effNode, e.getKey() );
1349 }
1350
1351 if ( effectiveSpecificationReferences.containsKey( e.getKey() ) )
1352 {
1353 for ( final Node<SpecificationReference> effNode
1354 : effectiveSpecificationReferences.get( e.getKey() ) )
1355 {
1356 effNode.getModifiableOverriddenNodes().addAll( set );
1357 }
1358 }
1359 else
1360 {
1361 effectiveSpecificationReferences.put( e.getKey(), set );
1362 }
1363 }
1364 }
1365
1366 if ( declMessages != null )
1367 {
1368 if ( effectiveMessages == null )
1369 {
1370 effectiveMessages = newMap();
1371 map( this.effMessages, context ).
1372 put( node.getModelObject().getIdentifier(), effectiveMessages );
1373
1374 }
1375
1376 for ( final Map.Entry<String, Set<Node<Message>>> e : declMessages.entrySet() )
1377 {
1378 final Set<Node<Message>> set = newSet( e.getValue().size() );
1379
1380 for ( final Node<Message> n : e.getValue() )
1381 {
1382 final Node<Message> effNode = new Node<Message>(
1383 node.getModelObject(), n.getSpecification(), classDeclaration, null, n.getModelObject(),
1384 n.isFinal(), n.isOverride() );
1385
1386 effNode.getModifiablePath().addAll( n.getPath() );
1387 set.add( effNode );
1388
1389 addNode( map( this.messages, context ), effNode, e.getKey() );
1390 }
1391
1392 if ( effectiveMessages.containsKey( e.getKey() ) )
1393 {
1394 for ( final Node<Message> effNode : effectiveMessages.get( e.getKey() ) )
1395 {
1396 effNode.getModifiableOverriddenNodes().addAll( set );
1397 }
1398 }
1399 else
1400 {
1401 effectiveMessages.put( e.getKey(), set );
1402 }
1403 }
1404 }
1405
1406 if ( declProperties != null )
1407 {
1408 if ( effectiveProperties == null )
1409 {
1410 effectiveProperties = newMap();
1411 map( this.effProperties, context ).
1412 put( node.getModelObject().getIdentifier(), effectiveProperties );
1413
1414 }
1415
1416 for ( final Map.Entry<String, Set<Node<Property>>> e : declProperties.entrySet() )
1417 {
1418 final Set<Node<Property>> set = newSet( e.getValue().size() );
1419
1420 for ( final Node<Property> n : e.getValue() )
1421 {
1422 final Node<Property> effNode = new Node<Property>(
1423 node.getModelObject(), n.getSpecification(), classDeclaration, null, n.getModelObject(),
1424 n.isFinal(), n.isOverride() );
1425
1426 effNode.getModifiablePath().addAll( n.getPath() );
1427 set.add( effNode );
1428
1429 addNode( map( this.properties, context ), effNode, e.getKey() );
1430 }
1431
1432 if ( effectiveProperties.containsKey( e.getKey() ) )
1433 {
1434 for ( final Node<Property> effNode : effectiveProperties.get( e.getKey() ) )
1435 {
1436 effNode.getModifiableOverriddenNodes().addAll( set );
1437 }
1438 }
1439 else
1440 {
1441 effectiveProperties.put( e.getKey(), set );
1442 }
1443 }
1444 }
1445
1446 if ( declXmlElements != null )
1447 {
1448 if ( effectiveXmlElements == null )
1449 {
1450 effectiveXmlElements = newMap();
1451 map( this.effXmlElements, context ).
1452 put( node.getModelObject().getIdentifier(), effectiveXmlElements );
1453
1454 }
1455
1456 for ( final Map.Entry<QName, Set<Node<Element>>> e : declXmlElements.entrySet() )
1457 {
1458 final Set<Node<Element>> set = newSet( e.getValue().size() );
1459
1460 for ( final Node<Element> n : e.getValue() )
1461 {
1462 final Node<Element> effNode = new Node<Element>(
1463 node.getModelObject(), n.getSpecification(), classDeclaration, null, n.getModelObject(),
1464 n.isFinal(), n.isOverride() );
1465
1466 effNode.getModifiablePath().addAll( n.getPath() );
1467 set.add( effNode );
1468
1469 addNode( map( this.xmlElements, context ), effNode, e.getKey() );
1470 }
1471
1472 if ( effectiveXmlElements.containsKey( e.getKey() ) )
1473 {
1474 for ( final Node<Element> effNode : effectiveXmlElements.get( e.getKey() ) )
1475 {
1476 effNode.getModifiableOverriddenNodes().addAll( set );
1477 }
1478 }
1479 else
1480 {
1481 effectiveXmlElements.put( e.getKey(), set );
1482 }
1483 }
1484 }
1485
1486 if ( declJaxbElements != null )
1487 {
1488 if ( effectiveJaxbElements == null )
1489 {
1490 effectiveJaxbElements = newMap();
1491 map( this.effJaxbElements, context ).
1492 put( node.getModelObject().getIdentifier(), effectiveJaxbElements );
1493
1494 }
1495
1496 for ( final Map.Entry<QName, Set<Node<JAXBElement<?>>>> e : declJaxbElements.entrySet() )
1497 {
1498 final Set<Node<JAXBElement<?>>> set = newSet( e.getValue().size() );
1499
1500 for ( final Node<JAXBElement<?>> n : e.getValue() )
1501 {
1502 final Node<JAXBElement<?>> effNode = new Node<JAXBElement<?>>(
1503 node.getModelObject(), n.getSpecification(), classDeclaration, null, n.getModelObject(),
1504 n.isFinal(), n.isOverride() );
1505
1506 effNode.getModifiablePath().addAll( n.getPath() );
1507 set.add( effNode );
1508
1509 addNode( map( this.jaxbElements, context ), effNode, e.getKey() );
1510 }
1511
1512 if ( effectiveJaxbElements.containsKey( e.getKey() ) )
1513 {
1514 for ( final Node<JAXBElement<?>> effNode : effectiveJaxbElements.get( e.getKey() ) )
1515 {
1516 effNode.getModifiableOverriddenNodes().addAll( set );
1517 }
1518 }
1519 else
1520 {
1521 effectiveJaxbElements.put( e.getKey(), set );
1522 }
1523 }
1524 }
1525 }
1526 }
1527
1528 private Implementation getClassDeclaration( final Implementation implementation )
1529 {
1530 Implementation declaration = null;
1531
1532 if ( implementation.getClazz() != null && !implementation.isClassDeclaration() )
1533 {
1534 find:
1535 for ( int i = 0, s0 = this.modules.getModule().size(); i < s0; i++ )
1536 {
1537 final Module candidateModule = this.modules.getModule().get( i );
1538
1539 if ( candidateModule.getImplementations() != null )
1540 {
1541 for ( int j = 0, s1 = candidateModule.getImplementations().getImplementation().size(); j < s1; j++ )
1542 {
1543 final Implementation candidate =
1544 candidateModule.getImplementations().getImplementation().get( j );
1545
1546 if ( candidate.isClassDeclaration()
1547 && candidate.getClazz().equals( implementation.getClazz() ) )
1548 {
1549 declaration = candidate;
1550 break find;
1551 }
1552 }
1553 }
1554 }
1555 }
1556
1557 return declaration;
1558 }
1559
1560 private static <T, K> void addNode( final Map<K, Set<Node<T>>> map, final Node<T> node, final K key )
1561 {
1562 Set<Node<T>> set = map.get( key );
1563
1564 if ( set == null )
1565 {
1566 set = newSet();
1567 map.put( key, set );
1568 }
1569
1570 set.add( node );
1571 }
1572
1573 private static <T, K> void overrideNodes( final Map<String, Map<K, Set<Node<T>>>> effective,
1574 final Node<Implementation> implementation,
1575 final Map<K, Set<Node<T>>> directNodes )
1576 {
1577 for ( final Map.Entry<K, Set<Node<T>>> e : directNodes.entrySet() )
1578 {
1579 final Set<Node<T>> effectiveNodes =
1580 effectiveNodes( effective, implementation.getModelObject().getIdentifier(), e.getKey() );
1581
1582 final Set<Node<T>> overridingNodes = newSet();
1583
1584 for ( final Node<T> directNode : e.getValue() )
1585 {
1586 for ( final Iterator<Node<T>> it = effectiveNodes.iterator(); it.hasNext(); )
1587 {
1588 final Node<T> effectiveNode = it.next();
1589
1590 if ( isOverriding( effectiveNode, directNode ) )
1591 {
1592 it.remove();
1593
1594 if ( directNode != effectiveNode )
1595 {
1596 directNode.getModifiableOverriddenNodes().add( effectiveNode );
1597 }
1598 }
1599 }
1600
1601 boolean overriddenByAncestor = false;
1602
1603 if ( directNode.getSpecification() != null )
1604 {
1605 for ( final Node<T> effectiveNode : effectiveNodes )
1606 {
1607 if ( effectiveNode.getSpecification() == null )
1608 {
1609 overriddenByAncestor = true;
1610 effectiveNode.getModifiableOverriddenNodes().add( directNode );
1611 }
1612 }
1613 }
1614
1615 if ( !overriddenByAncestor )
1616 {
1617 overridingNodes.add( directNode );
1618 }
1619 }
1620
1621 effectiveNodes.addAll( overridingNodes );
1622 }
1623 }
1624
1625 private static <K, V, T> Map<K, V> map( final Map<T, Map<K, V>> map, final T context )
1626 {
1627 Map<K, V> contextMap = map.get( context );
1628
1629 if ( contextMap == null )
1630 {
1631 contextMap = newMap();
1632 map.put( context, contextMap );
1633 }
1634
1635 return contextMap;
1636 }
1637
1638 private static <K, V> Set<Node<V>> nodes( final Map<K, Set<Node<V>>> map, final K key )
1639 {
1640 Set<Node<V>> nodes = map.get( key );
1641
1642 if ( nodes == null )
1643 {
1644 nodes = newSet();
1645 map.put( key, nodes );
1646 }
1647
1648 return nodes;
1649 }
1650
1651 private static <K, V> Set<Node<V>> effectiveNodes( final Map<String, Map<K, Set<Node<V>>>> map,
1652 final String context, final K key )
1653 {
1654 return nodes( map( map, context ), key );
1655 }
1656
1657 private static <T, K> void inheritNodes(
1658 final Map<String, Map<K, Set<Node<T>>>> effective, final Map<K, Set<Node<T>>> ancestor,
1659 final Node<Implementation> descendant )
1660 {
1661 for ( Map.Entry<K, Set<Node<T>>> e : ancestor.entrySet() )
1662 {
1663 for ( final Node<T> inherit : e.getValue() )
1664 {
1665 if ( isInheritableNode( inherit ) )
1666 {
1667 effectiveNodes( effective, descendant.getModelObject().getIdentifier(), e.getKey() ).add( inherit );
1668 }
1669 }
1670 }
1671 }
1672
1673 private static <T, K> Map<K, Set<Node<T>>> getDirectEffectiveNodes( final Map<K, Set<Node<T>>> map,
1674 final String origin )
1675 {
1676 final Map<K, Set<Node<T>>> declarationMap = newMap( map.size() );
1677
1678 for ( final Map.Entry<K, Set<Node<T>>> e : map.entrySet() )
1679 {
1680 final Set<Node<T>> set = nodes( declarationMap, e.getKey() );
1681
1682 for ( final Node<T> n : e.getValue() )
1683 {
1684 if ( isDirectEffectiveNode( n, origin ) )
1685 {
1686 set.add( n );
1687 }
1688 }
1689
1690 for ( final Node<T> n : e.getValue() )
1691 {
1692 if ( isDirectSpecifiedNode( n, origin ) )
1693 {
1694 boolean add = true;
1695
1696 for ( final Node<T> override : set )
1697 {
1698 if ( override.getSpecification() == null )
1699 {
1700 override.getModifiableOverriddenNodes().add( n );
1701 add = false;
1702 }
1703 }
1704
1705 if ( add )
1706 {
1707 set.add( n );
1708 }
1709 }
1710 }
1711 }
1712
1713 return declarationMap;
1714 }
1715
1716 private static <T, K> Map<K, Set<Node<T>>> getEffectiveNodes(
1717 final Map<String, Map<String, Map<K, Set<Node<T>>>>> effective, final String context,
1718 final String implementation )
1719 {
1720 return map( effective, context ).get( implementation );
1721 }
1722
1723 private static boolean isDirectNode( final Node<?> node, final String implementation )
1724 {
1725 return implementation.equals( node.getImplementation().getIdentifier() );
1726 }
1727
1728 private static boolean isDirectEffectiveNode( final Node<?> node, final String implementation )
1729 {
1730 return isDirectNode( node, implementation ) && node.getClassDeclaration() == null
1731 && node.getSpecification() == null;
1732
1733 }
1734
1735 private static boolean isDirectSpecifiedNode( final Node<?> node, final String implementation )
1736 {
1737 return isDirectNode( node, implementation ) && node.getClassDeclaration() == null
1738 && node.getSpecification() != null;
1739
1740 }
1741
1742 private static boolean isOverriding( final Node<?> node, final Node<?> override )
1743 {
1744 if ( override.getSpecification() != null )
1745 {
1746 if ( node.getSpecification() == null )
1747 {
1748 return false;
1749 }
1750 else if ( !override.getSpecification().getIdentifier().equals( node.getSpecification().getIdentifier() ) )
1751 {
1752 return false;
1753 }
1754 }
1755
1756 return true;
1757 }
1758
1759 private static boolean isInheritableNode( final Node<?> node )
1760 {
1761 return node.getClassDeclaration() == null;
1762 }
1763
1764 private static <K, V> Map<K, V> newMap()
1765 {
1766 return new HashMap<K, V>();
1767 }
1768
1769 private static <K, V> Map<K, V> newMap( final int initialCapacity )
1770 {
1771 return new HashMap<K, V>( initialCapacity );
1772 }
1773
1774 private static <T> Set<T> newSet()
1775 {
1776 return new HashSet<T>();
1777 }
1778
1779 private static <T> Set<T> newSet( final int initialCapacity )
1780 {
1781 return new HashSet<T>( initialCapacity );
1782 }
1783
1784 private static <T> Set<T> newSet( final Collection<? extends T> col )
1785 {
1786 return new HashSet<T>( col );
1787 }
1788
1789 private static <T> Set<T> unmodifiableSet( final Set<T> set )
1790 {
1791 return set != null ? Collections.unmodifiableSet( set ) : Collections.<T>emptySet();
1792 }
1793
1794 private static QName getXmlElementName( final Element element )
1795 {
1796 if ( element.getNamespaceURI() != null )
1797 {
1798 return new QName( element.getNamespaceURI(), element.getLocalName() );
1799 }
1800 else
1801 {
1802 return new QName( element.getLocalName() );
1803 }
1804 }
1805
1806 }