001package org.hl7.fhir.r4.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 java.net.URI;
033import java.net.URISyntaxException;
034
035import org.apache.commons.lang3.StringUtils;
036
037import ca.uhn.fhir.model.api.annotation.DatatypeDef;
038
039/**
040 * Primitive type "uri" in FHIR: any valid URI. Sometimes constrained to be only
041 * an absolute URI, and sometimes constrained to be a literal reference
042 */
043@DatatypeDef(name = "uri")
044public class UriType extends PrimitiveType<String> {
045
046  private static final long serialVersionUID = 3L;
047
048  /**
049   * Constructor
050   */
051  public UriType() {
052    // nothing
053  }
054
055  /**
056   * Constructor
057   */
058  public UriType(String theValue) {
059    setValueAsString(theValue);
060  }
061
062  /**
063   * Constructor
064   */
065  public UriType(URI theValue) {
066    setValue(theValue.toString());
067  }
068
069  @Override
070  public UriType copy() {
071    UriType ret = new UriType(getValue());
072    copyValues(ret);
073    return ret;
074  }
075
076  @Override
077  protected String encode(String theValue) {
078    return theValue;
079  }
080
081  /**
082   * Compares the given string to the string representation of this URI. In many
083   * cases it is preferable to use this instead of the standard
084   * {@link #equals(Object)} method, since that method returns <code>false</code>
085   * unless it is passed an instance of {@link UriType}
086   */
087  public boolean equals(String theString) {
088    return StringUtils.equals(getValueAsString(), theString);
089  }
090
091  @Override
092  public int hashCode() {
093    final int prime = 31;
094    int result = 1;
095
096    String normalize = normalize(getValue());
097    result = prime * result + ((normalize == null) ? 0 : normalize.hashCode());
098
099    return result;
100  }
101
102  private String normalize(String theValue) {
103    if (theValue == null) {
104      return null;
105    }
106    try {
107      URI retVal = new URI(getValue()).normalize();
108      String urlString = retVal.toString();
109      if (urlString.endsWith("/") && urlString.length() > 1) {
110        retVal = new URI(urlString.substring(0, urlString.length() - 1));
111      }
112      return retVal.toASCIIString();
113    } catch (URISyntaxException e) {
114      // ourLog.debug("Failed to normalize URL '{}', message was: {}", urlString,
115      // e.toString());
116      return theValue;
117    }
118  }
119
120  @Override
121  protected String parse(String theValue) {
122    return theValue;
123  }
124
125  /**
126   * Creates a new OidType instance which uses the given OID as the content (and
127   * prepends "urn:oid:" to the OID string in the value of the newly created
128   * OidType, per the FHIR specification).
129   * 
130   * @param theOid The OID to use (<code>null</code> is acceptable and will result
131   *               in a UriDt instance with a <code>null</code> value)
132   * @return A new UriDt instance
133   */
134  public static OidType fromOid(String theOid) {
135    if (theOid == null) {
136      return new OidType();
137    }
138    return new OidType("urn:oid:" + theOid);
139  }
140
141  @Override
142  public boolean equalsDeep(Base obj) {
143    if (!super.equalsDeep(obj))
144      return false;
145    if (this == obj)
146      return true;
147    if (obj == null)
148      return false;
149    if (getClass() != obj.getClass())
150      return false;
151
152    UriType other = (UriType) obj;
153    if (getValue() == null && other.getValue() == null) {
154      return true;
155    }
156    if (getValue() == null || other.getValue() == null) {
157      return false;
158    }
159    if (getValue().equals(other.getValue())) {
160      return true;
161    }
162
163    String normalize = normalize(getValue());
164    String normalize2 = normalize(other.getValue());
165    return normalize.equals(normalize2);
166  }
167
168  public String fhirType() {
169    return "uri";
170  }
171
172}