001package ca.uhn.fhir.model.primitive;
002
003/*
004 * #%L
005 * HAPI FHIR - Core Library
006 * %%
007 * Copyright (C) 2014 - 2021 Smile CDR, Inc.
008 * %%
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 *
013 *      http://www.apache.org/licenses/LICENSE-2.0
014 *
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 * #L%
021 */
022
023import java.net.URI;
024import java.net.URISyntaxException;
025
026import org.apache.commons.lang3.StringUtils;
027
028import ca.uhn.fhir.model.api.BasePrimitive;
029import ca.uhn.fhir.model.api.annotation.DatatypeDef;
030import ca.uhn.fhir.model.api.annotation.SimpleSetter;
031
032@DatatypeDef(name = "uri")
033public class UriDt extends BasePrimitive<String> {
034
035        private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(UriDt.class);
036
037        /**
038         * Create a new String
039         */
040        public UriDt() {
041                // nothing
042        }
043
044        /**
045         * Create a new String
046         */
047        @SimpleSetter
048        public UriDt(@SimpleSetter.Parameter(name = "theUri") String theValue) {
049                setValueAsString(theValue);
050        }
051
052        @Override
053        protected String encode(String theValue) {
054                return theValue;
055        }
056
057        @Override
058        public boolean equals(Object obj) {
059                if (this == obj)
060                        return true;
061                if (obj == null)
062                        return false;
063                if (getClass() != obj.getClass())
064                        return false;
065
066                UriDt other = (UriDt) obj;
067                if (getValue() == null && other.getValue() == null) {
068                        return true;
069                }
070                if (getValue() == null || other.getValue() == null) {
071                        return false;
072                }
073
074                String normalize = normalize(getValue());
075                String normalize2 = normalize(other.getValue());
076                return normalize.equals(normalize2);
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 UriDt}
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                URI retVal;
104                try {
105                        retVal = new URI(theValue).normalize();
106                        String urlString = retVal.toString();
107                        if (urlString.endsWith("/") && urlString.length() > 1) {
108                                retVal = new URI(urlString.substring(0, urlString.length() - 1));
109                        }
110                } catch (URISyntaxException e) {
111                        ourLog.debug("Failed to normalize URL '{}', message was: {}", theValue, e.toString());
112                        return theValue;
113                }
114
115                return retVal.toASCIIString();
116        }
117
118        @Override
119        protected String parse(String theValue) {
120                return theValue;
121        }
122
123        /**
124         * Creates a new UriDt instance which uses the given OID as the content (and prepends "urn:oid:" to the OID string
125         * in the value of the newly created UriDt, per the FHIR specification).
126         * 
127         * @param theOid
128         *           The OID to use (<code>null</code> is acceptable and will result in a UriDt instance with a
129         *           <code>null</code> value)
130         * @return A new UriDt instance
131         */
132        public static UriDt fromOid(String theOid) {
133                if (theOid == null) {
134                        return new UriDt();
135                }
136                return new UriDt("urn:oid:" + theOid);
137        }
138
139}