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.Collections;
25 import java.util.HashSet;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Map.Entry;
29 import java.util.Set;
30
31 import ca.uhn.fhir.model.api.IElement;
32 import ca.uhn.fhir.model.api.IResource;
33 import ca.uhn.fhir.model.api.annotation.Child;
34 import ca.uhn.fhir.model.api.annotation.Description;
35 import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
36
37 public class RuntimeChildResourceDefinition extends BaseRuntimeDeclaredChildDefinition {
38
39 private BaseRuntimeElementDefinition<?> myRuntimeDef;
40 private List<Class<? extends IResource>> myResourceTypes;
41 private Set<String> myValidChildNames;
42
43 public RuntimeChildResourceDefinition(Field theField, String theElementName, Child theChildAnnotation, Description theDescriptionAnnotation, List<Class<? extends IResource>> theResourceTypes) {
44 super(theField, theChildAnnotation, theDescriptionAnnotation, theElementName);
45 myResourceTypes = theResourceTypes;
46
47 if (theResourceTypes == null || theResourceTypes.isEmpty()) {
48 throw new ConfigurationException("Field '" + theField.getName() + "' on type '" + theField.getDeclaringClass().getCanonicalName() + "' has no resource types noted");
49 }
50 }
51
52 @Override
53 public String getChildNameByDatatype(Class<? extends IElement> theDatatype) {
54 if (BaseResourceReferenceDt.class.isAssignableFrom(theDatatype)) {
55 return getElementName();
56 }
57 return null;
58 }
59
60 @Override
61 public BaseRuntimeElementDefinition<?> getChildElementDefinitionByDatatype(Class<? extends IElement> theDatatype) {
62 if (BaseResourceReferenceDt.class.isAssignableFrom(theDatatype)) {
63 return myRuntimeDef;
64 }
65 return null;
66 }
67
68 @Override
69 public Set<String> getValidChildNames() {
70 return myValidChildNames;
71 }
72
73 @Override
74 public BaseRuntimeElementDefinition<?> getChildByName(String theName) {
75 return myRuntimeDef;
76 }
77
78 @Override
79 void sealAndInitialize(Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions) {
80 myRuntimeDef = new RuntimeResourceReferenceDefinition(getElementName(), myResourceTypes);
81 myRuntimeDef.sealAndInitialize(theClassToElementDefinitions);
82
83 myValidChildNames = new HashSet<String>();
84 myValidChildNames.add(getElementName());
85 myValidChildNames.add(getElementName() + "Resource");
86
87 for (Class<? extends IResource> next : myResourceTypes) {
88 if (next == IResource.class) {
89 for (Entry<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> nextEntry : theClassToElementDefinitions.entrySet()) {
90 if (IResource.class.isAssignableFrom(nextEntry.getKey())) {
91 RuntimeResourceDefinition nextDef = (RuntimeResourceDefinition) nextEntry.getValue();
92 myValidChildNames.add(getElementName() + nextDef.getName());
93 }
94 }
95 } else {
96 RuntimeResourceDefinition nextDef = (RuntimeResourceDefinition) theClassToElementDefinitions.get(next);
97 if (nextDef == null) {
98 throw new ConfigurationException("Can't find child of type: " + next.getCanonicalName() + " in " + getField().getDeclaringClass());
99 }
100 myValidChildNames.add(getElementName() + nextDef.getName());
101 }
102 }
103
104 myResourceTypes = Collections.unmodifiableList(myResourceTypes);
105 myValidChildNames = Collections.unmodifiableSet(myValidChildNames);
106 }
107
108 public List<Class<? extends IResource>> getResourceTypes() {
109 return myResourceTypes;
110 }
111
112 @Override
113 public String toString() {
114 return getClass().getSimpleName() + "[" + getElementName() + "]";
115 }
116 }