org.hl7.fhir.utilities.npm.BasePackageCacheManager Maven / Gradle / Ivy
package org.hl7.fhir.utilities.npm;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.utilities.Utilities;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
public abstract class BasePackageCacheManager implements IPackageCacheManager {
private static final Logger ourLog = LoggerFactory.getLogger(BasePackageCacheManager.class);
private List myPackageServers = new ArrayList<>();
private Function myClientFactory = address -> new CachingPackageClient(address);
/**
* Constructor
*/
public BasePackageCacheManager() {
super();
}
/**
* Provide a new client factory implementation
*/
public void setClientFactory(Function theClientFactory) {
Validate.notNull(theClientFactory, "theClientFactory must not be null");
myClientFactory = theClientFactory;
}
public List getPackageServers() {
return myPackageServers;
}
/**
* Add a package server that can be used to fetch remote packages
*/
public void addPackageServer(@Nonnull String thePackageServer) {
Validate.notBlank(thePackageServer, "thePackageServer must not be null or empty");
if (!myPackageServers.contains(thePackageServer)) {
myPackageServers.add(thePackageServer);
}
}
/**
* Load the latest version of the identified package from the cache - it it exists
*/
public NpmPackage loadPackageFromCacheOnly(String id) throws IOException {
return loadPackageFromCacheOnly(id, null);
}
/**
* Try to load a package from all registered package servers, and return null
* if it can not be found at any of them.
*/
@Nullable
protected InputStreamWithSrc loadFromPackageServer(String id, String version) {
for (String nextPackageServer : getPackageServers()) {
if (okToUsePackageServer(nextPackageServer, id)) {
PackageClient packageClient = myClientFactory.apply(nextPackageServer);
try {
if (Utilities.noString(version)) {
version = packageClient.getLatestVersion(id);
}
if (version.endsWith(".x")) {
version = packageClient.getLatestVersion(id, version);
}
InputStream stream = packageClient.fetch(id, version);
String url = packageClient.url(id, version);
return new InputStreamWithSrc(stream, url, version);
} catch (IOException e) {
ourLog.info("Failed to resolve package {}#{} from server: {}", id, version, nextPackageServer);
}
}
}
return null;
}
// hack - we have a hacked 1.4.0 out there. Only packages2.fhir.org has it.
// this is not a long term thing, but it's not clear how to release patches for
// 1.4.0
private boolean okToUsePackageServer(String server, String id) {
if ("http://packages.fhir.org".equals(server) && "hl7.fhir.r2b.core".equals(id)) {
return false;
}
return true;
}
public abstract NpmPackage loadPackageFromCacheOnly(String id, @Nullable String version) throws IOException;
@Override
public String getPackageUrl(String packageId) throws IOException {
String result = null;
NpmPackage npm = loadPackageFromCacheOnly(packageId);
if (npm != null) {
return npm.canonical();
}
for (String nextPackageServer : getPackageServers()) {
result = getPackageUrl(packageId, nextPackageServer);
if (result != null) {
return result;
}
}
return result;
}
private String getPackageUrl(String packageId, String server) throws IOException {
PackageClient pc = myClientFactory.apply(server);
List res = pc.search(packageId, null, null, false);
if (res.size() == 0) {
return null;
} else {
return res.get(0).getUrl();
}
}
@Override
public String getPackageId(String canonicalUrl) throws IOException {
String result = null;
for (String nextPackageServer : getPackageServers()) {
result = getPackageId(canonicalUrl, nextPackageServer);
if (result != null) {
break;
}
}
return result;
}
private String getPackageId(String canonical, String server) throws IOException {
if (canonical == null) {
return null;
}
PackageClient pc = myClientFactory.apply(server);
List res = pc.search(null, canonical, null, false);
if (res.size() == 0) {
return null;
} else {
// this is driven by HL7 Australia (http://hl7.org.au/fhir/ is the canonical url for the base package, and the root for all the others)
for (PackageInfo pi : res) {
if (canonical.equals(pi.getCanonical())) {
return pi.getId();
}
}
return res.get(0).getId();
}
}
public class InputStreamWithSrc {
public InputStream stream;
public String url;
public String version;
public InputStreamWithSrc(InputStream stream, String url, String version) {
this.stream = stream;
this.url = url;
this.version = version;
}
}
public NpmPackage loadPackage(String idAndVer) throws FHIRException, IOException {
return loadPackage(idAndVer, null);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy