001package ca.uhn.fhir.cql.common.provider; 002 003/*- 004 * #%L 005 * HAPI FHIR JPA Server - Clinical Quality Language 006 * %% 007 * Copyright (C) 2014 - 2022 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 ca.uhn.fhir.rest.api.server.RequestDetails; 024 025import java.util.function.Function; 026 027public interface LibraryResolutionProvider<LibraryType> { 028 static int compareVersions(String version1, String version2) { 029 // Treat null as MAX VERSION 030 if (version1 == null && version2 == null) { 031 return 0; 032 } 033 034 if (version1 != null && version2 == null) { 035 return -1; 036 } 037 038 if (version1 == null && version2 != null) { 039 return 1; 040 } 041 042 String[] string1Vals = version1.split("\\."); 043 String[] string2Vals = version2.split("\\."); 044 045 int length = Math.max(string1Vals.length, string2Vals.length); 046 047 for (int i = 0; i < length; i++) 048 { 049 Integer v1 = (i < string1Vals.length)?Integer.parseInt(string1Vals[i]):0; 050 Integer v2 = (i < string2Vals.length)?Integer.parseInt(string2Vals[i]):0; 051 052 //Making sure Version1 bigger than version2 053 if (v1 > v2) 054 { 055 return 1; 056 } 057 //Making sure Version1 smaller than version2 058 else if (v1 < v2) { 059 return -1; 060 } 061 } 062 063 //Both are equal 064 return 0; 065 } 066 067 LibraryType resolveLibraryById(String libraryId, RequestDetails theRequestDetails); 068 069 LibraryType resolveLibraryByName(String libraryName, String libraryVersion); 070 071 LibraryType resolveLibraryByCanonicalUrl(String libraryUrl, RequestDetails theRequestDetails); 072 073 074 // This function assumes that you're selecting from a set of libraries with the same name. 075 // It returns the closest matching version, or the max version if no version is specified. 076 static <LibraryType> LibraryType selectFromList(Iterable<LibraryType> libraries, String libraryVersion, Function<LibraryType, String> getVersion) { 077 LibraryType library = null; 078 LibraryType maxVersion = null; 079 for (LibraryType l : libraries) { 080 String currentVersion = getVersion.apply(l); 081 if ((libraryVersion != null && currentVersion.equals(libraryVersion)) || 082 (libraryVersion == null && currentVersion == null)) { 083 library = l; 084 } 085 086 if (maxVersion == null || compareVersions( 087 getVersion.apply(maxVersion), 088 getVersion.apply(l)) < 0) { 089 maxVersion = l; 090 } 091 } 092 093 // If we were not given a version, return the highest found 094 if (libraryVersion == null && maxVersion != null) { 095 return maxVersion; 096 } 097 098 return library; 099 } 100 101 // Hmmm... Probably need to think through this use case a bit more. 102 // Should we throw an exception? Should this be a different interface? 103 void update(LibraryType library); 104}