View Javadoc
1   package ca.uhn.fhir.model.view;
2   
3   /*
4    * #%L
5    * HAPI FHIR - Core Library
6    * %%
7    * Copyright (C) 2014 - 2018 University Health Network
8    * %%
9    * Licensed under the Apache License, Version 2.0 (the "License");
10   * you may not use this file except in compliance with the License.
11   * You may obtain a copy of the License at
12   * 
13   *      http://www.apache.org/licenses/LICENSE-2.0
14   * 
15   * Unless required by applicable law or agreed to in writing, software
16   * distributed under the License is distributed on an "AS IS" BASIS,
17   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18   * See the License for the specific language governing permissions and
19   * limitations under the License.
20   * #L%
21   */
22  
23  import java.util.List;
24  
25  import org.hl7.fhir.instance.model.api.IBase;
26  import org.hl7.fhir.instance.model.api.IBaseExtension;
27  
28  import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
29  import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
30  import ca.uhn.fhir.context.ConfigurationException;
31  import ca.uhn.fhir.context.FhirContext;
32  import ca.uhn.fhir.context.RuntimeChildDeclaredExtensionDefinition;
33  import ca.uhn.fhir.context.RuntimeResourceDefinition;
34  import ca.uhn.fhir.model.api.BaseElement;
35  import ca.uhn.fhir.model.api.ExtensionDt;
36  import ca.uhn.fhir.model.api.IResource;
37  
38  public class ViewGenerator {
39  
40  	private FhirContext myCtx;
41  
42  	public ViewGenerator(FhirContext theFhirContext) {
43  		myCtx=theFhirContext;
44  	}
45  
46  	public <T extends IResource> T newView(IResource theResource, Class<T> theTargetType) {
47  		Class<? extends IResource> sourceType = theResource.getClass();
48  		RuntimeResourceDefinition sourceDef = myCtx.getResourceDefinition(theResource);
49  		RuntimeResourceDefinition targetDef = myCtx.getResourceDefinition(theTargetType);
50  
51  		if (sourceType.equals(theTargetType)) {
52  			@SuppressWarnings("unchecked")
53  			T resource = (T) theResource;
54  			return resource;
55  		}
56  
57  		T retVal;
58  		try {
59  			retVal = theTargetType.newInstance();
60  		} catch (InstantiationException e) {
61  			throw new ConfigurationException("Failed to instantiate " + theTargetType, e);
62  		} catch (IllegalAccessException e) {
63  			throw new ConfigurationException("Failed to instantiate " + theTargetType, e);
64  		}
65  
66  		copyChildren(sourceDef, (BaseElement) theResource, targetDef, (BaseElement) retVal);
67  
68  		return retVal;
69  	}
70  
71  	private void copyChildren(BaseRuntimeElementCompositeDefinition<?> theSourceDef, BaseElement theSource, BaseRuntimeElementCompositeDefinition<?> theTargetDef, BaseElement theTarget) {
72  		if (!theSource.isEmpty()) {
73  			List<BaseRuntimeChildDefinition> targetChildren = theTargetDef.getChildren();
74  			List<RuntimeChildDeclaredExtensionDefinition> targetExts = theTargetDef.getExtensions();
75  
76  			for (BaseRuntimeChildDefinition nextChild : targetChildren) {
77  
78  				String elementName = nextChild.getElementName();
79  				if (nextChild.getValidChildNames().size() > 1) {
80  					elementName = nextChild.getValidChildNames().iterator().next();
81  				}
82  				
83  				BaseRuntimeChildDefinition sourceChildEquivalent = theSourceDef.getChildByNameOrThrowDataFormatException(elementName);
84  				if (sourceChildEquivalent == null) {
85  					continue;
86  				}
87  
88  				List<? extends IBase> sourceValues = sourceChildEquivalent.getAccessor().getValues(theSource);
89  				for (IBase nextElement : sourceValues) {
90  					boolean handled = false;
91  					if (nextElement instanceof IBaseExtension) {
92  						String url = ((IBaseExtension<?,?>) nextElement).getUrl();
93  						for (RuntimeChildDeclaredExtensionDefinition nextExt : targetExts) {
94  							String nextTargetUrl = nextExt.getExtensionUrl();
95  							if (!nextTargetUrl.equals(url)) {
96  								continue;
97  							}
98  							addExtension(theSourceDef, theSource, theTarget, nextExt, url);
99  							handled = true;
100 						}						
101 					} 
102 					if (!handled) {
103 						nextChild.getMutator().addValue(theTarget, nextElement);
104 					}
105 				}
106 			}
107 			
108 			for (RuntimeChildDeclaredExtensionDefinition nextExt : targetExts) {
109 				String url = nextExt.getExtensionUrl();
110 				addExtension(theSourceDef, theSource, theTarget, nextExt, url);
111 			}
112 			
113 			
114 		}
115 	}
116 
117 	private void addExtension(BaseRuntimeElementCompositeDefinition<?> theSourceDef, BaseElement theSource, BaseElement theTarget, RuntimeChildDeclaredExtensionDefinition nextExt, String url) {
118 		RuntimeChildDeclaredExtensionDefinition sourceDeclaredExt = theSourceDef.getDeclaredExtension(url, "");
119 		if (sourceDeclaredExt == null) {
120 			
121 			for (ExtensionDt next : theSource.getAllUndeclaredExtensions()) {
122 				if (next.getUrlAsString().equals(url)) {
123 					nextExt.getMutator().addValue(theTarget, next.getValue());
124 				}
125 			}
126 			
127 		} else {
128 			
129 			List<? extends IBase> values = sourceDeclaredExt.getAccessor().getValues(theSource);
130 			for (IBase nextElement : values) {
131 				nextExt.getMutator().addValue(theTarget, nextElement);
132 			}
133 			
134 		}
135 	}
136 }