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