001package ca.uhn.fhir.model.view; 002 003/* 004 * #%L 005 * HAPI FHIR - Core Library 006 * %% 007 * Copyright (C) 2014 - 2016 University Health Network 008 * %% 009 * Licensed under the Apache License, Version 2.0 (the "License"); 010 * you may not use this file except in compliance with the License. 011 * You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, software 016 * distributed under the License is distributed on an "AS IS" BASIS, 017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 018 * See the License for the specific language governing permissions and 019 * limitations under the License. 020 * #L% 021 */ 022 023import java.util.List; 024 025import org.hl7.fhir.instance.model.api.IBase; 026 027import ca.uhn.fhir.context.BaseRuntimeChildDefinition; 028import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition; 029import ca.uhn.fhir.context.ConfigurationException; 030import ca.uhn.fhir.context.FhirContext; 031import ca.uhn.fhir.context.RuntimeChildDeclaredExtensionDefinition; 032import ca.uhn.fhir.context.RuntimeResourceDefinition; 033import ca.uhn.fhir.model.api.BaseElement; 034import ca.uhn.fhir.model.api.ExtensionDt; 035import ca.uhn.fhir.model.api.IResource; 036 037public class ViewGenerator { 038 039 private FhirContext myCtx; 040 041 public ViewGenerator(FhirContext theFhirContext) { 042 myCtx=theFhirContext; 043 } 044 045 public <T extends IResource> T newView(IResource theResource, Class<T> theTargetType) { 046 Class<? extends IResource> sourceType = theResource.getClass(); 047 RuntimeResourceDefinition sourceDef = myCtx.getResourceDefinition(theResource); 048 RuntimeResourceDefinition targetDef = myCtx.getResourceDefinition(theTargetType); 049 050 if (sourceType.equals(theTargetType)) { 051 @SuppressWarnings("unchecked") 052 T resource = (T) theResource; 053 return resource; 054 } 055 056 T retVal; 057 try { 058 retVal = theTargetType.newInstance(); 059 } catch (InstantiationException e) { 060 throw new ConfigurationException("Failed to instantiate " + theTargetType, e); 061 } catch (IllegalAccessException e) { 062 throw new ConfigurationException("Failed to instantiate " + theTargetType, e); 063 } 064 065 copyChildren(sourceDef, (BaseElement) theResource, targetDef, (BaseElement) retVal); 066 067 return retVal; 068 } 069 070 private void copyChildren(BaseRuntimeElementCompositeDefinition<?> theSourceDef, BaseElement theSource, BaseRuntimeElementCompositeDefinition<?> theTargetDef, BaseElement theTarget) { 071 if (!theSource.isEmpty()) { 072 List<BaseRuntimeChildDefinition> targetChildren = theTargetDef.getChildren(); 073 for (BaseRuntimeChildDefinition nextChild : targetChildren) { 074 075 String elementName = nextChild.getElementName(); 076 if (nextChild.getValidChildNames().size() > 1) { 077 elementName = nextChild.getValidChildNames().iterator().next(); 078 } 079 080 BaseRuntimeChildDefinition sourceChildEquivalent = theSourceDef.getChildByNameOrThrowDataFormatException(elementName); 081 if (sourceChildEquivalent == null) { 082 continue; 083 } 084 085 List<? extends IBase> sourceValues = sourceChildEquivalent.getAccessor().getValues(theSource); 086 for (IBase nextElement : sourceValues) { 087 nextChild.getMutator().addValue(theTarget, nextElement); 088 } 089 } 090 091 List<RuntimeChildDeclaredExtensionDefinition> targetExts = theTargetDef.getExtensions(); 092 for (RuntimeChildDeclaredExtensionDefinition nextExt : targetExts) { 093 String url = nextExt.getExtensionUrl(); 094 095 RuntimeChildDeclaredExtensionDefinition sourceDeclaredExt = theSourceDef.getDeclaredExtension(url); 096 if (sourceDeclaredExt == null) { 097 098 for (ExtensionDt next : theSource.getAllUndeclaredExtensions()) { 099 if (next.getUrlAsString().equals(url)) { 100 nextExt.getMutator().addValue(theTarget, next.getValue()); 101 } 102 } 103 104 } else { 105 106 List<? extends IBase> values = sourceDeclaredExt.getAccessor().getValues(theSource); 107 for (IBase nextElement : values) { 108 nextExt.getMutator().addValue(theTarget, nextElement); 109 } 110 111 } 112 113 } 114 115 116 } 117 } 118}