1 package ca.uhn.fhir.context;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 import java.lang.reflect.Field;
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Set;
30
31 import org.apache.commons.lang3.StringUtils;
32
33 import ca.uhn.fhir.model.api.IElement;
34 import ca.uhn.fhir.model.api.IResource;
35 import ca.uhn.fhir.model.api.annotation.Child;
36 import ca.uhn.fhir.model.api.annotation.Description;
37 import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
38
39 public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefinition {
40
41 private List<Class<? extends IElement>> myChoiceTypes;
42 private Map<String, BaseRuntimeElementDefinition<?>> myNameToChildDefinition;
43 private Map<Class<? extends IElement>, String> myDatatypeToElementName;
44 private Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> myDatatypeToElementDefinition;
45
46 public RuntimeChildChoiceDefinition(Field theField, String theElementName, Child theChildAnnotation, Description theDescriptionAnnotation, List<Class<? extends IElement>> theChoiceTypes) {
47 super(theField, theChildAnnotation, theDescriptionAnnotation, theElementName);
48
49 myChoiceTypes = Collections.unmodifiableList(theChoiceTypes);
50 }
51
52
53
54
55 RuntimeChildChoiceDefinition(Field theField, String theElementName, Child theChildAnnotation, Description theDescriptionAnnotation) {
56 super(theField, theChildAnnotation, theDescriptionAnnotation, theElementName);
57 }
58
59 void setChoiceTypes(List<Class<? extends IElement>> theChoiceTypes) {
60 myChoiceTypes = Collections.unmodifiableList(theChoiceTypes);
61 }
62
63 public List<Class<? extends IElement>> getChoices() {
64 return myChoiceTypes;
65 }
66
67 @Override
68 public Set<String> getValidChildNames() {
69 return myNameToChildDefinition.keySet();
70 }
71
72 @Override
73 public BaseRuntimeElementDefinition<?> getChildByName(String theName) {
74 assert myNameToChildDefinition.containsKey(theName);
75
76 return myNameToChildDefinition.get(theName);
77 }
78
79 @SuppressWarnings("unchecked")
80 @Override
81 void sealAndInitialize(Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions) {
82 myNameToChildDefinition = new HashMap<String, BaseRuntimeElementDefinition<?>>();
83 myDatatypeToElementName = new HashMap<Class<? extends IElement>, String>();
84 myDatatypeToElementDefinition = new HashMap<Class<? extends IElement>, BaseRuntimeElementDefinition<?>>();
85
86 for (Class<? extends IElement> next : myChoiceTypes) {
87
88 String elementName;
89 String alternateElementName = null;
90 BaseRuntimeElementDefinition<?> nextDef;
91 if (IResource.class.isAssignableFrom(next)) {
92 elementName = getElementName() + StringUtils.capitalize(next.getSimpleName());
93 alternateElementName = getElementName() + "Resource";
94 List<Class<? extends IResource>> types = new ArrayList<Class<? extends IResource>>();
95 types.add((Class<? extends IResource>) next);
96 nextDef = new RuntimeResourceReferenceDefinition(elementName, types);
97 nextDef.sealAndInitialize(theClassToElementDefinitions);
98 } else {
99 nextDef = theClassToElementDefinitions.get(next);
100 elementName = getElementName() + StringUtils.capitalize(nextDef.getName());
101 }
102
103 myNameToChildDefinition.put(elementName, nextDef);
104 if (alternateElementName != null) {
105 myNameToChildDefinition.put(alternateElementName, nextDef);
106 }
107
108 if (IResource.class.isAssignableFrom(next)) {
109 myDatatypeToElementDefinition.put(ResourceReferenceDt.class, nextDef);
110 alternateElementName = getElementName() + "Resource";
111 myDatatypeToElementName.put(ResourceReferenceDt.class, alternateElementName);
112 }
113
114 myDatatypeToElementDefinition.put(next, nextDef);
115 myDatatypeToElementName.put(next, elementName);
116 }
117
118 myNameToChildDefinition = Collections.unmodifiableMap(myNameToChildDefinition);
119 myDatatypeToElementName = Collections.unmodifiableMap(myDatatypeToElementName);
120 myDatatypeToElementDefinition = Collections.unmodifiableMap(myDatatypeToElementDefinition);
121
122 }
123
124 @Override
125 public String getChildNameByDatatype(Class<? extends IElement> theDatatype) {
126 return myDatatypeToElementName.get(theDatatype);
127 }
128
129 @Override
130 public BaseRuntimeElementDefinition<?> getChildElementDefinitionByDatatype(Class<? extends IElement> theDatatype) {
131 return myDatatypeToElementDefinition.get(theDatatype);
132 }
133
134 public Set<Class<? extends IElement>> getValidChildTypes() {
135 return Collections.unmodifiableSet((myDatatypeToElementDefinition.keySet()));
136 }
137
138 }