001package ca.uhn.fhir.rest.param; 002 003/* 004 * #%L 005 * HAPI FHIR - Core Library 006 * %% 007 * Copyright (C) 2014 - 2018 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 return ParameterUtil.escape(StringUtils.defaultString(getSystem())) + '|' + ParameterUtil.escape(getValue()); 104 } 105 return ParameterUtil.escape(getValue()); 106 } 107 108 /** 109 * {@inheritDoc} 110 */ 111 @Override 112 void doSetValueAsQueryToken(FhirContext theContext, String theParamName, String theQualifier, String theParameter) { 113 setModifier(null); 114 if (theQualifier != null) { 115 TokenParamModifier modifier = TokenParamModifier.forValue(theQualifier); 116 setModifier(modifier); 117 118 if (modifier == TokenParamModifier.TEXT) { 119 setSystem(null); 120 setValue(ParameterUtil.unescape(theParameter)); 121 return; 122 } 123 } 124 125 setSystem(null); 126 if (theParameter == null) { 127 setValue(null); 128 } else { 129 int barIndex = ParameterUtil.nonEscapedIndexOf(theParameter, '|'); 130 if (barIndex != -1) { 131 setSystem(theParameter.substring(0, barIndex)); 132 setValue(ParameterUtil.unescape(theParameter.substring(barIndex + 1))); 133 } else { 134 setValue(ParameterUtil.unescape(theParameter)); 135 } 136 } 137 } 138 139 /** 140 * Returns the modifier for this token 141 */ 142 public TokenParamModifier getModifier() { 143 return myModifier; 144 } 145 146 public TokenParam setModifier(TokenParamModifier theModifier) { 147 myModifier = theModifier; 148 return this; 149 } 150 151 /** 152 * Returns the system for this token. Note that if a {@link #getModifier()} is being used, the entire value of the 153 * parameter will be placed in {@link #getValue() value} and this method will return <code>null</code>. 154 * <p 155 * Also note that this value may be <code>null</code> or <code>""</code> (empty string) and that 156 * each of these have a different meaning. When a token is passed on a URL and it has no 157 * vertical bar (often meaning "return values that match the given code in any codesystem") 158 * this method will return <code>null</code>. When a token is passed on a URL and it has 159 * a vetical bar but nothing before the bar (often meaning "return values that match the 160 * given code but that have no codesystem) this method will return <code>""</code> 161 * </p> 162 */ 163 public String getSystem() { 164 return mySystem; 165 } 166 167 public TokenParam setSystem(String theSystem) { 168 mySystem = theSystem; 169 return this; 170 } 171 172 /** 173 * Returns the value for the token (generally the value to the right of the 174 * vertical bar on the URL) 175 */ 176 public String getValue() { 177 return myValue; 178 } 179 180 public TokenParam setValue(String theValue) { 181 myValue = theValue; 182 return this; 183 } 184 185 public InternalCodingDt getValueAsCoding() { 186 return new InternalCodingDt(mySystem, myValue); 187 } 188 189 public String getValueNotNull() { 190 return defaultString(myValue); 191 } 192 193 public boolean isEmpty() { 194 return StringUtils.isEmpty(myValue); 195 } 196 197 /** 198 * Returns true if {@link #getModifier()} returns {@link TokenParamModifier#TEXT} 199 */ 200 public boolean isText() { 201 return myModifier == TokenParamModifier.TEXT; 202 } 203 204 /** 205 * @deprecated Use {@link #setModifier(TokenParamModifier)} instead 206 */ 207 @Deprecated 208 public TokenParam setText(boolean theText) { 209 if (theText) { 210 myModifier = TokenParamModifier.TEXT; 211 } else { 212 myModifier = null; 213 } 214 return this; 215 } 216 217 @Override 218 public String toString() { 219 ToStringBuilder builder = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE); 220 builder.append("system", defaultString(getSystem())); 221 if (myModifier != null) { 222 builder.append(":" + myModifier.getValue()); 223 } 224 builder.append("value", getValue()); 225 if (getMissing() != null) { 226 builder.append(":missing", getMissing()); 227 } 228 return builder.toString(); 229 } 230 231 private static String toSystemValue(UriDt theSystem) { 232 return theSystem.getValueAsString(); 233 } 234 235}