
001/* 002 * #%L 003 * HAPI FHIR - Core Library 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.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.CodeDt; 028import ca.uhn.fhir.model.primitive.StringDt; 029import ca.uhn.fhir.model.primitive.UriDt; 030import ca.uhn.fhir.rest.param.ParameterUtil; 031import ca.uhn.fhir.rest.param.TokenParam; 032import org.apache.commons.lang3.StringUtils; 033 034public abstract class BaseCodingDt extends BaseIdentifiableElement implements ICompositeDatatype, IQueryParameterType { 035 036 private static final long serialVersionUID = 4425182816398730643L; 037 038 /** 039 * 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>. 040 * 041 * <p> 042 * <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) 043 * </p> 044 */ 045 public abstract CodeDt getCodeElement(); 046 047 @Override 048 public String getQueryParameterQualifier() { 049 return null; 050 } 051 052 /** 053 * 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>. 054 * 055 * <p> 056 * <b>Definition:</b> The identification of the code system that defines the meaning of the symbol in the code. 057 * </p> 058 */ 059 public abstract UriDt getSystemElement(); 060 061 /** 062 * Gets the value(s) for <b>display</b> (Representation defined by the system). 063 * creating it if it does 064 * not exist. Will not return <code>null</code>. 065 * 066 * <p> 067 * <b>Definition:</b> 068 * A representation of the meaning of the code in the system, following the rules of the system. 069 * </p> 070 */ 071 public abstract StringDt getDisplayElement(); 072 073 public abstract BaseCodingDt setDisplay( String theString); 074 075 /* 076 todo: handle version 077 public abstract StringDt getVersion(); 078 079 public abstract BaseCodingDt setVersion ( String theString); 080 */ 081 082 /** 083 * {@inheritDoc} 084 */ 085 @Override 086 public String getValueAsQueryToken(FhirContext theContext) { 087 if (getSystemElement().getValueAsString() != null) { 088 return ParameterUtil.escape(StringUtils.defaultString(getSystemElement().getValueAsString())) + '|' + ParameterUtil.escape(getCodeElement().getValueAsString()); 089 } 090 return ParameterUtil.escape(getCodeElement().getValueAsString()); 091 } 092 093 /** 094 * {@inheritDoc} 095 */ 096 @Override 097 public void setValueAsQueryToken(FhirContext theContext, String theParamName, String theQualifier, String theParameter) { 098 int barIndex = ParameterUtil.nonEscapedIndexOf(theParameter, '|'); 099 if (barIndex != -1) { 100 setSystem(theParameter.substring(0, barIndex)); 101 setCode(ParameterUtil.unescape(theParameter.substring(barIndex + 1))); 102 } else { 103 setCode(ParameterUtil.unescape(theParameter)); 104 } 105 } 106 107 /** 108 * 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 109 * Codes (e.g. getUseElement()) or any extensions. 110 */ 111 public boolean matchesSystemAndCode(BaseCodingDt theCoding) { 112 if (theCoding == null) { 113 return false; 114 } 115 return getCodeElement().equals(theCoding.getCodeElement()) && getSystemElement().equals(theCoding.getSystemElement()); 116 } 117 118 /** 119 * returns true if <code>this</code> Coding matches a search for the coding specified by <code>theSearchParam</code>, according 120 * to the following: 121 * <ul> 122 * <li>[parameter]=[namespace]|[code] matches a code/value in the given system namespace</li> 123 * <li>[parameter]=[code] matches a code/value irrespective of it's system namespace</li> 124 * <li>[parameter]=|[code] matches a code/value that has no system namespace</li> 125 * </ul> 126 * @param theSearchParam - coding to test <code>this</code> against 127 * @return true if the coding matches, false otherwise 128 */ 129 public boolean matchesToken(BaseCodingDt theSearchParam) { 130 if (theSearchParam.isSystemPresent()) { 131 if (theSearchParam.isSystemBlank()) { 132 // [parameter]=|[code] matches a code/value that has no system namespace 133 if (isSystemPresent() && !isSystemBlank()) 134 return false; 135 } else { 136 // [parameter]=[namespace]|[code] matches a code/value in the given system namespace 137 if (!isSystemPresent()) 138 return false; 139 if (!getSystemElement().equals(theSearchParam.getSystemElement())) 140 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 /** 178 * <b>Not supported!</b> 179 * 180 * @deprecated get/setMissing is not supported in StringDt. Use {@link TokenParam} instead if you 181 * need this functionality 182 */ 183 @Deprecated 184 @Override 185 public Boolean getMissing() { 186 return null; 187 } 188 189 /** 190 * <b>Not supported!</b> 191 * 192 * @deprecated get/setMissing is not supported in StringDt. Use {@link TokenParam} instead if you 193 * need this functionality 194 */ 195 @Deprecated 196 @Override 197 public IQueryParameterType setMissing(Boolean theMissing) { 198 throw new UnsupportedOperationException(Msg.code(1903) + "get/setMissing is not supported in StringDt. Use {@link StringParam} instead if you need this functionality"); 199 } 200 201}