blob: 0354d7242df7c67579b6eddafa525c181d907702 [file] [log] [blame]
/*******************************************************************************
* Copyright 2011 Chair for Applied Software Engineering,
* Technische Universitaet Muenchen.
* All rights reserved. This program and the accompanying materials
* are made available under the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
******************************************************************************/
package org.eclipse.emf.emfstore.client.model.filetransfer;
import java.io.File;
import java.io.IOException;
import org.eclipse.emf.emfstore.client.model.Configuration;
import org.eclipse.emf.emfstore.client.model.ProjectSpace;
import org.eclipse.emf.emfstore.common.model.util.FileUtil;
import org.eclipse.emf.emfstore.server.exceptions.FileTransferException;
import org.eclipse.emf.emfstore.server.model.FileIdentifier;
/**
* This class manages the locally cached files for file transfers. A cache
* manager instance is contained in every FileTransferManager. No other cache
* managers should be created.
*
* @author jfinis
*/
public class FileTransferCacheManager {
/**
* tmp folder for file uploads to server.
*/
public static final String TEMP_FOLDER = "tmp";
/**
* project folder prefix.
*/
public static final String PROJECT_FOLDER_PREFIX = "project-";
/**
* Attachment folder for uploads and downloads.
*/
public static final String ATTACHMENT_FOLDER = "attachment";
/**
* The delimiter that separates file attachment id, file version and file
* name in an uploaded file.
*/
public static final String FILE_NAME_DELIMITER = "_";
/**
* The associated project space.
*/
private ProjectSpace projectSpace;
/**
* The cache folder, constructed from the identifier of the project space.
*/
private File cacheFolder;
/**
* The temp folder is a folder where unfinished file downloads are stored.
*/
private File tempCacheFolder;
/**
* Default constructor for a specific project space.
*
* @param projectSpaceImpl
* the project space to which this cache belongs.
*/
public FileTransferCacheManager(ProjectSpace projectSpaceImpl) {
this.projectSpace = projectSpaceImpl;
this.cacheFolder = new File(getCacheFolder(projectSpace));
this.tempCacheFolder = new File(cacheFolder, "temp");
mkdirs();
}
/**
* Returns the default file cache folder of a given projectspace.
*
* @param projectSpace the projectSpace
* @return the name of the cache folder
*/
public static String getCacheFolder(ProjectSpace projectSpace) {
return Configuration.getWorkspaceDirectory() + "ps-" + projectSpace.getIdentifier() + File.separatorChar
+ "files" + File.separatorChar;
}
/**
* Returns true iff a file with this identifier is present in the cache.
* After this method has returned true, it is guaranteed that the
* getCachedFile method finds the file and does not throw an exception.
*
* @param identifier
* the identifer of the file
* @return if the file is present in the cache
*/
public boolean hasCachedFile(FileIdentifier identifier) {
File f = getFileFromId(cacheFolder, identifier);
return f.exists();
}
/**
* Returns a cached file with a given identifier. If the file does not
* exist, a FileTransferException is thrown.
*
* @param identifier
* the idntifier of the file
* @return the file
* @throws FileTransferException
* if the file is not present in the cache
*/
public File getCachedFile(FileIdentifier identifier) throws FileTransferException {
File f = getFileFromId(cacheFolder, identifier);
if (!f.exists()) {
throw new FileTransferException("The file with the id " + identifier + " is not in the cache");
}
return f;
}
/**
* Adds a file to the cache using a given id. If a file with the given id is
* already in the cache, it is overwritten.
*
* @param input
* the file to be cached
* @param id
* the id to be used for the file.
* @return the file in the cache folder
* @throws IOException
* any IO Exception that can occur during copying a file
*/
public File cacheFile(File input, FileIdentifier id) throws IOException {
mkdirs();
File destination = new File(cacheFolder, id.getIdentifier());
FileUtil.copyFile(input, destination);
return destination;
}
/**
* Creates a file in the temp cache folder for a specified file id and
* returns it. If the file already exists, it is deleted and newly created.
*
* @param id
* the file id for which to create a temporary file
* @return the temporary file
* @throws FileTransferException
* if an io exception occurred during the creation of a new file
*/
public File createTempFile(FileIdentifier id) throws FileTransferException {
mkdirs();
File cacheFile = getFileFromId(tempCacheFolder, id);
if (cacheFile.exists()) {
cacheFile.delete();
}
try {
cacheFile.createNewFile();
} catch (IOException e) {
throw new FileTransferException("Could not create temporary file");
}
return cacheFile;
}
/**
* This method moves a file from the temp folder into the cache. It should
* be called after a temporary file was written successfully. A file
* transfer exception is thrown in the following cases: - The file does not
* exist in the temp folder - The file already exists in the cache folder -
* The file cannot be moved to the cache folder (the rename operation fails)
*
* @param id
* the id of the file which is to be moved
* @return the new location of the file after moving it
* @throws FileTransferException
* thrown if the temp file does not exist, the final file
* already exists, or if the rename operation which moves the
* file fails
*/
public File moveTempFileToCache(FileIdentifier id) throws FileTransferException {
mkdirs();
File cacheFile = getFileFromId(cacheFolder, id);
File tmpFile = getFileFromId(tempCacheFolder, id);
if (!tmpFile.exists()) {
throw new FileTransferException(
"Could not move temp file to cache folder. The file does not exist in the temp folder. FileId: "
+ id.getIdentifier());
}
if (cacheFile.exists()) {
throw new FileTransferException(
"Could not move temp file to cache folder. The file already exists in the cache folder"
+ id.getIdentifier());
}
if (!tmpFile.renameTo(cacheFile)) {
throw new FileTransferException("Could not move temp file to cache folder. The move operation failed");
}
return cacheFile;
}
/**
* Builds a file from a cache folder and a file identifier.
*
* @param folder
* the base folder in which the file is
* @param id
* the file identifier of that file
* @return the assembled file
*/
private File getFileFromId(File folder, FileIdentifier id) {
return new File(folder, id.getIdentifier());
}
/**
* Creates all necessary directories (cache and temp).
*/
private void mkdirs() {
cacheFolder.mkdirs();
tempCacheFolder.mkdirs();
}
/**
* Removes a file from the cache. Does nothing if no such file is cached.
* Returns true if the file was successfully deleted from cache, otherwise
* false.
*
* @param fileIdentifier
* the identifier of the file to be removed
* @return true iff the file was deleted successfully
*/
public boolean removeCachedFile(FileIdentifier fileIdentifier) {
File toRemove = getFileFromId(cacheFolder, fileIdentifier);
if (toRemove.exists()) {
return toRemove.delete();
}
return false;
}
}