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 ca.uhn.fhir.context.*;
24  import org.hl7.fhir.instance.model.api.*;
25  
26  import java.util.List;
27  
28  public class ViewGenerator {
29  
30  	private FhirContext myCtx;
31  
32  	public ViewGenerator(FhirContext theFhirContext) {
33  		myCtx = theFhirContext;
34  	}
35  
36  	public <T extends IBaseResource> T newView(IBaseResource theResource, Class<T> theTargetType) {
37  		Class<? extends IBaseResource> sourceType = theResource.getClass();
38  		RuntimeResourceDefinition sourceDef = myCtx.getResourceDefinition(theResource);
39  		RuntimeResourceDefinition targetDef = myCtx.getResourceDefinition(theTargetType);
40  
41  		if (sourceType.equals(theTargetType)) {
42  			@SuppressWarnings("unchecked")
43  			T resource = (T) theResource;
44  			return resource;
45  		}
46  
47  		T retVal;
48  		try {
49  			retVal = theTargetType.newInstance();
50  		} catch (Exception e) {
51  			throw new ConfigurationException("Failed to instantiate " + theTargetType, e);
52  		}
53  
54  		copyChildren(sourceDef, (IBase) theResource, targetDef, (IBase) retVal);
55  
56  		return retVal;
57  	}
58  
59  	private void copyChildren(BaseRuntimeElementCompositeDefinition<?> theSourceDef, IBase theSource, BaseRuntimeElementCompositeDefinition<?> theTargetDef, IBase theTarget) {
60  		if (!theSource.isEmpty()) {
61  			List<BaseRuntimeChildDefinition> targetChildren = theTargetDef.getChildren();
62  			List<RuntimeChildDeclaredExtensionDefinition> targetExts = theTargetDef.getExtensions();
63  
64  			for (BaseRuntimeChildDefinition nextChild : targetChildren) {
65  
66  				String elementName = nextChild.getElementName();
67  				if (nextChild.getValidChildNames().size() > 1) {
68  					elementName = nextChild.getValidChildNames().iterator().next();
69  				}
70  
71  				BaseRuntimeChildDefinition sourceChildEquivalent = theSourceDef.getChildByNameOrThrowDataFormatException(elementName);
72  				if (sourceChildEquivalent == null) {
73  					continue;
74  				}
75  
76  				List<? extends IBase> sourceValues = sourceChildEquivalent.getAccessor().getValues(theSource);
77  				for (IBase nextElement : sourceValues) {
78  					boolean handled = false;
79  					if (nextElement instanceof IBaseExtension) {
80  						String url = ((IBaseExtension<?, ?>) nextElement).getUrl();
81  						for (RuntimeChildDeclaredExtensionDefinition nextExt : targetExts) {
82  							String nextTargetUrl = nextExt.getExtensionUrl();
83  							if (!nextTargetUrl.equals(url)) {
84  								continue;
85  							}
86  							addExtension(theSourceDef, theSource, theTarget, nextExt, url);
87  							handled = true;
88  						}
89  					}
90  					if (!handled) {
91  						nextChild.getMutator().addValue(theTarget, nextElement);
92  					}
93  				}
94  			}
95  
96  			for (RuntimeChildDeclaredExtensionDefinition nextExt : targetExts) {
97  				String url = nextExt.getExtensionUrl();
98  				addExtension(theSourceDef, theSource, theTarget, nextExt, url);
99  			}
100 
101 
102 		}
103 	}
104 
105 	private void addExtension(BaseRuntimeElementCompositeDefinition<?> theSourceDef, IBase theSource, IBase theTarget, RuntimeChildDeclaredExtensionDefinition nextExt, String url) {
106 		RuntimeChildDeclaredExtensionDefinition sourceDeclaredExt = theSourceDef.getDeclaredExtension(url, "");
107 		if (sourceDeclaredExt == null) {
108 
109 			if (theSource instanceof IBaseHasExtensions) {
110 				for (IBaseExtension<?, ?> next : ((IBaseHasExtensions) theSource).getExtension()) {
111 					if (next.getUrl().equals(url)) {
112 						nextExt.getMutator().addValue(theTarget, next.getValue());
113 					}
114 				}
115 			}
116 			if (theSource instanceof IBaseHasModifierExtensions) {
117 				for (IBaseExtension<?, ?> next : ((IBaseHasModifierExtensions) theSource).getModifierExtension()) {
118 					if (next.getUrl().equals(url)) {
119 						nextExt.getMutator().addValue(theTarget, next.getValue());
120 					}
121 				}
122 			}
123 
124 		} else {
125 
126 			List<? extends IBase> values = sourceDeclaredExt.getAccessor().getValues(theSource);
127 			for (IBase nextElement : values) {
128 				nextExt.getMutator().addValue(theTarget, nextElement);
129 			}
130 
131 		}
132 	}
133 }