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