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