/******************************************************************************* * 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.policy; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.net.URL; import org.eclipse.buckminster.download.ICache; import org.eclipse.buckminster.download.Installer; import org.eclipse.buckminster.download.Messages; import org.eclipse.buckminster.download.internal.FileReader; import org.eclipse.buckminster.runtime.BuckminsterException; import org.eclipse.buckminster.runtime.IFileInfo; import org.eclipse.buckminster.runtime.IOUtils; import org.eclipse.buckminster.runtime.MonitorUtils; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.ecf.core.security.IConnectContext; import org.eclipse.osgi.util.NLS; /** * @author Thomas Hallgren * */ public class ArchivePolicy extends AbstractFetchPolicy { private static final Object THREADLOCK = new Object(); /** * Creates directories in a synchronized block. Note: The same method is in * the org.eclipse.buckminster.core.helpers.FileUtils class, however, for * the dependency hierarchy reasons, this package is not accessible from * here. This could be solved by refactoring the dependencies. * * @param directory * The path for which all directories should be created * @throws CoreException * If the directories cannot be created */ private static void mkdirs(File directory) throws CoreException { synchronized (THREADLOCK) { if (directory == null || directory.exists() && !directory.isDirectory()) throw BuckminsterException.fromMessage(NLS.bind(Messages.error_0_cause_1, NLS.bind(Messages.unable_to_create_directory_0, directory != null ? directory : "(null)"), Messages.not_a_directory)); //$NON-NLS-1$ if (!directory.exists() && !directory.mkdirs()) throw BuckminsterException.fromMessage(NLS.bind(Messages.unable_to_create_directory_0, directory)); } } private final String remoteName; private final IConnectContext connectContext; public ArchivePolicy(ICache cache, IConnectContext cctx, String remoteName) { super(cache); this.remoteName = remoteName; this.connectContext = cctx; } @Override public boolean update(URL remoteFile, File localFile, boolean checkOnly, IFileInfo[] fiHandle, IProgressMonitor monitor) throws CoreException { MonitorUtils.begin(monitor, 1000); try { long localFileTS = localFile.lastModified(); if (localFileTS != 0L) { long localAge = System.currentTimeMillis() - localFileTS; if (localAge <= DEFAULT_MAX_LOCAL_AGE) { if (fiHandle != null) fiHandle[0] = readLocalFileInfo(remoteFile); return false; } IFileInfo fi; try { fi = getCache().getRemoteInfo(remoteFile, connectContext); if (fiHandle != null) fiHandle[0] = fi; } catch (FileNotFoundException e) { localFile.delete(); throw BuckminsterException.wrap(e); } if (fi.getSize() == localFile.length() && fi.getLastModified() != 0L && fi.getLastModified() <= localFile.lastModified()) { // Update the timestamp on the local file to reflec the // check that // we just made. // localFile.setLastModified(System.currentTimeMillis()); return false; } } MonitorUtils.worked(monitor, 100); if (checkOnly) return true; File tempFile = new File(localFile.getPath() + ".tmp"); //$NON-NLS-1$ String fileName = readRemoteFile(remoteFile, tempFile, fiHandle, MonitorUtils.subMonitor(monitor, 800)); if (remoteName != null) fileName = remoteName; try { Installer.getInstaller(fileName, true).validate(tempFile, MonitorUtils.subMonitor(monitor, 100)); } catch (CoreException e) { tempFile.delete(); throw e; } safeRename(tempFile, localFile); return true; } finally { MonitorUtils.done(monitor); } } protected String readRemoteFile(URL url, File localFile, IFileInfo[] fiHandle, IProgressMonitor monitor) throws CoreException { // Set up the file transfer // OutputStream output = null; try { localFile = localFile.getCanonicalFile(); File parentFolder = localFile.getParentFile(); if (parentFolder != null) mkdirs(parentFolder); output = new FileOutputStream(localFile); FileReader retriever = new FileReader(connectContext); retriever.readInto(url, output, monitor); IFileInfo fileInfo = retriever.getLastFileInfo(); saveLocalFileInfo(url, fileInfo); if (fiHandle != null) fiHandle[0] = fileInfo; return fileInfo.getRemoteName(); } catch (IOException e) { throw BuckminsterException.wrap(e); } finally { IOUtils.close(output); } } }