diff options
Diffstat (limited to 'target_explorer/plugins/org.eclipse.tcf.te.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/utils/CacheManager.java')
-rw-r--r-- | target_explorer/plugins/org.eclipse.tcf.te.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/utils/CacheManager.java | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/utils/CacheManager.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/utils/CacheManager.java new file mode 100644 index 000000000..c5749959f --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/utils/CacheManager.java @@ -0,0 +1,204 @@ +/******************************************************************************* + * Copyright (c) 2011, 2013 Wind River Systems, Inc. and others. All rights reserved. + * This program and the accompanying materials are made available under the terms + * of the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + * William Chen (Wind River)- [345387] Open the remote files with a proper editor + * William Chen (Wind River)- [345552] Edit the remote files with a proper editor + *******************************************************************************/ +package org.eclipse.tcf.te.tcf.filesystem.core.internal.utils; + +import java.io.File; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.ISafeRunnable; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.SafeRunner; +import org.eclipse.osgi.util.NLS; +import org.eclipse.tcf.te.tcf.filesystem.core.activator.CorePlugin; +import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode; +import org.eclipse.tcf.te.tcf.filesystem.core.nls.Messages; + +/** + * The local file system cache used to manage the temporary files downloaded from a remote file + * system. + */ +public class CacheManager { + public static final char PATH_ESCAPE_CHAR = '$'; + + /** + * Get the local path of a node's cached file. + * <p> + * The preferred location is within the plugin's state location, in example + * <code><state location>agent_<hashcode_of_peerId>/remote/path/to/the/file...</code>. + * <p> + * If the plug-in is loaded in a RCP workspace-less environment, the fall back strategy is to + * use the users home directory. + * + * @param node The file/folder node. + * @return The local path of the node's cached file. + */ + public static IPath getCachePath(FSTreeNode node) { + File location = getCacheRoot(); + String agentId = node.peerNode.getPeerId(); + // Use Math.abs to avoid negative hash value. + String agent = agentId.replace(':', PATH_ESCAPE_CHAR); + IPath agentDir = new Path(location.getAbsolutePath()).append(agent); + File agentDirFile = agentDir.toFile(); + mkdirChecked(agentDirFile); + return appendNodePath(agentDir, node); + } + + /** + * Check and make a directory if it does not exist. Record the failure message if making fails. + * + * @param file The file to be deleted. + */ + static void mkdirChecked(final File dir) { + if (!dir.exists()) { + SafeRunner.run(new ISafeRunnable() { + @Override + public void run() throws Exception { + if (!dir.mkdir()) { + throw new Exception(NLS.bind(Messages.CacheManager_MkdirFailed, dir + .getAbsolutePath())); + } + } + + @Override + public void handleException(Throwable exception) { + // Ignore on purpose + } + }); + } + } + + /** + * Check if the file exists and delete if it does. Record the failure message if deleting fails. + * + * @param file The file to be deleted. + */ + static void deleteFileChecked(final File file) { + if (file.exists()) { + SafeRunner.run(new ISafeRunnable() { + @Override + public void run() throws Exception { + if (!file.delete()) { + throw new Exception(NLS.bind(Messages.Operation_DeletingFileFailed, file + .getAbsolutePath())); + } + } + + @Override + public void handleException(Throwable exception) { + // Ignore on purpose + } + }); + } + } + + /** + * Check if the file exists and set its read-only attribute if it does. Record the failure + * message if it fails. + * + * @param file The file to be set. + */ + static void setReadOnlyChecked(final File file) { + if (file.exists()) { + SafeRunner.run(new ISafeRunnable() { + @Override + public void run() throws Exception { + if (!file.setReadOnly()) { + throw new Exception(NLS.bind(Messages.OpStreamOp_SetReadOnlyFailed, file + .getAbsolutePath())); + } + } + + @Override + public void handleException(Throwable exception) { + // Ignore on purpose + } + }); + } + } + + /** + * Get the local file of the specified node. + * + * <p> + * The preferred location is within the plugin's state location, in example + * <code><state location>agent_<hashcode_of_peerId>/remote/path/to/the/file...</code>. + * <p> + * If the plug-in is loaded in a RCP workspace-less environment, the fall back strategy is to + * use the users home directory. + * + * @param node The file/folder node. + * @return The file object of the node's local cache. + */ + public static File getCacheFile(FSTreeNode node) { + return getCachePath(node).toFile(); + } + + /** + * Get the cache file system's root directory on the local host's file system. + * + * @return The root folder's location of the cache file system. + */ + public static File getCacheRoot() { + File location; + try { + location = CorePlugin.getDefault().getStateLocation().toFile(); + } + catch (IllegalStateException e) { + // An RCP workspace-less environment (-data @none) + location = new File(System.getProperty("user.home"), ".tcf"); //$NON-NLS-1$ //$NON-NLS-2$ + location = new File(location, "fs"); //$NON-NLS-1$ + } + + // Create the location if it not exist + mkdirChecked(location); + return location; + } + + /** + * Append the path with the specified node's context path. + * + * @param path The path to be appended. + * @param node The file/folder node. + * @return The path to the node. + */ + private static IPath appendNodePath(IPath path, FSTreeNode node) { + if (!node.isRoot() && node.getParent() != null) { + path = appendNodePath(path, node.getParent()); + return appendPathSegment(node, path, node.name); + } + if (node.isWindowsNode()) { + String name = node.name; + name = name.substring(0, name.length() - 1); + name = name.replace(':', PATH_ESCAPE_CHAR); + return appendPathSegment(node, path, name); + } + return path; + } + + /** + * Append the path with the segment "name". Create a directory if the node is a directory which + * does not yet exist. + * + * @param node The file/folder node. + * @param path The path to appended. + * @param name The segment's name. + * @return The path with the segment "name" appended. + */ + private static IPath appendPathSegment(FSTreeNode node, IPath path, String name) { + IPath newPath = path.append(name); + File newFile = newPath.toFile(); + if (node.isDirectory()) { + mkdirChecked(newFile); + } + return newPath; + } +} |