/*******************************************************************************
* Copyright (c) 2006-2013, Cloudsmith Inc.
* The code, documentation and other materials contained herein have been
* licensed under the Eclipse Public License - v 1.0 by the copyright holder
* listed above, as the Initial Contributor under such license. The text of
* such license is available at www.eclipse.org.
******************************************************************************/
package org.eclipse.buckminster.download.internal;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.UUID;
import org.eclipse.buckminster.download.DownloadManager;
import org.eclipse.buckminster.download.ICache;
import org.eclipse.buckminster.download.IFetchPolicy;
import org.eclipse.buckminster.download.Messages;
import org.eclipse.buckminster.download.policy.ArchivePolicy;
import org.eclipse.buckminster.download.policy.DigestPolicy;
import org.eclipse.buckminster.runtime.BuckminsterException;
import org.eclipse.buckminster.runtime.FileInfoBuilder;
import org.eclipse.buckminster.runtime.IFileInfo;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.ecf.core.security.IConnectContext;
import org.eclipse.osgi.util.NLS;
/**
* @author Thomas Hallgren
*/
public class CacheImpl implements ICache {
public static final String LAST_MODIFIED_HEADER = "Last-Modified"; //$NON-NLS-1$
private static File asLocal(URL url) {
try {
url = FileLocator.resolve(url);
return "file".equalsIgnoreCase(url.getProtocol()) ? new File(url.toURI()) : null; //$NON-NLS-1$
} catch (IOException e) {
return null;
} catch (URISyntaxException e) {
return null;
}
}
private final File location;
public CacheImpl(File location) throws CoreException {
this.location = location;
if (!(location.isDirectory() || location.mkdirs()))
throw BuckminsterException.fromMessage(NLS.bind(Messages.unable_to_access_cache_0, location));
}
public UUID getHash(String urlStr) {
return UUID.nameUUIDFromBytes(urlStr.getBytes());
}
@Override
public File getLocation() {
return location;
}
@Override
public IFileInfo getRemoteInfo(URL remoteFile, IConnectContext cctx) throws CoreException, FileNotFoundException {
File localFile = asLocal(remoteFile);
if (localFile != null)
return new FileInfoBuilder(localFile);
if (cctx == null) {
URL[] uh = new URL[] { remoteFile };
cctx = DownloadManager.createConnectContext(uh);
remoteFile = uh[0];
}
FileReader reader = new FileReader(cctx);
return reader.readInfo(remoteFile);
}
public File getSubFolder(String protocol, String domain) {
File protoFolder = new File(location, protocol);
if (domain == null)
domain = "localhost"; //$NON-NLS-1$
return new File(protoFolder, domain);
}
public File getSubFolder(URL url) {
return getSubFolder(url.getProtocol(), url.getHost());
}
@Override
public boolean isUpToDate(IFetchPolicy policy, URL remoteFile, IProgressMonitor monitor) throws CoreException, FileNotFoundException {
String urlStr = remoteFile.toString().intern();
synchronized (urlStr) {
File localFile = asLocal(remoteFile);
if (localFile != null)
return localFile.canRead();
localFile = new File(getSubFolder(remoteFile), getHash(urlStr).toString());
return !policy.update(remoteFile, localFile, true, null, monitor);
}
}
@Override
public boolean isUpToDate(URL remoteFile, IConnectContext cctx, String remoteName, IProgressMonitor monitor) throws CoreException,
FileNotFoundException {
if (cctx == null) {
URL[] uh = new URL[] { remoteFile };
cctx = DownloadManager.createConnectContext(uh);
remoteFile = uh[0];
}
return isUpToDate(new ArchivePolicy(this, cctx, remoteName), remoteFile, monitor);
}
@Override
public boolean isUpToDate(URL remoteFile, URL remoteDigest, IConnectContext cctx, String algorithm, IProgressMonitor monitor)
throws CoreException, FileNotFoundException {
if (cctx == null) {
URL[] uh = new URL[] { remoteFile };
cctx = DownloadManager.createConnectContext(uh);
remoteFile = uh[0];
// Assume that the digest has the same credentials
uh[0] = remoteDigest;
DownloadManager.createConnectContext(uh);
remoteDigest = uh[0];
}
return isUpToDate(new DigestPolicy(this, remoteDigest, cctx, algorithm, DigestPolicy.DEFAULT_MAX_DIGEST_AGE), remoteFile, monitor);
}
@Override
public InputStream open(IFetchPolicy policy, URL remoteFile, IFileInfo[] fiHandle, IProgressMonitor monitor) throws CoreException,
FileNotFoundException {
File file = asLocal(remoteFile);
if (file != null) {
if (fiHandle != null)
fiHandle[0] = new FileInfoBuilder(file);
return new FileInputStream(file);
}
URL[] uh = new URL[] { remoteFile };
DownloadManager.createConnectContext(uh);
remoteFile = uh[0];
String urlStr = remoteFile.toString().intern();
synchronized (urlStr) {
File localFile = new File(getSubFolder(remoteFile), getHash(urlStr).toString());
policy.update(remoteFile, localFile, false, fiHandle, monitor);
return new FileInputStream(localFile);
}
}
@Override
public InputStream open(URL remoteFile, IConnectContext cctx, String remoteName, IFileInfo[] fiHandle, IProgressMonitor monitor)
throws CoreException, FileNotFoundException {
if (cctx == null) {
URL[] uh = new URL[] { remoteFile };
cctx = DownloadManager.createConnectContext(uh);
remoteFile = uh[0];
}
return open(new ArchivePolicy(this, cctx, remoteName), remoteFile, fiHandle, monitor);
}
@Override
public InputStream open(URL remoteFile, URL remoteDigest, IConnectContext cctx, String algorithm, IFileInfo[] fiHandle, IProgressMonitor monitor)
throws CoreException, FileNotFoundException {
if (cctx == null) {
URL[] uh = new URL[] { remoteFile };
cctx = DownloadManager.createConnectContext(uh);
remoteFile = uh[0];
}
return open(new DigestPolicy(this, remoteDigest, cctx, algorithm, DigestPolicy.DEFAULT_MAX_DIGEST_AGE), remoteFile, fiHandle, monitor);
}
@Override
public InputStream openRemote(URL remoteFile, IConnectContext cctx) throws CoreException, FileNotFoundException {
File file = asLocal(remoteFile);
if (file != null)
return new FileInputStream(file);
if (cctx == null) {
URL[] uh = new URL[] { remoteFile };
cctx = DownloadManager.createConnectContext(uh);
remoteFile = uh[0];
}
FileReader reader = new FileReader(cctx);
return reader.read(remoteFile);
}
}