
001/* 002 * #%L 003 * HAPI FHIR - Core Library 004 * %% 005 * Copyright (C) 2014 - 2023 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 java.lang.reflect.Field; 023import java.util.ArrayList; 024import java.util.Collections; 025import java.util.Comparator; 026import java.util.List; 027import java.util.Map; 028 029import org.hl7.fhir.instance.model.api.IBase; 030import org.hl7.fhir.instance.model.api.IBaseDatatype; 031import org.hl7.fhir.instance.model.api.IBaseReference; 032 033import ca.uhn.fhir.model.api.IDatatype; 034import ca.uhn.fhir.model.api.IResource; 035import ca.uhn.fhir.model.api.annotation.Child; 036import ca.uhn.fhir.model.api.annotation.Description; 037import ca.uhn.fhir.model.primitive.XhtmlDt; 038 039public class RuntimeChildAny extends RuntimeChildChoiceDefinition { 040 041 public RuntimeChildAny(Field theField, String theElementName, Child theChildAnnotation, Description theDescriptionAnnotation) { 042 super(theField, theElementName, theChildAnnotation, theDescriptionAnnotation); 043 } 044 045 @Override 046 void sealAndInitialize(FhirContext theContext, Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions) { 047 List<Class<? extends IBase>> choiceTypes = new ArrayList<Class<? extends IBase>>(); 048 049 for (Class<? extends IBase> next : theClassToElementDefinitions.keySet()) { 050 if (next.equals(XhtmlDt.class)) { 051 continue; 052 } 053 054 BaseRuntimeElementDefinition<?> nextDef = theClassToElementDefinitions.get(next); 055 if (nextDef instanceof IRuntimeDatatypeDefinition) { 056 if (((IRuntimeDatatypeDefinition) nextDef).isSpecialization()) { 057 /* 058 * Things like BoundCodeDt shoudn't be considered as valid options for an "any" choice, since 059 * we'll already have CodeDt as an option 060 */ 061 continue; 062 } 063 } 064 065 if (IResource.class.isAssignableFrom(next) || IDatatype.class.isAssignableFrom(next) || IBaseDatatype.class.isAssignableFrom(next) || IBaseReference.class.isAssignableFrom(next)) { 066 choiceTypes.add(next); 067 } 068 } 069 Collections.sort(choiceTypes,new Comparator<Class<?>>(){ 070 @Override 071 public int compare(Class<?> theO1, Class<?> theO2) { 072 boolean o1res = IResource.class.isAssignableFrom(theO1); 073 boolean o2res = IResource.class.isAssignableFrom(theO2); 074 if (o1res && o2res) { 075 return theO1.getSimpleName().compareTo(theO2.getSimpleName()); 076 } else if (o1res) { 077 return -1; 078 } else if (o1res == false && o2res == false) { 079 return 0; 080 }else { 081 return 1; 082 } 083 }}); 084 085 setChoiceTypes(choiceTypes); 086 087 super.sealAndInitialize(theContext, theClassToElementDefinitions); 088 } 089 090 091 092}