View Javadoc
1   package ca.uhn.fhir.model.view;
2   
3   /*
4    * #%L
5    * HAPI FHIR - Core Library
6    * %%
7    * Copyright (C) 2014 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 ca.uhn.fhir.context.BaseRuntimeChildDefinition;
26  import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
27  import ca.uhn.fhir.context.ConfigurationException;
28  import ca.uhn.fhir.context.FhirContext;
29  import ca.uhn.fhir.context.RuntimeChildDeclaredExtensionDefinition;
30  import ca.uhn.fhir.context.RuntimeResourceDefinition;
31  import ca.uhn.fhir.model.api.BaseElement;
32  import ca.uhn.fhir.model.api.ExtensionDt;
33  import ca.uhn.fhir.model.api.IElement;
34  import ca.uhn.fhir.model.api.IResource;
35  
36  public class ViewGenerator {
37  
38  	private FhirContext myCtx;
39  
40  	public ViewGenerator(FhirContext theFhirContext) {
41  		myCtx=theFhirContext;
42  	}
43  
44  	public <T extends IResource> T newView(IResource theResource, Class<T> theTargetType) {
45  		Class<? extends IResource> sourceType = theResource.getClass();
46  		RuntimeResourceDefinition sourceDef = myCtx.getResourceDefinition(theResource);
47  		RuntimeResourceDefinition targetDef = myCtx.getResourceDefinition(theTargetType);
48  
49  		if (sourceType.equals(theTargetType)) {
50  			@SuppressWarnings("unchecked")
51  			T resource = (T) theResource;
52  			return resource;
53  		}
54  
55  		T retVal;
56  		try {
57  			retVal = theTargetType.newInstance();
58  		} catch (InstantiationException e) {
59  			throw new ConfigurationException("Failed to instantiate " + theTargetType, e);
60  		} catch (IllegalAccessException e) {
61  			throw new ConfigurationException("Failed to instantiate " + theTargetType, e);
62  		}
63  
64  		copyChildren(sourceDef, (BaseElement) theResource, targetDef, (BaseElement) retVal);
65  
66  		return retVal;
67  	}
68  
69  	private void copyChildren(BaseRuntimeElementCompositeDefinition<?> theSourceDef, BaseElement theSource, BaseRuntimeElementCompositeDefinition<?> theTargetDef, BaseElement theTarget) {
70  		if (!theSource.isEmpty()) {
71  			List<BaseRuntimeChildDefinition> targetChildren = theTargetDef.getChildren();
72  			for (BaseRuntimeChildDefinition nextChild : targetChildren) {
73  
74  				String elementName = nextChild.getElementName();
75  				if (nextChild.getValidChildNames().size() > 1) {
76  					elementName = nextChild.getValidChildNames().iterator().next();
77  				}
78  				
79  				BaseRuntimeChildDefinition sourceChildEquivalent = theSourceDef.getChildByNameOrThrowDataFormatException(elementName);
80  				if (sourceChildEquivalent == null) {
81  					continue;
82  				}
83  
84  				List<? extends IElement> sourceValues = sourceChildEquivalent.getAccessor().getValues(theSource);
85  				for (IElement nextElement : sourceValues) {
86  					nextChild.getMutator().addValue(theTarget, nextElement);
87  				}
88  			}
89  			
90  			List<RuntimeChildDeclaredExtensionDefinition> targetExts = theTargetDef.getExtensions();
91  			for (RuntimeChildDeclaredExtensionDefinition nextExt : targetExts) {
92  				String url = nextExt.getExtensionUrl();
93  				
94  				RuntimeChildDeclaredExtensionDefinition sourceDeclaredExt = theSourceDef.getDeclaredExtension(url);
95  				if (sourceDeclaredExt == null) {
96  					
97  					for (ExtensionDt next : theSource.getAllUndeclaredExtensions()) {
98  						if (next.getUrlAsString().equals(url)) {
99  							nextExt.getMutator().addValue(theTarget, next.getValue());
100 						}
101 					}
102 					
103 				} else {
104 					
105 					List<? extends IElement> values = sourceDeclaredExt.getAccessor().getValues(theSource);
106 					for (IElement nextElement : values) {
107 						nextExt.getMutator().addValue(theTarget, nextElement);
108 					}
109 					
110 				}
111 				
112 			}
113 			
114 			
115 		}
116 	}
117 }