001package org.hl7.fhir.dstu2.model;
002
003/*-
004 * #%L
005 * org.hl7.fhir.dstu2
006 * %%
007 * Copyright (C) 2014 - 2019 Health Level 7
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
023
024import org.apache.commons.lang3.StringUtils;
025import org.apache.commons.lang3.builder.EqualsBuilder;
026import org.apache.commons.lang3.builder.HashCodeBuilder;
027import org.hl7.fhir.instance.model.api.IBaseHasExtensions;
028import org.hl7.fhir.instance.model.api.IPrimitiveType;
029
030public abstract class PrimitiveType<T> extends Type implements IPrimitiveType<T>, IBaseHasExtensions {
031
032        private static final long serialVersionUID = 3L;
033
034        private T myCoercedValue;
035        private String myStringValue;
036
037        public T getValue() {
038                return myCoercedValue;
039        }
040
041        public String asStringValue() {
042                return myStringValue;
043        }
044
045        @Override
046        public int hashCode() {
047                return new HashCodeBuilder().append(getValue()).toHashCode();
048        }
049
050        public PrimitiveType<T> setValue(T theValue) {
051                myCoercedValue = theValue;
052                updateStringValue();
053                return this;
054        }
055
056        protected void updateStringValue() {
057                if (myCoercedValue == null) {
058                        myStringValue = null;
059                } else {
060                        // NB this might be null
061                        myStringValue = encode(myCoercedValue);
062                }
063        }
064
065        @Override
066        public boolean isEmpty() {
067                return super.isEmpty() && StringUtils.isBlank(getValueAsString());
068        }
069
070        public void fromStringValue(String theValue) {
071                if (theValue == null) {
072                        myCoercedValue = null;
073                } else {
074                        // NB this might be null
075                        myCoercedValue = parse(theValue);
076                }
077                myStringValue = theValue;
078        }
079
080        /**
081         * Subclasses must override to convert an encoded representation of this datatype into a "coerced" one
082         * 
083         * @param theValue
084         *            Will not be null
085         * @return May return null if the value does not correspond to anything
086         */
087        protected abstract T parse(String theValue);
088
089        /**
090         * Subclasses must override to convert a "coerced" value into an encoded one.
091         * 
092         * @param theValue
093         *            Will not be null
094         * @return May return null if the value does not correspond to anything
095         */
096        protected abstract String encode(T theValue);
097
098        public boolean isPrimitive() {
099                return true;
100        }
101        
102        public String primitiveValue() {
103                return asStringValue();
104        }
105
106        @Override
107        public String toString() {
108                return getClass().getSimpleName() + "[" + asStringValue() + "]";
109        }
110
111        public boolean hasValue() {
112          return !StringUtils.isBlank(getValueAsString());
113        }
114
115        public String getValueAsString() {
116                return asStringValue();
117        }
118
119        public void setValueAsString(String theValue) {
120                fromStringValue(theValue);
121        }
122
123        protected Type typedCopy() {
124                return copy();
125        }
126
127        public abstract Type copy();
128
129        @Override
130        public boolean equalsDeep(Base obj) {
131                if (!super.equalsDeep(obj))
132                        return false;
133                if (obj == null) {
134                        return false;
135                }
136                if (!(obj.getClass() == getClass())) {
137                        return false;
138                }
139
140                PrimitiveType<?> o = (PrimitiveType<?>) obj;
141
142                EqualsBuilder b = new EqualsBuilder();
143                b.append(getValue(), o.getValue());
144                return b.isEquals();
145        }
146
147        @Override
148        public boolean equalsShallow(Base obj) {
149                if (obj == null) {
150                        return false;
151                }
152                if (!(obj.getClass() == getClass())) {
153                        return false;
154                }
155
156                PrimitiveType<?> o = (PrimitiveType<?>) obj;
157
158                EqualsBuilder b = new EqualsBuilder();
159                b.append(getValue(), o.getValue());
160                return b.isEquals();
161        }
162
163
164}