001/*
002Copyright (c) 2011+, HL7, Inc
003All rights reserved.
004
005Redistribution and use in source and binary forms, with or without modification, 
006are permitted provided that the following conditions are met:
007
008 * Redistributions of source code must retain the above copyright notice, this 
009   list of conditions and the following disclaimer.
010 * Redistributions in binary form must reproduce the above copyright notice, 
011   this list of conditions and the following disclaimer in the documentation 
012   and/or other materials provided with the distribution.
013 * Neither the name of HL7 nor the names of its contributors may be used to 
014   endorse or promote products derived from this software without specific 
015   prior written permission.
016
017THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
018ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
019WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
020IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
021INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
022NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
023PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
024WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
025ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
026POSSIBILITY OF SUCH DAMAGE.
027
028*/
029package org.hl7.fhir.r4.model;
030
031import java.net.URI;
032import java.net.URISyntaxException;
033
034import org.apache.commons.lang3.StringUtils;
035
036import ca.uhn.fhir.model.api.annotation.DatatypeDef;
037
038/**
039 * Primitive type "uri" in FHIR: any valid URI. Sometimes constrained to be only an absolute URI, and sometimes constrained to be a literal reference
040 */
041@DatatypeDef(name = "uri")
042public class UriType extends PrimitiveType<String> {
043
044        private static final long serialVersionUID = 3L;
045
046        /**
047         * Constructor
048         */
049        public UriType() {
050                // nothing
051        }
052
053        /**
054         * Constructor
055         */
056        public UriType(String theValue) {
057                setValueAsString(theValue);
058        }
059
060        /**
061         * Constructor
062         */
063        public UriType(URI theValue) {
064                setValue(theValue.toString());
065        }
066
067        @Override
068        public UriType copy() {
069                return new UriType(getValue());
070        }
071
072        @Override
073        protected String encode(String theValue) {
074                return theValue;
075        }
076
077        /**
078         * Compares the given string to the string representation of this URI. In many cases it is preferable to use this
079         * instead of the standard {@link #equals(Object)} method, since that method returns <code>false</code> unless it is
080         * passed an instance of {@link UriType}
081         */
082        public boolean equals(String theString) {
083                return StringUtils.equals(getValueAsString(), theString);
084        }
085
086        @Override
087        public int hashCode() {
088                final int prime = 31;
089                int result = 1;
090
091                String normalize = normalize(getValue());
092                result = prime * result + ((normalize == null) ? 0 : normalize.hashCode());
093
094                return result;
095        }
096
097        private String normalize(String theValue) {
098                if (theValue == null) {
099                        return null;
100                }
101                try {
102                        URI retVal = new URI(getValue()).normalize();
103                        String urlString = retVal.toString();
104                        if (urlString.endsWith("/") && urlString.length() > 1) {
105                                retVal = new URI(urlString.substring(0, urlString.length() - 1));
106                        }
107                        return retVal.toASCIIString();
108                } catch (URISyntaxException e) {
109                        // ourLog.debug("Failed to normalize URL '{}', message was: {}", urlString, e.toString());
110                        return theValue;
111                }
112        }
113
114        @Override
115        protected String parse(String theValue) {
116                return theValue;
117        }
118
119        /**
120         * Creates a new OidType instance which uses the given OID as the content (and prepends "urn:oid:" to the OID string
121         * in the value of the newly created OidType, per the FHIR specification).
122         * 
123         * @param theOid
124         *            The OID to use (<code>null</code> is acceptable and will result in a UriDt instance with a
125         *            <code>null</code> value)
126         * @return A new UriDt instance
127         */
128        public static OidType fromOid(String theOid) {
129                if (theOid == null) {
130                        return new OidType();
131                }
132                return new OidType("urn:oid:" + theOid);
133        }
134
135         @Override
136   public boolean equalsDeep(Base obj) {
137     if (!super.equalsDeep(obj))
138       return false;
139                if (this == obj)
140                        return true;
141                if (obj == null)
142                        return false;
143                if (getClass() != obj.getClass())
144                        return false;
145
146                UriType other = (UriType) obj;
147                if (getValue() == null && other.getValue() == null) {
148                        return true;
149                }
150                if (getValue() == null || other.getValue() == null) {
151                        return false;
152                }
153
154                String normalize = normalize(getValue());
155                String normalize2 = normalize(other.getValue());
156                return normalize.equals(normalize2);
157   }
158
159                public String fhirType() {
160                        return "uri";                   
161                }
162
163}