package org.bndtools.templating.jgit;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URI;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import aQute.bnd.http.HttpClient;
import aQute.bnd.service.url.TaggedData;
import aQute.lib.io.IO;
import aQute.libg.tuple.Pair;
public class Cache {
private final ConcurrentMap<URI,Pair<String,byte[]>> cache = new ConcurrentHashMap<>();
public byte[] download(URI uri) throws IOException {
byte[] data;
try (HttpClient client = new HttpClient()) {
Pair<String,byte[]> cachedTag = cache.get(uri);
if (cachedTag == null) {
// Not previously cached
TaggedData td = client.connectTagged(uri.toURL());
if (td == null || td.isNotFound())
throw new FileNotFoundException("Not found");
data = IO.read(td.getInputStream());
if (td.getTag() != null)
cache.put(uri, new Pair<String,byte[]>(td.getTag(), data));
} else {
// Previously cached with an ETag
TaggedData td = client.connectTagged(uri.toURL(), cachedTag.getFirst());
if (td == null || td.isNotFound())
throw new FileNotFoundException("Not found");
if (td.getResponseCode() == 304) {
// unchanged
data = cachedTag.getSecond();
} else {
// changed
data = IO.read(td.getInputStream());
if (td.getTag() == null) {
// server now not giving an etag -> remove from cache
cache.remove(td.getTag());
} else {
// replace cache entry with new tag
cache.put(uri, new Pair<String,byte[]>(td.getTag(), data));
}
}
}
return data;
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw new IOException(e);
}
}
}