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