001package org.hl7.fhir.dstu2.model;
002
003/*
004  Copyright (c) 2011+, HL7, Inc.
005  All rights reserved.
006  
007  Redistribution and use in source and binary forms, with or without modification, 
008  are permitted provided that the following conditions are met:
009    
010   * Redistributions of source code must retain the above copyright notice, this 
011     list of conditions and the following disclaimer.
012   * Redistributions in binary form must reproduce the above copyright notice, 
013     this list of conditions and the following disclaimer in the documentation 
014     and/or other materials provided with the distribution.
015   * Neither the name of HL7 nor the names of its contributors may be used to 
016     endorse or promote products derived from this software without specific 
017     prior written permission.
018  
019  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
020  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
021  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
022  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
023  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
024  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
025  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
026  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
027  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
028  POSSIBILITY OF SUCH DAMAGE.
029  
030 */
031
032import org.apache.commons.lang3.StringUtils;
033import org.apache.commons.lang3.builder.EqualsBuilder;
034import org.apache.commons.lang3.builder.HashCodeBuilder;
035import org.hl7.fhir.instance.model.api.IBaseHasExtensions;
036import org.hl7.fhir.instance.model.api.IPrimitiveType;
037
038public abstract class PrimitiveType<T> extends Type implements IPrimitiveType<T>, IBaseHasExtensions {
039
040  private static final long serialVersionUID = 3L;
041
042  private T myCoercedValue;
043  private String myStringValue;
044
045  public T getValue() {
046    return myCoercedValue;
047  }
048
049  public String asStringValue() {
050    return myStringValue;
051  }
052
053  @Override
054  public int hashCode() {
055    return new HashCodeBuilder().append(getValue()).toHashCode();
056  }
057
058  public PrimitiveType<T> setValue(T theValue) {
059    myCoercedValue = theValue;
060    updateStringValue();
061    return this;
062  }
063
064  protected void updateStringValue() {
065    if (myCoercedValue == null) {
066      myStringValue = null;
067    } else {
068      // NB this might be null
069      myStringValue = encode(myCoercedValue);
070    }
071  }
072
073  @Override
074  public boolean isEmpty() {
075    return super.isEmpty() && StringUtils.isBlank(getValueAsString());
076  }
077
078  public void fromStringValue(String theValue) {
079    if (theValue == null) {
080      myCoercedValue = null;
081    } else {
082      // NB this might be null
083      myCoercedValue = parse(theValue);
084    }
085    myStringValue = theValue;
086  }
087
088  /**
089   * Subclasses must override to convert an encoded representation of this
090   * datatype into a "coerced" one
091   * 
092   * @param theValue Will not be null
093   * @return May return null if the value does not correspond to anything
094   */
095  protected abstract T parse(String theValue);
096
097  /**
098   * Subclasses must override to convert a "coerced" value into an encoded one.
099   * 
100   * @param theValue Will not be null
101   * @return May return null if the value does not correspond to anything
102   */
103  protected abstract String encode(T theValue);
104
105  public boolean isPrimitive() {
106    return true;
107  }
108
109  public String primitiveValue() {
110    return asStringValue();
111  }
112
113  @Override
114  public String toString() {
115    return getClass().getSimpleName() + "[" + asStringValue() + "]";
116  }
117
118  public boolean hasValue() {
119    return !StringUtils.isBlank(getValueAsString());
120  }
121
122  public String getValueAsString() {
123    return asStringValue();
124  }
125
126  public void setValueAsString(String theValue) {
127    fromStringValue(theValue);
128  }
129
130  protected Type typedCopy() {
131    return copy();
132  }
133
134  public abstract Type copy();
135
136  @Override
137  public boolean equalsDeep(Base obj) {
138    if (!super.equalsDeep(obj))
139      return false;
140    if (obj == null) {
141      return false;
142    }
143    if (!(obj.getClass() == getClass())) {
144      return false;
145    }
146
147    PrimitiveType<?> o = (PrimitiveType<?>) obj;
148
149    EqualsBuilder b = new EqualsBuilder();
150    b.append(getValue(), o.getValue());
151    return b.isEquals();
152  }
153
154  @Override
155  public boolean equalsShallow(Base obj) {
156    if (obj == null) {
157      return false;
158    }
159    if (!(obj.getClass() == getClass())) {
160      return false;
161    }
162
163    PrimitiveType<?> o = (PrimitiveType<?>) obj;
164
165    EqualsBuilder b = new EqualsBuilder();
166    b.append(getValue(), o.getValue());
167    return b.isEquals();
168  }
169
170}