package aQute.bnd.osgi; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URL; import java.net.URLConnection; import java.nio.ByteBuffer; import aQute.lib.io.IO; public class URLResource implements Resource { private static final ByteBuffer CLOSED = ByteBuffer.allocate(0); private ByteBuffer buffer; private final URL url; private String extra; private long lastModified = -1L; private int size = -1; public URLResource(URL url) { this.url = url; } @Override public ByteBuffer buffer() throws Exception { return getBuffer().duplicate(); } private ByteBuffer getBuffer() throws Exception { if (buffer != null) { return buffer; } if (url.getProtocol().equals("file")) { File file = new File(url.getPath()); lastModified = file.lastModified(); return buffer = IO.read(file.toPath()); } URLConnection conn = openConnection(); if (size == -1) { return buffer = ByteBuffer.wrap(IO.read(conn.getInputStream())); } ByteBuffer bb = IO.copy(conn.getInputStream(), ByteBuffer.allocate(size)); bb.flip(); return buffer = bb; } private URLConnection openConnection() throws Exception { URLConnection conn = url.openConnection(); conn.connect(); lastModified = conn.getLastModified(); int length = conn.getContentLength(); if (length != -1) { size = length; } return conn; } public InputStream openInputStream() throws Exception { return IO.stream(buffer()); } @Override public String toString() { return ":" + url.toExternalForm() + ":"; } public void write(OutputStream out) throws Exception { if (buffer != null) { IO.copy(buffer(), out); } else { IO.copy(openConnection().getInputStream(), out); } } public long lastModified() { if (lastModified >= 0L) { return lastModified; } try { getBuffer(); } catch (Exception e) { lastModified = 0L; } return lastModified; } public String getExtra() { return extra; } public void setExtra(String extra) { this.extra = extra; } public long size() throws Exception { if (size >= 0) { return size; } return size = getBuffer().limit(); } @Override public void close() throws IOException { /* * Allow original buffer to be garbage collected and prevent it being * remapped for this URLResouce. */ buffer = CLOSED; } }