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