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                UriType ret = new UriType(getValue());
070    copyValues(ret);
071    return ret;
072        }
073
074        @Override
075        protected String encode(String theValue) {
076                return theValue;
077        }
078
079        /**
080         * Compares the given string to the string representation of this URI. In many cases it is preferable to use this
081         * instead of the standard {@link #equals(Object)} method, since that method returns <code>false</code> unless it is
082         * 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, e.toString());
112                        return theValue;
113                }
114        }
115
116        @Override
117        protected String parse(String theValue) {
118                return theValue;
119        }
120
121        /**
122         * Creates a new OidType instance which uses the given OID as the content (and prepends "urn:oid:" to the OID string
123         * in the value of the newly created OidType, per the FHIR specification).
124         * 
125         * @param theOid
126         *            The OID to use (<code>null</code> is acceptable and will result in a UriDt instance with a
127         *            <code>null</code> value)
128         * @return A new UriDt instance
129         */
130        public static OidType fromOid(String theOid) {
131                if (theOid == null) {
132                        return new OidType();
133                }
134                return new OidType("urn:oid:" + theOid);
135        }
136
137         @Override
138   public boolean equalsDeep(Base obj) {
139     if (!super.equalsDeep(obj))
140       return false;
141                if (this == obj)
142                        return true;
143                if (obj == null)
144                        return false;
145                if (getClass() != obj.getClass())
146                        return false;
147
148                UriType other = (UriType) obj;
149                if (getValue() == null && other.getValue() == null) {
150                        return true;
151                }
152                if (getValue() == null || other.getValue() == null) {
153                        return false;
154                }
155
156                String normalize = normalize(getValue());
157                String normalize2 = normalize(other.getValue());
158                return normalize.equals(normalize2);
159   }
160
161                public String fhirType() {
162                        return "uri";                   
163                }
164
165}