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 - 2016 University Health Network 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; 034import ca.uhn.fhir.model.dstu2.composite.CodeableConceptDt; 035import ca.uhn.fhir.model.dstu2.composite.CodingDt; 036 037@DatatypeDef(name = "CodeableConcept", isSpecialization = true) 038public class BoundCodeableConceptDt<T extends Enum<?>> extends CodeableConceptDt implements IBoundCodeableConcept { 039 040 private IValueSetEnumBinder<T> myBinder; 041 042 /** 043 * @deprecated This constructor is provided only for serialization support. Do not call it directly! 044 */ 045 @Deprecated 046 public BoundCodeableConceptDt() { 047 // nothing 048 } 049 050 /** 051 * Constructor 052 */ 053 public BoundCodeableConceptDt(IValueSetEnumBinder<T> theBinder) { 054 Validate.notNull(theBinder, "theBinder must not be null"); 055 myBinder = theBinder; 056 } 057 058 /** 059 * Constructor 060 */ 061 public BoundCodeableConceptDt(IValueSetEnumBinder<T> theBinder, T theValue) { 062 Validate.notNull(theBinder, "theBinder must not be null"); 063 myBinder = theBinder; 064 setValueAsEnum(theValue); 065 } 066 067 /** 068 * Constructor 069 */ 070 public BoundCodeableConceptDt(IValueSetEnumBinder<T> theBinder, Collection<T> theValues) { 071 Validate.notNull(theBinder, "theBinder must not be null"); 072 myBinder = theBinder; 073 setValueAsEnum(theValues); 074 } 075 076 /** 077 * Sets the {@link #getCoding()} to contain a coding with the code and 078 * system defined by the given enumerated types, AND clearing any existing 079 * codings first. If theValue is null, existing codings are cleared and no 080 * codings are added. 081 * 082 * @param theValues 083 * The value to add, or <code>null</code> 084 */ 085 public void setValueAsEnum(Collection<T> theValues) { 086 Validate.notNull(myBinder, "This object does not have a binder. Constructor BoundCodeableConceptDt() should not be called!"); 087 getCoding().clear(); 088 if (theValues != null) { 089 for (T next : theValues) { 090 getCoding().add(new CodingDt(myBinder.toSystemString(next), myBinder.toCodeString(next))); 091 } 092 } 093 } 094 095 /** 096 * Sets the {@link #getCoding()} to contain a coding with the code and 097 * system defined by the given enumerated type, AND clearing any existing 098 * codings first. If theValue is null, existing codings are cleared and no 099 * codings are added. 100 * 101 * @param theValue 102 * The value to add, or <code>null</code> 103 */ 104 public void setValueAsEnum(T theValue) { 105 Validate.notNull(myBinder, "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(myBinder, "This object does not have a binder. Constructor BoundCodeableConceptDt() should not be called!"); 126 Set<T> retVal = new HashSet<T>(); 127 for (CodingDt next : getCoding()) { 128 if (next == null) { 129 continue; 130 } 131 T nextT = myBinder.fromCodeString(defaultString(next.getCodeElement().getValue()), defaultString(next.getSystemElement().getValueAsString())); 132 if (nextT != null) { 133 retVal.add(nextT); 134 } else { 135 // TODO: throw special exception type? 136 } 137 } 138 return retVal; 139 } 140 141}