001package ca.uhn.fhir.rest.param; 002 003/* 004 * #%L 005 * HAPI FHIR - Core Library 006 * %% 007 * Copyright (C) 2014 - 2019 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 ca.uhn.fhir.context.FhirContext; 024import ca.uhn.fhir.model.base.composite.BaseCodingDt; 025import ca.uhn.fhir.model.base.composite.BaseIdentifierDt; 026import ca.uhn.fhir.model.primitive.UriDt; 027import org.apache.commons.lang3.StringUtils; 028import org.apache.commons.lang3.builder.ToStringBuilder; 029import org.apache.commons.lang3.builder.ToStringStyle; 030 031import static org.apache.commons.lang3.StringUtils.defaultString; 032import static org.apache.commons.lang3.StringUtils.isNotBlank; 033 034public class TokenParam extends BaseParam /*implements IQueryParameterType*/ { 035 036 private TokenParamModifier myModifier; 037 private String mySystem; 038 private String myValue; 039 040 /** 041 * Constructor 042 */ 043 public TokenParam() { 044 super(); 045 } 046 047 /** 048 * Constructor which copies the {@link InternalCodingDt#getSystemElement() system} and 049 * {@link InternalCodingDt#getCodeElement() code} from a {@link InternalCodingDt} instance and adds it as a parameter 050 * 051 * @param theCodingDt The coding 052 */ 053 public TokenParam(BaseCodingDt theCodingDt) { 054 this(toSystemValue(theCodingDt.getSystemElement()), theCodingDt.getCodeElement().getValue()); 055 } 056 057 /** 058 * Constructor which copies the {@link BaseIdentifierDt#getSystemElement() system} and 059 * {@link BaseIdentifierDt#getValueElement() value} from a {@link BaseIdentifierDt} instance and adds it as a 060 * parameter 061 * 062 * @param theIdentifierDt The identifier 063 */ 064 public TokenParam(BaseIdentifierDt theIdentifierDt) { 065 this(toSystemValue(theIdentifierDt.getSystemElement()), theIdentifierDt.getValueElement().getValue()); 066 } 067 068 public TokenParam(String theSystem, String theValue) { 069 setSystem(theSystem); 070 setValue(theValue); 071 } 072 073 public TokenParam(String theSystem, String theValue, boolean theText) { 074 if (theText && isNotBlank(theSystem)) { 075 throw new IllegalArgumentException("theSystem can not be non-blank if theText is true (:text searches do not include a system). In other words, set the first parameter to null for a text search"); 076 } 077 setSystem(theSystem); 078 setValue(theValue); 079 setText(theText); 080 } 081 082 /** 083 * Constructor that takes a code but no system 084 */ 085 public TokenParam(String theCode) { 086 this(null, theCode); 087 } 088 089 @Override 090 String doGetQueryParameterQualifier() { 091 if (getModifier() != null) { 092 return getModifier().getValue(); 093 } 094 return null; 095 } 096 097 /** 098 * {@inheritDoc} 099 */ 100 @Override 101 String doGetValueAsQueryToken(FhirContext theContext) { 102 if (getSystem() != null) { 103 if (getValue() != null) { 104 return ParameterUtil.escape(StringUtils.defaultString(getSystem())) + '|' + ParameterUtil.escape(getValue()); 105 } else { 106 return ParameterUtil.escape(StringUtils.defaultString(getSystem())) + '|'; 107 } 108 } 109 return ParameterUtil.escape(getValue()); 110 } 111 112 /** 113 * {@inheritDoc} 114 */ 115 @Override 116 void doSetValueAsQueryToken(FhirContext theContext, String theParamName, String theQualifier, String theParameter) { 117 setModifier(null); 118 if (theQualifier != null) { 119 TokenParamModifier modifier = TokenParamModifier.forValue(theQualifier); 120 setModifier(modifier); 121 122 if (modifier == TokenParamModifier.TEXT) { 123 setSystem(null); 124 setValue(ParameterUtil.unescape(theParameter)); 125 return; 126 } 127 } 128 129 setSystem(null); 130 if (theParameter == null) { 131 setValue(null); 132 } else { 133 int barIndex = ParameterUtil.nonEscapedIndexOf(theParameter, '|'); 134 if (barIndex != -1) { 135 setSystem(theParameter.substring(0, barIndex)); 136 setValue(ParameterUtil.unescape(theParameter.substring(barIndex + 1))); 137 } else { 138 setValue(ParameterUtil.unescape(theParameter)); 139 } 140 } 141 } 142 143 /** 144 * Returns the modifier for this token 145 */ 146 public TokenParamModifier getModifier() { 147 return myModifier; 148 } 149 150 public TokenParam setModifier(TokenParamModifier theModifier) { 151 myModifier = theModifier; 152 return this; 153 } 154 155 /** 156 * Returns the system for this token. Note that if a {@link #getModifier()} is being used, the entire value of the 157 * parameter will be placed in {@link #getValue() value} and this method will return <code>null</code>. 158 * <p 159 * Also note that this value may be <code>null</code> or <code>""</code> (empty string) and that 160 * each of these have a different meaning. When a token is passed on a URL and it has no 161 * vertical bar (often meaning "return values that match the given code in any codesystem") 162 * this method will return <code>null</code>. When a token is passed on a URL and it has 163 * a vetical bar but nothing before the bar (often meaning "return values that match the 164 * given code but that have no codesystem) this method will return <code>""</code> 165 * </p> 166 */ 167 public String getSystem() { 168 return mySystem; 169 } 170 171 public TokenParam setSystem(String theSystem) { 172 mySystem = theSystem; 173 return this; 174 } 175 176 /** 177 * Returns the value for the token (generally the value to the right of the 178 * vertical bar on the URL) 179 */ 180 public String getValue() { 181 return myValue; 182 } 183 184 public TokenParam setValue(String theValue) { 185 myValue = theValue; 186 return this; 187 } 188 189 public InternalCodingDt getValueAsCoding() { 190 return new InternalCodingDt(mySystem, myValue); 191 } 192 193 public String getValueNotNull() { 194 return defaultString(myValue); 195 } 196 197 public boolean isEmpty() { 198 return StringUtils.isEmpty(myValue); 199 } 200 201 /** 202 * Returns true if {@link #getModifier()} returns {@link TokenParamModifier#TEXT} 203 */ 204 public boolean isText() { 205 return myModifier == TokenParamModifier.TEXT; 206 } 207 208 /** 209 * @deprecated Use {@link #setModifier(TokenParamModifier)} instead 210 */ 211 @Deprecated 212 public TokenParam setText(boolean theText) { 213 if (theText) { 214 myModifier = TokenParamModifier.TEXT; 215 } else { 216 myModifier = null; 217 } 218 return this; 219 } 220 221 @Override 222 public String toString() { 223 ToStringBuilder builder = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE); 224 builder.append("system", defaultString(getSystem())); 225 if (myModifier != null) { 226 builder.append(":" + myModifier.getValue()); 227 } 228 builder.append("value", getValue()); 229 if (getMissing() != null) { 230 builder.append(":missing", getMissing()); 231 } 232 return builder.toString(); 233 } 234 235 private static String toSystemValue(UriDt theSystem) { 236 return theSystem.getValueAsString(); 237 } 238 239}