001package ca.uhn.fhir.model.base.composite;
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 */
022
023import org.apache.commons.lang3.StringUtils;
024
025import ca.uhn.fhir.model.api.BaseIdentifiableElement;
026import ca.uhn.fhir.model.api.ICompositeDatatype;
027import ca.uhn.fhir.model.api.IQueryParameterType;
028import ca.uhn.fhir.model.primitive.CodeDt;
029import ca.uhn.fhir.model.primitive.StringDt;
030import ca.uhn.fhir.model.primitive.UriDt;
031import ca.uhn.fhir.rest.param.ParameterUtil;
032import ca.uhn.fhir.rest.param.TokenParam;
033
034public abstract class BaseCodingDt extends BaseIdentifiableElement implements ICompositeDatatype, IQueryParameterType {
035
036        /**
037         * Gets the value(s) for <b>code</b> (Symbol in syntax defined by the system). creating it if it does not exist. Will not return <code>null</code>.
038         *
039         * <p>
040         * <b>Definition:</b> A symbol in syntax defined by the system. The symbol may be a predefined code or an expression in a syntax defined by the coding system (e.g. post-coordination)
041         * </p>
042         */
043        public abstract CodeDt getCodeElement();
044
045        @Override
046        public String getQueryParameterQualifier() {
047                return null;
048        }
049
050        /**
051         * Gets the value(s) for <b>system</b> (Identity of the terminology system). creating it if it does not exist. Will not return <code>null</code>.
052         *
053         * <p>
054         * <b>Definition:</b> The identification of the code system that defines the meaning of the symbol in the code.
055         * </p>
056         */
057        public abstract UriDt getSystemElement();
058
059        /**
060         * Gets the value(s) for <b>display</b> (Representation defined by the system).
061         * creating it if it does
062         * not exist. Will not return <code>null</code>.
063         *
064     * <p>
065     * <b>Definition:</b>
066     * A representation of the meaning of the code in the system, following the rules of the system.
067     * </p> 
068         */
069        public abstract StringDt getDisplayElement();
070
071        public abstract BaseCodingDt setDisplay( String theString);
072
073        /*
074        todo: handle version
075        public abstract StringDt getVersion();
076
077        public abstract BaseCodingDt setVersion ( String theString);
078        */
079
080        /**
081         * {@inheritDoc}
082         */
083        @Override
084        public String getValueAsQueryToken() {
085                if (getSystemElement().getValueAsString() != null) {
086                        return ParameterUtil.escape(StringUtils.defaultString(getSystemElement().getValueAsString())) + '|' + ParameterUtil.escape(getCodeElement().getValueAsString());
087                } else {
088                        return ParameterUtil.escape(getCodeElement().getValueAsString());
089                }
090        }
091
092        /**
093         * {@inheritDoc}
094         */
095        @Override
096        public void setValueAsQueryToken(String theQualifier, String theParameter) {
097                int barIndex = ParameterUtil.nonEscapedIndexOf(theParameter, '|');
098                if (barIndex != -1) {
099                        setSystem(theParameter.substring(0, barIndex));
100                        setCode(ParameterUtil.unescape(theParameter.substring(barIndex + 1)));
101                } else {
102                        setCode(ParameterUtil.unescape(theParameter));
103                }
104        }
105
106        /**
107         * Returns true if <code>this</code> Coding has the same {@link #getCodeElement() Code} and {@link #getSystemElement() system} (as compared by simple equals comparison). Does not compare other
108         * Codes (e.g. getUseElement()) or any extensions.
109         */
110        public boolean matchesSystemAndCode(BaseCodingDt theCoding) {
111                if (theCoding == null) {
112                        return false;
113                }
114                return getCodeElement().equals(theCoding.getCodeElement()) && getSystemElement().equals(theCoding.getSystemElement());
115        }
116
117        /**
118         * returns true if <code>this</code> Coding matches a search for the coding specified by <code>theSearchParam</code>, according
119         * to the following:
120         * <ul>
121         *              <li>[parameter]=[namespace]|[code] matches a code/value in the given system namespace</li>
122         *              <li>[parameter]=[code] matches a code/value irrespective of it's system namespace</li>
123         *              <li>[parameter]=|[code] matches a code/value that has no system namespace</li>
124         * </ul>
125         * @param theSearchParam - coding to test <code>this</code> against
126         * @return true if the coding matches, false otherwise
127         */
128        public boolean matchesToken(BaseCodingDt theSearchParam) {
129                if (theSearchParam.isSystemPresent()) {
130                        if (theSearchParam.isSystemBlank()) {
131                                //  [parameter]=|[code] matches a code/value that has no system namespace
132                                if (isSystemPresent() && !isSystemBlank())
133                                        return false;
134                        } else {
135                                //  [parameter]=[namespace]|[code] matches a code/value in the given system namespace
136                                if (!isSystemPresent())
137                                        return false;
138                                if (!getSystemElement().equals(theSearchParam.getSystemElement()))
139                                        return false;
140                        }
141                } else {
142                        //  [parameter]=[code] matches a code/value irrespective of it's system namespace
143                        // (nothing to do for system for this case)
144                }
145
146                return getCodeElement().equals(theSearchParam.getCodeElement());
147        }
148
149        private boolean isSystemPresent() {
150                return !getSystemElement().isEmpty();
151        }
152
153        private boolean isSystemBlank() {
154                return isSystemPresent() && getSystemElement().getValueAsString().equals("");
155        }
156
157        /**
158         * Sets the value for <b>code</b> (Symbol in syntax defined by the system)
159         *
160         * <p>
161         * <b>Definition:</b> A symbol in syntax defined by the system. The symbol may be a predefined code or an expression in a syntax defined by the coding system (e.g. post-coordination)
162         * </p>
163         */
164        public abstract BaseCodingDt setCode(String theCode);
165
166        /**
167         * Sets the value for <b>system</b> (Identity of the terminology system)
168         *
169         * <p>
170         * <b>Definition:</b> The identification of the code system that defines the meaning of the symbol in the code.
171         * </p>
172         */
173        public abstract BaseCodingDt setSystem(String theUri);
174
175
176        /**
177         * <b>Not supported!</b>
178         * 
179         * @deprecated get/setMissing is not supported in StringDt. Use {@link TokenParam} instead if you
180         * need this functionality
181         */
182        @Deprecated
183        @Override
184        public Boolean getMissing() {
185                return null;
186        }
187
188        /**
189         * <b>Not supported!</b>
190         * 
191         * @deprecated get/setMissing is not supported in StringDt. Use {@link TokenParam} instead if you
192         * need this functionality
193         */
194        @Deprecated
195        @Override
196        public void setMissing(Boolean theMissing) {
197                throw new UnsupportedOperationException("get/setMissing is not supported in StringDt. Use {@link StringParam} instead if you need this functionality");
198        }
199
200}