001/* 002 * #%L 003 * HAPI FHIR - Core Library 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.base.composite; 021 022import ca.uhn.fhir.context.FhirContext; 023import ca.uhn.fhir.i18n.Msg; 024import ca.uhn.fhir.model.api.BaseIdentifiableElement; 025import ca.uhn.fhir.model.api.ICompositeDatatype; 026import ca.uhn.fhir.model.api.IQueryParameterType; 027import ca.uhn.fhir.model.primitive.BooleanDt; 028import ca.uhn.fhir.model.primitive.CodeDt; 029import ca.uhn.fhir.model.primitive.StringDt; 030import ca.uhn.fhir.model.primitive.UriDt; 031import ca.uhn.fhir.rest.param.ParameterUtil; 032import ca.uhn.fhir.rest.param.TokenParam; 033import org.apache.commons.lang3.StringUtils; 034 035public abstract class BaseCodingDt extends BaseIdentifiableElement implements ICompositeDatatype, IQueryParameterType { 036 037 private static final long serialVersionUID = 4425182816398730643L; 038 039 /** 040 * Gets the value(s) for <b>code</b> (Symbol in syntax defined by the system). creating it if it does not exist. Will not return <code>null</code>. 041 * 042 * <p> 043 * <b>Definition:</b> A symbol in syntax defined by the system. The symbol may be a predefined code or an expression in a syntax defined by the coding system (e.g. post-coordination) 044 * </p> 045 */ 046 public abstract CodeDt getCodeElement(); 047 048 @Override 049 public String getQueryParameterQualifier() { 050 return null; 051 } 052 053 /** 054 * Gets the value(s) for <b>system</b> (Identity of the terminology system). creating it if it does not exist. Will not return <code>null</code>. 055 * 056 * <p> 057 * <b>Definition:</b> The identification of the code system that defines the meaning of the symbol in the code. 058 * </p> 059 */ 060 public abstract UriDt getSystemElement(); 061 062 public abstract StringDt getVersionElement(); 063 064 public abstract BooleanDt getUserSelectedElement(); 065 066 /** 067 * Gets the value(s) for <b>display</b> (Representation defined by the system). 068 * creating it if it does 069 * not exist. Will not return <code>null</code>. 070 * 071 * <p> 072 * <b>Definition:</b> 073 * A representation of the meaning of the code in the system, following the rules of the system. 074 * </p> 075 */ 076 public abstract StringDt getDisplayElement(); 077 078 public abstract BaseCodingDt setDisplay(String theString); 079 080 /** 081 * {@inheritDoc} 082 */ 083 @Override 084 public String getValueAsQueryToken(FhirContext theContext) { 085 if (getSystemElement().getValueAsString() != null) { 086 return ParameterUtil.escape( 087 StringUtils.defaultString(getSystemElement().getValueAsString())) 088 + '|' 089 + ParameterUtil.escape(getCodeElement().getValueAsString()); 090 } 091 return ParameterUtil.escape(getCodeElement().getValueAsString()); 092 } 093 094 /** 095 * {@inheritDoc} 096 */ 097 @Override 098 public void setValueAsQueryToken( 099 FhirContext theContext, String theParamName, String theQualifier, String theParameter) { 100 int barIndex = ParameterUtil.nonEscapedIndexOf(theParameter, '|'); 101 if (barIndex != -1) { 102 setSystem(theParameter.substring(0, barIndex)); 103 setCode(ParameterUtil.unescape(theParameter.substring(barIndex + 1))); 104 } else { 105 setCode(ParameterUtil.unescape(theParameter)); 106 } 107 } 108 109 /** 110 * Returns true if <code>this</code> Coding has the same {@link #getCodeElement() Code} and {@link #getSystemElement() system} (as compared by simple equals comparison). Does not compare other 111 * Codes (e.g. getUseElement()) or any extensions. 112 */ 113 public boolean matchesSystemAndCode(BaseCodingDt theCoding) { 114 if (theCoding == null) { 115 return false; 116 } 117 return getCodeElement().equals(theCoding.getCodeElement()) 118 && getSystemElement().equals(theCoding.getSystemElement()); 119 } 120 121 /** 122 * returns true if <code>this</code> Coding matches a search for the coding specified by <code>theSearchParam</code>, according 123 * to the following: 124 * <ul> 125 * <li>[parameter]=[namespace]|[code] matches a code/value in the given system namespace</li> 126 * <li>[parameter]=[code] matches a code/value irrespective of it's system namespace</li> 127 * <li>[parameter]=|[code] matches a code/value that has no system namespace</li> 128 * </ul> 129 * @param theSearchParam - coding to test <code>this</code> against 130 * @return true if the coding matches, false otherwise 131 */ 132 public boolean matchesToken(BaseCodingDt theSearchParam) { 133 if (theSearchParam.isSystemPresent()) { 134 if (theSearchParam.isSystemBlank()) { 135 // [parameter]=|[code] matches a code/value that has no system namespace 136 if (isSystemPresent() && !isSystemBlank()) return false; 137 } else { 138 // [parameter]=[namespace]|[code] matches a code/value in the given system namespace 139 if (!isSystemPresent()) return false; 140 if (!getSystemElement().equals(theSearchParam.getSystemElement())) return false; 141 } 142 } else { 143 // [parameter]=[code] matches a code/value irrespective of it's system namespace 144 // (nothing to do for system for this case) 145 } 146 147 return getCodeElement().equals(theSearchParam.getCodeElement()); 148 } 149 150 private boolean isSystemPresent() { 151 return !getSystemElement().isEmpty(); 152 } 153 154 private boolean isSystemBlank() { 155 return isSystemPresent() && getSystemElement().getValueAsString().equals(""); 156 } 157 158 /** 159 * Sets the value for <b>code</b> (Symbol in syntax defined by the system) 160 * 161 * <p> 162 * <b>Definition:</b> A symbol in syntax defined by the system. The symbol may be a predefined code or an expression in a syntax defined by the coding system (e.g. post-coordination) 163 * </p> 164 */ 165 public abstract BaseCodingDt setCode(String theCode); 166 167 /** 168 * Sets the value for <b>system</b> (Identity of the terminology system) 169 * 170 * <p> 171 * <b>Definition:</b> The identification of the code system that defines the meaning of the symbol in the code. 172 * </p> 173 */ 174 public abstract BaseCodingDt setSystem(String theUri); 175 176 /** 177 * <b>Not supported!</b> 178 * 179 * @deprecated get/setMissing is not supported in StringDt. Use {@link TokenParam} instead if you 180 * need this functionality 181 */ 182 @Deprecated(since = "6.0.0") 183 @Override 184 public Boolean getMissing() { 185 return null; 186 } 187 188 /** 189 * <b>Not supported!</b> 190 * 191 * @deprecated get/setMissing is not supported in StringDt. Use {@link TokenParam} instead if you 192 * need this functionality 193 */ 194 @Deprecated(since = "6.0.0") 195 @Override 196 public IQueryParameterType setMissing(Boolean theMissing) { 197 throw new UnsupportedOperationException( 198 Msg.code(1903) 199 + "get/setMissing is not supported in StringDt. Use {@link StringParam} instead if you need this functionality"); 200 } 201}