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