View Javadoc
1   package ca.uhn.fhir.rest.param;
2   
3   /*
4    * #%L
5    * HAPI FHIR - Core Library
6    * %%
7    * Copyright (C) 2014 - 2019 University Health Network
8    * %%
9    * Licensed under the Apache License, Version 2.0 (the "License");
10   * you may not use this file except in compliance with the License.
11   * You may obtain a copy of the License at
12   * 
13   *      http://www.apache.org/licenses/LICENSE-2.0
14   * 
15   * Unless required by applicable law or agreed to in writing, software
16   * distributed under the License is distributed on an "AS IS" BASIS,
17   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18   * See the License for the specific language governing permissions and
19   * limitations under the License.
20   * #L%
21   */
22  
23  import ca.uhn.fhir.context.FhirContext;
24  import ca.uhn.fhir.model.base.composite.BaseCodingDt;
25  import ca.uhn.fhir.model.base.composite.BaseIdentifierDt;
26  import ca.uhn.fhir.model.primitive.UriDt;
27  import org.apache.commons.lang3.StringUtils;
28  import org.apache.commons.lang3.builder.ToStringBuilder;
29  import org.apache.commons.lang3.builder.ToStringStyle;
30  
31  import static org.apache.commons.lang3.StringUtils.defaultString;
32  import static org.apache.commons.lang3.StringUtils.isNotBlank;
33  
34  public class TokenParam extends BaseParam /*implements IQueryParameterType*/ {
35  
36  	private TokenParamModifier myModifier;
37  	private String mySystem;
38  	private String myValue;
39  
40  	/**
41  	 * Constructor
42  	 */
43  	public TokenParam() {
44  		super();
45  	}
46  
47  	/**
48  	 * Constructor which copies the {@link InternalCodingDt#getSystemElement() system} and
49  	 * {@link InternalCodingDt#getCodeElement() code} from a {@link InternalCodingDt} instance and adds it as a parameter
50  	 *
51  	 * @param theCodingDt The coding
52  	 */
53  	public TokenParam(BaseCodingDt theCodingDt) {
54  		this(toSystemValue(theCodingDt.getSystemElement()), theCodingDt.getCodeElement().getValue());
55  	}
56  
57  	/**
58  	 * Constructor which copies the {@link BaseIdentifierDt#getSystemElement() system} and
59  	 * {@link BaseIdentifierDt#getValueElement() value} from a {@link BaseIdentifierDt} instance and adds it as a
60  	 * parameter
61  	 *
62  	 * @param theIdentifierDt The identifier
63  	 */
64  	public TokenParam(BaseIdentifierDt theIdentifierDt) {
65  		this(toSystemValue(theIdentifierDt.getSystemElement()), theIdentifierDt.getValueElement().getValue());
66  	}
67  
68  	public TokenParam(String theSystem, String theValue) {
69  		setSystem(theSystem);
70  		setValue(theValue);
71  	}
72  
73  	public TokenParam(String theSystem, String theValue, boolean theText) {
74  		if (theText && isNotBlank(theSystem)) {
75  			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");
76  		}
77  		setSystem(theSystem);
78  		setValue(theValue);
79  		setText(theText);
80  	}
81  
82  	/**
83  	 * Constructor that takes a code but no system
84  	 */
85  	public TokenParam(String theCode) {
86  		this(null, theCode);
87  	}
88  
89  	@Override
90  	String doGetQueryParameterQualifier() {
91  		if (getModifier() != null) {
92  			return getModifier().getValue();
93  		}
94  		return null;
95  	}
96  
97  	/**
98  	 * {@inheritDoc}
99  	 */
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 }