001package ca.uhn.fhir.rest.param;
002
003/*
004 * #%L
005 * HAPI FHIR - Core Library
006 * %%
007 * Copyright (C) 2014 - 2016 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.model.api.IQueryParameterType;
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                } else {
089                        return null;
090                }
091        }
092
093        /**
094         * {@inheritDoc}
095         */
096        @Override
097        String doGetValueAsQueryToken() {
098                if (getSystem() != null) {
099                        return ParameterUtil.escape(StringUtils.defaultString(getSystem())) + '|' + ParameterUtil.escape(getValue());
100                } else {
101                        return ParameterUtil.escape(getValue());
102                }
103        }
104
105        /**
106         * {@inheritDoc}
107         */
108        @Override
109        void doSetValueAsQueryToken(String theQualifier, String theParameter) {
110                setModifier(null);
111                if (theQualifier != null) {
112                        TokenParamModifier modifier = TokenParamModifier.forValue(theQualifier);
113                        setModifier(modifier);
114                        setSystem(null);
115                        setValue(ParameterUtil.unescape(theParameter));
116                } else {
117                        setSystem(null);
118                        if (theParameter == null) {
119                                setValue(null);
120                        } else {
121                                int barIndex = ParameterUtil.nonEscapedIndexOf(theParameter, '|');
122                                if (barIndex != -1) {
123                                        setSystem(theParameter.substring(0, barIndex));
124                                        setValue(ParameterUtil.unescape(theParameter.substring(barIndex + 1)));
125                                } else {
126                                        setValue(ParameterUtil.unescape(theParameter));
127                                }
128                        }
129                }
130        }
131
132        /**
133         * Returns the modifier for this token
134         */
135        public TokenParamModifier getModifier() {
136                return myModifier;
137        }
138
139        /**
140         * Returns the system for this token. Note that if a {@link #getModifier()} is being used, the entire value of the
141         * parameter will be placed in {@link #getValue() value} and this method will return <code>null</code>.
142         */
143        public String getSystem() {
144                return mySystem;
145        }
146
147        /**
148         * Returns the value for the token
149         */
150        public String getValue() {
151                return myValue;
152        }
153
154        public InternalCodingDt getValueAsCoding() {
155                return new InternalCodingDt(mySystem, myValue);
156        }
157
158        public String getValueNotNull() {
159                return defaultString(myValue);
160        }
161
162        public boolean isEmpty() {
163                return StringUtils.isEmpty(myValue);
164        }
165
166        /**
167         * Returns true if {@link #getModifier()} returns {@link TokenParamModifier#TEXT}
168         */
169        public boolean isText() {
170                return myModifier == TokenParamModifier.TEXT;
171        }
172
173        public TokenParam setModifier(TokenParamModifier theModifier) {
174                myModifier = theModifier;
175                return this;
176        }
177
178        public TokenParam setSystem(String theSystem) {
179                mySystem = theSystem;
180                return this;
181        }
182
183        /**
184         * @deprecated Use {@link #setModifier(TokenParamModifier)} instead
185         */
186        @Deprecated
187        public TokenParam setText(boolean theText) {
188                if (theText) {
189                        myModifier = TokenParamModifier.TEXT;
190                } else {
191                        myModifier = null;
192                }
193                return this;
194        }
195
196        public TokenParam setValue(String theValue) {
197                myValue = theValue;
198                return this;
199        }
200
201        @Override
202        public String toString() {
203                ToStringBuilder builder = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
204                builder.append("system", defaultString(getSystem()));
205                if (myModifier != null) {
206                        builder.append(":" + myModifier.getValue());
207                }
208                builder.append("value", getValue());
209                if (getMissing() != null) {
210                        builder.append(":missing", getMissing());
211                }
212                return builder.toString();
213        }
214
215        private static String toSystemValue(UriDt theSystem) {
216                return theSystem.getValueAsString();
217        }
218
219}