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