001package ca.uhn.fhir.util; 002 003/*- 004 * #%L 005 * HAPI FHIR - Core Library 006 * %% 007 * Copyright (C) 2014 - 2022 Smile CDR, Inc. 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 ca.uhn.fhir.context.BaseRuntimeChildDefinition; 024import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition; 025import ca.uhn.fhir.context.FhirContext; 026import ca.uhn.fhir.context.FhirVersionEnum; 027import ca.uhn.fhir.i18n.Msg; 028import org.hl7.fhir.instance.model.api.IBase; 029import org.hl7.fhir.instance.model.api.IBaseExtension; 030import org.hl7.fhir.instance.model.api.IBaseHasExtensions; 031import org.hl7.fhir.instance.model.api.IBaseMetaType; 032import org.hl7.fhir.instance.model.api.IBaseResource; 033import org.hl7.fhir.instance.model.api.IPrimitiveType; 034import org.slf4j.Logger; 035import org.slf4j.LoggerFactory; 036 037import java.util.List; 038 039 040public class MetaUtil { 041 private static final Logger ourLog = LoggerFactory.getLogger(MetaUtil.class); 042 043 private MetaUtil() { 044 // non-instantiable 045 } 046 047 public static String getSource(FhirContext theContext, IBaseMetaType theMeta) { 048 if (theContext.getVersion().getVersion().isEqualOrNewerThan(FhirVersionEnum.R4)) { 049 return getSourceR4Plus(theContext, theMeta); 050 } else if (theContext.getVersion().getVersion().equals(FhirVersionEnum.DSTU3)) { 051 return getSourceDstu3((IBaseHasExtensions) theMeta); 052 } else { 053 throw new UnsupportedOperationException(Msg.code(1782) + MetaUtil.class.getSimpleName() + ".getSource() not supported on FHIR Version " + theContext.getVersion().getVersion()); 054 } 055 } 056 057 private static String getSourceDstu3(IBaseHasExtensions theMeta) { 058 IBaseHasExtensions metaWithExtensions = theMeta; 059 List<? extends IBaseExtension<?, ?>> extensions = metaWithExtensions.getExtension(); 060 for (IBaseExtension extension : extensions) { 061 if (HapiExtensions.EXT_META_SOURCE.equals(extension.getUrl())) { 062 IPrimitiveType<String> value = (IPrimitiveType<String>) extension.getValue(); 063 return value.getValueAsString(); 064 } 065 } 066 return null; 067 } 068 069 private static String getSourceR4Plus(FhirContext theFhirContext, IBaseMetaType theMeta) { 070 BaseRuntimeElementCompositeDefinition<?> elementDef = (BaseRuntimeElementCompositeDefinition<?>) theFhirContext.getElementDefinition(theMeta.getClass()); 071 BaseRuntimeChildDefinition sourceChild = elementDef.getChildByName("source"); 072 if (sourceChild == null) { 073 return null; 074 } 075 List<IBase> sourceValues = sourceChild.getAccessor().getValues(theMeta); 076 String retVal = null; 077 if (sourceValues.size() > 0) { 078 retVal = ((IPrimitiveType<?>) sourceValues.get(0)).getValueAsString(); 079 } 080 return retVal; 081 } 082 083 /** 084 * Sets the value for <code>Resource.meta.source</code> for R4+ resources, and places the value in 085 * an extension on <code>Resource.meta</code> 086 * with the URL <code>http://hapifhir.io/fhir/StructureDefinition/resource-meta-source</code> for DSTU3. 087 * 088 * @param theContext The FhirContext object 089 * @param theResource The resource to modify 090 * @param theValue The source URI 091 * @see <a href="http://hl7.org/fhir/resource-definitions.html#Resource.meta">Meta.source</a> 092 */ 093 @SuppressWarnings("unchecked") 094 public static void setSource(FhirContext theContext, IBaseResource theResource, String theValue) { 095 if (theContext.getVersion().getVersion().isEqualOrNewerThan(FhirVersionEnum.R4)) { 096 MetaUtil.setSource(theContext, theResource.getMeta(), theValue); 097 } else if (theContext.getVersion().getVersion().equals(FhirVersionEnum.DSTU3)) { 098 IBaseExtension<?, ?> sourceExtension = ((IBaseHasExtensions) theResource.getMeta()).addExtension(); 099 sourceExtension.setUrl(HapiExtensions.EXT_META_SOURCE); 100 IPrimitiveType<String> value = (IPrimitiveType<String>) theContext.getElementDefinition("uri").newInstance(); 101 value.setValue(theValue); 102 sourceExtension.setValue(value); 103 } else { 104 ourLog.debug(MetaUtil.class.getSimpleName() + ".setSource() not supported on FHIR Version " + theContext.getVersion().getVersion()); 105 } 106 } 107 108 public static void setSource(FhirContext theContext, IBaseMetaType theMeta, String theValue) { 109 BaseRuntimeElementCompositeDefinition<?> elementDef = (BaseRuntimeElementCompositeDefinition<?>) theContext.getElementDefinition(theMeta.getClass()); 110 BaseRuntimeChildDefinition sourceChild = elementDef.getChildByName("source"); 111 List<IBase> sourceValues = sourceChild.getAccessor().getValues(theMeta); 112 IPrimitiveType<?> sourceElement; 113 if (sourceValues.size() > 0) { 114 sourceElement = ((IPrimitiveType<?>) sourceValues.get(0)); 115 } else { 116 sourceElement = (IPrimitiveType<?>) theContext.getElementDefinition("uri").newInstance(); 117 sourceChild.getMutator().setValue(theMeta, sourceElement); 118 } 119 sourceElement.setValueAsString(theValue); 120 } 121 122}