
001/*- 002 * #%L 003 * HAPI FHIR - Core Library 004 * %% 005 * Copyright (C) 2014 - 2025 Smile CDR, Inc. 006 * %% 007 * Licensed under the Apache License, Version 2.0 (the "License"); 008 * you may not use this file except in compliance with the License. 009 * You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 * #L% 019 */ 020package ca.uhn.fhir.context; 021 022import ca.uhn.fhir.model.api.ISupportsUndeclaredExtensions; 023import com.google.common.collect.Sets; 024import org.apache.commons.lang3.Validate; 025import org.hl7.fhir.instance.model.api.IBase; 026import org.hl7.fhir.instance.model.api.IBaseExtension; 027import org.hl7.fhir.instance.model.api.IBaseHasExtensions; 028 029import java.util.Collections; 030import java.util.HashMap; 031import java.util.List; 032import java.util.Map; 033import java.util.Set; 034 035public class RuntimeChildExt extends BaseRuntimeChildDefinition { 036 037 private Map<String, BaseRuntimeElementDefinition<?>> myNameToChild; 038 private Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> myDatatypeToChild; 039 private Map<Class<? extends IBase>, String> myDatatypeToChildName; 040 041 @Override 042 public IAccessor getAccessor() { 043 return new IAccessor() { 044 @SuppressWarnings({"unchecked", "rawtypes"}) 045 @Override 046 public List<IBase> getValues(IBase theTarget) { 047 if (theTarget instanceof IBaseHasExtensions hasExtensions) { 048 List extension = hasExtensions.getExtension(); 049 return Collections.unmodifiableList(extension); 050 } else { 051 // DSTU2 only 052 List extension = ((ISupportsUndeclaredExtensions) theTarget).getAllUndeclaredExtensions(); 053 return Collections.unmodifiableList(extension); 054 } 055 } 056 }; 057 } 058 059 @Override 060 public BaseRuntimeElementDefinition<?> getChildByName(String theName) { 061 return myNameToChild.get(theName); 062 } 063 064 @Override 065 public BaseRuntimeElementDefinition<?> getChildElementDefinitionByDatatype(Class<? extends IBase> theType) { 066 return myDatatypeToChild.get(theType); 067 } 068 069 @Override 070 public String getChildNameByDatatype(Class<? extends IBase> theDatatype) { 071 return myDatatypeToChildName.get(theDatatype); 072 } 073 074 @Override 075 public String getElementName() { 076 return "extension"; 077 } 078 079 @Override 080 public int getMax() { 081 return -1; 082 } 083 084 @Override 085 public int getMin() { 086 return 0; 087 } 088 089 @Override 090 public IMutator getMutator() { 091 return new IMutator() { 092 @Override 093 public void addValue(IBase theTarget, IBase theValue) { 094 List extensions = ((IBaseHasExtensions) theTarget).getExtension(); 095 IBaseExtension<?, ?> value = (IBaseExtension<?, ?>) theValue; 096 extensions.add(value); 097 } 098 099 @Override 100 public void setValue(IBase theTarget, IBase theValue) { 101 List extensions = ((IBaseHasExtensions) theTarget).getExtension(); 102 extensions.clear(); 103 if (theValue != null) { 104 IBaseExtension<?, ?> value = (IBaseExtension<?, ?>) theValue; 105 extensions.add(value); 106 } 107 } 108 }; 109 } 110 111 @Override 112 public Set<String> getValidChildNames() { 113 return Sets.newHashSet("extension"); 114 } 115 116 @Override 117 public boolean isSummary() { 118 return false; 119 } 120 121 @Override 122 void sealAndInitialize( 123 FhirContext theContext, 124 Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions) { 125 myNameToChild = new HashMap<>(); 126 myDatatypeToChild = new HashMap<>(); 127 myDatatypeToChildName = new HashMap<>(); 128 129 for (BaseRuntimeElementDefinition<?> next : theClassToElementDefinitions.values()) { 130 if (next.getName().equals("Extension")) { 131 myNameToChild.put("extension", next); 132 myDatatypeToChild.put(next.getImplementingClass(), next); 133 myDatatypeToChildName.put(next.getImplementingClass(), "extension"); 134 } 135 } 136 137 Validate.isTrue(!myNameToChild.isEmpty()); 138 } 139}