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