
001package ca.uhn.fhir.model.dstu2.composite; 002 003/* 004 * #%L 005 * HAPI FHIR Structures - DSTU2 (FHIR v1.0.0) 006 * %% 007 * Copyright (C) 2014 - 2023 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 static org.apache.commons.lang3.StringUtils.defaultString; 024 025import java.util.Collection; 026import java.util.HashSet; 027import java.util.Set; 028 029import org.apache.commons.lang3.Validate; 030 031import ca.uhn.fhir.model.api.IBoundCodeableConcept; 032import ca.uhn.fhir.model.api.IValueSetEnumBinder; 033import ca.uhn.fhir.model.api.annotation.DatatypeDef; 034 035@DatatypeDef(name = "CodeableConcept", isSpecialization = true) 036public class BoundCodeableConceptDt<T extends Enum<?>> extends CodeableConceptDt implements IBoundCodeableConcept { 037 038 private IValueSetEnumBinder<T> myBinder; 039 040 /** 041 * @deprecated This constructor is provided only for serialization support. Do not call it directly! 042 */ 043 @Deprecated 044 public BoundCodeableConceptDt() { 045 // nothing 046 } 047 048 /** 049 * Constructor 050 */ 051 public BoundCodeableConceptDt(IValueSetEnumBinder<T> theBinder) { 052 Validate.notNull(theBinder, "theBinder must not be null"); 053 myBinder = theBinder; 054 } 055 056 /** 057 * Constructor 058 */ 059 public BoundCodeableConceptDt(IValueSetEnumBinder<T> theBinder, T theValue) { 060 Validate.notNull(theBinder, "theBinder must not be null"); 061 myBinder = theBinder; 062 setValueAsEnum(theValue); 063 } 064 065 /** 066 * Constructor 067 */ 068 public BoundCodeableConceptDt(IValueSetEnumBinder<T> theBinder, Collection<T> theValues) { 069 Validate.notNull(theBinder, "theBinder must not be null"); 070 myBinder = theBinder; 071 setValueAsEnum(theValues); 072 } 073 074 /** 075 * Sets the {@link #getCoding()} to contain a coding with the code and 076 * system defined by the given enumerated types, AND clearing any existing 077 * codings first. If theValue is null, existing codings are cleared and no 078 * codings are added. 079 * 080 * @param theValues 081 * The value to add, or <code>null</code> 082 */ 083 public void setValueAsEnum(Collection<T> theValues) { 084 Validate.notNull(myBinder, "This object does not have a binder. Constructor BoundCodeableConceptDt() should not be called!"); 085 getCoding().clear(); 086 if (theValues != null) { 087 for (T next : theValues) { 088 getCoding().add(new CodingDt(myBinder.toSystemString(next), myBinder.toCodeString(next))); 089 } 090 } 091 } 092 093 /** 094 * Sets the {@link #getCoding()} to contain a coding with the code and 095 * system defined by the given enumerated type, AND clearing any existing 096 * codings first. If theValue is null, existing codings are cleared and no 097 * codings are added. 098 * 099 * @param theValue 100 * The value to add, or <code>null</code> 101 */ 102 public void setValueAsEnum(T theValue) { 103 Validate.notNull(myBinder, "This object does not have a binder. Constructor BoundCodeableConceptDt() should not be called!"); 104 getCoding().clear(); 105 if (theValue == null) { 106 return; 107 } 108 getCoding().add(new CodingDt(myBinder.toSystemString(theValue), myBinder.toCodeString(theValue))); 109 } 110 111 /** 112 * Loops through the {@link #getCoding() codings} in this codeable concept 113 * and returns the first bound enumerated type that matches. <b>Use 114 * caution</b> using this method, see the return description for more 115 * information. 116 * 117 * @return Returns the bound enumerated type, or <code>null</code> if none 118 * are found. Note that a null return value doesn't neccesarily 119 * imply that this Codeable Concept has no codes, only that it has 120 * no codes that match the enum. 121 */ 122 public Set<T> getValueAsEnum() { 123 Validate.notNull(myBinder, "This object does not have a binder. Constructor BoundCodeableConceptDt() should not be called!"); 124 Set<T> retVal = new HashSet<T>(); 125 for (CodingDt next : getCoding()) { 126 if (next == null) { 127 continue; 128 } 129 T nextT = myBinder.fromCodeString(defaultString(next.getCodeElement().getValue()), defaultString(next.getSystemElement().getValueAsString())); 130 if (nextT != null) { 131 retVal.add(nextT); 132 } else { 133 // TODO: throw special exception type? 134 } 135 } 136 return retVal; 137 } 138 139}