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