001package ca.uhn.fhir.context;
002
003/*
004 * #%L
005 * HAPI FHIR - Core Library
006 * %%
007 * Copyright (C) 2014 - 2017 University Health Network
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 ca.uhn.fhir.model.api.IFhirVersion;
024import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
025
026public enum FhirVersionEnum {
027
028        /*
029         * ***********************
030         * Don't auto-sort this type!!!
031         *
032         * Or more accurately, entries should be sorted from OLDEST FHIR release
033         * to NEWEST FHIR release instead of alphabetically
034         * ***********************
035         */
036
037        DSTU1("ca.uhn.fhir.model.dstu.FhirDstu1", null, false, new Version("0.0.82")),
038
039        DSTU2("ca.uhn.fhir.model.dstu2.FhirDstu2", null, false, new Version("1.0.2")),
040
041        DSTU2_HL7ORG("org.hl7.fhir.instance.FhirDstu2Hl7Org", DSTU2, true, new Version("1.0.2")),
042
043        DSTU2_1("org.hl7.fhir.dstu2016may.hapi.ctx.FhirDstu2_1", null, true, new Version("1.4.0")),
044
045        DSTU3("org.hl7.fhir.dstu3.hapi.ctx.FhirDstu3", null, true, new Dstu3Version());
046
047        private final FhirVersionEnum myEquivalent;
048        private final boolean myIsRi;
049        private volatile Boolean myPresentOnClasspath;
050        private final String myVersionClass;
051        private volatile IFhirVersion myVersionImplementation;
052        private String myFhirVersionString;
053
054        FhirVersionEnum(String theVersionClass, FhirVersionEnum theEquivalent, boolean theIsRi, IVersionProvider theVersionExtractor) {
055                myVersionClass = theVersionClass;
056                myEquivalent = theEquivalent;
057                myFhirVersionString = theVersionExtractor.provideVersion();
058                myIsRi = theIsRi;
059        }
060
061        public String getFhirVersionString() {
062                return myFhirVersionString;
063        }
064
065        public IFhirVersion getVersionImplementation() {
066                if (!isPresentOnClasspath()) {
067                        throw new IllegalStateException("Version " + name() + " is not present on classpath");
068                }
069                if (myVersionImplementation == null) {
070                        try {
071                                myVersionImplementation = (IFhirVersion) Class.forName(myVersionClass).newInstance();
072                        } catch (Exception e) {
073                                throw new InternalErrorException("Failed to instantiate FHIR version " + name(), e);
074                        }
075                }
076                return myVersionImplementation;
077        }
078
079        public boolean isEquivalentTo(FhirVersionEnum theVersion) {
080                if (this.equals(theVersion)) {
081                        return true;
082                }
083                if (myEquivalent != null) {
084                        return myEquivalent.equals(theVersion);
085                }
086                return false;
087        }
088
089        public boolean isNewerThan(FhirVersionEnum theVersion) {
090                return !isEquivalentTo(theVersion) && ordinal() > theVersion.ordinal();
091        }
092
093        public boolean isOlderThan(FhirVersionEnum theVersion) {
094                return !isEquivalentTo(theVersion) && ordinal() < theVersion.ordinal();
095        }
096
097        /**
098         * Returns true if the given version is present on the classpath
099         */
100        public boolean isPresentOnClasspath() {
101                Boolean retVal = myPresentOnClasspath;
102                if (retVal == null) {
103                        try {
104                                Class.forName(myVersionClass);
105                                retVal = true;
106                        } catch (Exception e) {
107                                retVal = false;
108                        }
109                        myPresentOnClasspath = retVal;
110                }
111                return retVal;
112        }
113
114        /**
115         * Is this version using the HL7.org RI structures?
116         */
117        public boolean isRi() {
118                return myIsRi;
119        }
120
121        private static class Version implements IVersionProvider {
122
123                public Version(String theVersion) {
124                        super();
125                        myVersion = theVersion;
126                }
127
128                private String myVersion;
129
130                @Override
131                public String provideVersion() {
132                        return myVersion;
133                }
134
135        }
136
137        private interface IVersionProvider {
138                String provideVersion();
139        }
140
141        private static class Dstu3Version implements IVersionProvider {
142
143                public Dstu3Version() {
144                        try {
145                                Class<?> c = Class.forName("org.hl7.fhir.dstu3.model.Constants");
146                                myVersion = (String) c.getDeclaredField("VERSION").get(null);
147                        } catch (Exception e) {
148                                myVersion = "UNKNOWN";
149                        }
150                }
151
152                private String myVersion;
153
154                @Override
155                public String provideVersion() {
156                        return myVersion;
157                }
158
159        }
160
161}