blob: ca3ae5857de341f1ec974fb6afea17fd0f6baedf [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2010 IBM Corporation 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:
* IBM Corporation - Initial API and implementation
* Roland Schulz, University of Tennessee
*******************************************************************************/
package org.eclipse.ptp.remote.remotetools.core;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.filesystem.provider.FileInfo;
import org.eclipse.core.filesystem.provider.FileStore;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.osgi.util.NLS;
import org.eclipse.ptp.remote.remotetools.core.messages.Messages;
import org.eclipse.ptp.remotetools.core.IRemoteExecutionManager;
import org.eclipse.ptp.remotetools.core.IRemoteFileTools;
import org.eclipse.ptp.remotetools.core.IRemoteItem;
import org.eclipse.ptp.remotetools.exception.CancelException;
import org.eclipse.ptp.remotetools.exception.RemoteOperationException;
public class RemoteToolsFileStore extends FileStore {
private static Map<String, RemoteToolsFileStore> instanceMap = new HashMap<String, RemoteToolsFileStore>();
/**
* Public factory method for obtaining RemoteToolsFileStore instances.
*
* @param uri
* URI to get a fileStore for
* @return an RemoteToolsFileStore instance for the URI.
*/
public static RemoteToolsFileStore getInstance(URI uri) {
synchronized (instanceMap) {
RemoteToolsFileStore store = instanceMap.get(uri.toString());
if (store == null) {
String name = RemoteToolsFileSystem.getConnectionNameFor(uri);
if (name != null) {
String path = uri.getPath();
store = new RemoteToolsFileStore(name, path);
instanceMap.put(uri.toString(), store);
}
}
return store;
}
}
private final String fConnectionName;
private final IPath fRemotePath;
private IRemoteItem fRemoteItem = null;
public RemoteToolsFileStore(String connName, String path) {
fConnectionName = connName;
fRemotePath = new Path(path);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.filesystem.provider.FileStore#childInfos(int,
* org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
public IFileInfo[] childInfos(int options, IProgressMonitor monitor) throws CoreException {
IRemoteItem[] items;
try {
items = getExecutionManager(monitor).getRemoteFileTools().listItems(fRemotePath.toString(), monitor);
} catch (Exception e) {
throw new CoreException(new Status(IStatus.ERROR, RemoteToolsAdapterCorePlugin.getDefault().getBundle()
.getSymbolicName(), EFS.ERROR_INTERNAL, e.getMessage(), null));
}
IFileInfo[] result = new FileInfo[items.length];
for (int i = 0; i < result.length; i++) {
result[i] = convertRemoteItemToFileInfo(items[i], getNameFromPath(new Path(items[i].getPath())));
}
return result;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.filesystem.provider.FileStore#childNames(int,
* org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
public String[] childNames(int options, IProgressMonitor monitor) throws CoreException {
if (monitor == null) {
monitor = new NullProgressMonitor();
}
// System.out.println("CHILDNAMES: " + fRemotePath.toString()); //$NON-NLS-1$
IRemoteItem[] items;
try {
items = getExecutionManager(monitor).getRemoteFileTools().listItems(fRemotePath.toString(), monitor);
} catch (Exception e) {
throw new CoreException(new Status(IStatus.ERROR, RemoteToolsAdapterCorePlugin.getDefault().getBundle()
.getSymbolicName(), EFS.ERROR_INTERNAL, e.getMessage(), null));
}
String[] names = new String[items.length];
for (int i = 0; i < items.length; i++) {
IPath path = new Path(items[i].getPath());
names[i] = path.lastSegment(); // should this be
// getNameFromPath(path)?
}
return names;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.filesystem.provider.FileStore#delete(int,
* org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
public void delete(int options, IProgressMonitor monitor) throws CoreException {
if (monitor == null) {
monitor = new NullProgressMonitor();
}
IRemoteItem item = getRemoteItem(monitor);
// System.out.println("DELETE: " + fRemotePath.toString() + ", exists: " + item.exists()); //$NON-NLS-1$ //$NON-NLS-2$
if (item.exists()) {
try {
cacheRemoteItem(null);
if (item.isDirectory()) {
getExecutionManager(monitor).getRemoteFileTools().removeDirectory(fRemotePath.toString(), monitor);
} else {
getExecutionManager(monitor).getRemoteFileTools().removeFile(fRemotePath.toString(), monitor);
}
} catch (Exception e) {
throw new CoreException(new Status(IStatus.ERROR, RemoteToolsAdapterCorePlugin.getDefault().getBundle()
.getSymbolicName(), EFS.ERROR_INTERNAL, Messages.RemoteToolsFileStore_0, e));
}
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.filesystem.provider.FileStore#fetchInfo(int,
* org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
public IFileInfo fetchInfo(int options, IProgressMonitor monitor) throws CoreException {
if (monitor == null) {
monitor = new NullProgressMonitor();
}
// System.out.println("FETCHINFO: " + fRemotePath.toString()); //$NON-NLS-1$
IRemoteItem item = getRemoteItem(monitor);
return convertRemoteItemToFileInfo(item, getName());
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.core.filesystem.provider.FileStore#getChild(java.lang.String)
*/
@Override
public IFileStore getChild(String name) {
// System.out.println("GETCHILD: " + name); //$NON-NLS-1$
URI uri = RemoteToolsFileSystem.getURIFor(fConnectionName, fRemotePath.append(name).toString());
return RemoteToolsFileStore.getInstance(uri);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.filesystem.provider.FileStore#getName()
*/
@Override
public String getName() {
return getNameFromPath(fRemotePath);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.filesystem.provider.FileStore#getParent()
*/
@Override
public IFileStore getParent() {
// System.out.println("GETPARENT: " + fRemotePath.toString()); //$NON-NLS-1$
if (fRemotePath.isRoot()) {
return null;
}
String parentPath = fRemotePath.toString();
if (fRemotePath.segmentCount() > 0) {
parentPath = fRemotePath.removeLastSegments(1).toString();
}
return RemoteToolsFileStore.getInstance(RemoteToolsFileSystem.getURIFor(fConnectionName, parentPath));
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.filesystem.provider.FileStore#mkdir(int,
* org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
public IFileStore mkdir(int options, IProgressMonitor monitor) throws CoreException {
if (monitor == null) {
monitor = new NullProgressMonitor();
}
// System.out.println("MKDIR: " + fRemotePath.toString()); //$NON-NLS-1$
IRemoteItem item = getRemoteItem(monitor);
if (!item.exists()) {
if ((options & EFS.SHALLOW) == EFS.SHALLOW) {
IFileStore parent = getParent();
if (parent != null && !parent.fetchInfo(EFS.NONE, monitor).exists()) {
throw new CoreException(new Status(IStatus.ERROR, RemoteToolsAdapterCorePlugin.getDefault().getBundle()
.getSymbolicName(), EFS.ERROR_WRITE, Messages.RemoteToolsFileStore_1, null));
}
}
try {
getExecutionManager(monitor).getRemoteFileTools().createDirectory(fRemotePath.toString(), monitor);
cacheRemoteItem(null);
} catch (Exception e) {
throw new CoreException(new Status(IStatus.ERROR, RemoteToolsAdapterCorePlugin.getDefault().getBundle()
.getSymbolicName(), EFS.ERROR_INTERNAL, Messages.RemoteToolsFileStore_2, e));
}
} else if (!item.isDirectory()) {
throw new CoreException(new Status(IStatus.ERROR, RemoteToolsAdapterCorePlugin.getDefault().getBundle()
.getSymbolicName(), EFS.ERROR_WRONG_TYPE, Messages.RemoteToolsFileStore_13, null));
}
return this;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.filesystem.provider.FileStore#openInputStream(int,
* org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
public InputStream openInputStream(int options, IProgressMonitor monitor) throws CoreException {
if (monitor == null) {
monitor = new NullProgressMonitor();
}
// System.out.println("OPENINPUTSTREAM: " + fRemotePath.toString()); //$NON-NLS-1$
IRemoteItem item = getRemoteItem(monitor);
if (!item.exists()) {
// System.out.println("OPENINPUTSTREAM: " + Messages.RemoteToolsFileStore_14); //$NON-NLS-1$
throw new CoreException(new Status(IStatus.ERROR, RemoteToolsAdapterCorePlugin.getDefault().getBundle()
.getSymbolicName(), EFS.ERROR_READ, Messages.RemoteToolsFileStore_14, null));
}
if (item.isDirectory()) {
// System.out.println("OPENINPUTSTREAM: " + Messages.RemoteToolsFileStore_3); //$NON-NLS-1$
throw new CoreException(new Status(IStatus.ERROR, RemoteToolsAdapterCorePlugin.getDefault().getBundle()
.getSymbolicName(), EFS.ERROR_WRONG_TYPE, Messages.RemoteToolsFileStore_3, null));
}
try {
return getExecutionManager(monitor).getRemoteFileTools().getInputStream(item.getPath(), monitor);
} catch (Exception e) {
// System.out.println("OPENINPUTSTREAM: " + e.getLocalizedMessage()); //$NON-NLS-1$
throw new CoreException(new Status(IStatus.ERROR, RemoteToolsAdapterCorePlugin.getDefault().getBundle()
.getSymbolicName(), EFS.ERROR_INTERNAL, Messages.RemoteToolsFileStore_4, e));
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.filesystem.provider.FileStore#openOutputStream(int,
* org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
public OutputStream openOutputStream(int options, IProgressMonitor monitor) throws CoreException {
if (monitor == null) {
monitor = new NullProgressMonitor();
}
// System.out.println("OPENOUTPUTSTREAM: " + fRemotePath.toString()); //$NON-NLS-1$
IRemoteItem item = getRemoteItem(monitor);
if (item.isDirectory()) {
throw new CoreException(new Status(IStatus.ERROR, RemoteToolsAdapterCorePlugin.getDefault().getBundle()
.getSymbolicName(), EFS.ERROR_WRONG_TYPE, Messages.RemoteToolsFileStore_3, null));
}
try {
// Convert from EFS option constants to IFileService option
// constants
if ((options & EFS.APPEND) != 0) {
options = IRemoteFileTools.APPEND;
} else {
options = IRemoteFileTools.NONE;
}
cacheRemoteItem(null);
return getExecutionManager(monitor).getRemoteFileTools().getOutputStream(item.getPath(), options, monitor);
} catch (Exception e) {
throw new CoreException(new Status(IStatus.ERROR, RemoteToolsAdapterCorePlugin.getDefault().getBundle()
.getSymbolicName(), EFS.ERROR_INTERNAL, Messages.RemoteToolsFileStore_6, e));
}
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.core.filesystem.provider.FileStore#putInfo(org.eclipse.core
* .filesystem.IFileInfo, int, org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
public void putInfo(IFileInfo info, int options, IProgressMonitor monitor) throws CoreException {
if (monitor == null) {
monitor = new NullProgressMonitor();
}
// System.out.println("PUTINFO: " + fRemotePath.toString()); //$NON-NLS-1$
IRemoteItem item = getRemoteItem(monitor);
boolean modified = false;
if ((options & EFS.SET_ATTRIBUTES) != 0) {
boolean writeable = !info.getAttribute(EFS.ATTRIBUTE_READ_ONLY);
item.setWriteable(writeable);
boolean executable = info.getAttribute(EFS.ATTRIBUTE_EXECUTABLE);
item.setExecutable(executable);
modified = true;
}
if ((options & EFS.SET_LAST_MODIFIED) != 0) {
long modtime = info.getLastModified();
item.setModificationTime(modtime);
modified = true;
}
if (modified) {
try {
item.commitAttributes(monitor);
} catch (Exception e) {
throw new CoreException(new Status(IStatus.ERROR, RemoteToolsAdapterCorePlugin.getDefault().getBundle()
.getSymbolicName(), EFS.ERROR_INTERNAL, e.getMessage(), e));
}
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.filesystem.provider.FileStore#toURI()
*/
@Override
public URI toURI() {
return RemoteToolsFileSystem.getURIFor(fConnectionName, fRemotePath.toString());
}
private void cacheRemoteItem(IRemoteItem item) {
fRemoteItem = item;
}
/**
* Copy attributes from an IRemoteItem object into an IFileInfo object.
*
* @param item
* the IRemoteItem to convert
* @param name
* the name of the file object
* @return an IFileInfo object containing the IRemoteItem attributes
*/
private IFileInfo convertRemoteItemToFileInfo(IRemoteItem item, String name) {
FileInfo info = new FileInfo(name);
if (!item.exists()) {
info.setExists(false);
return info;
}
info.setExists(true);
info.setLastModified(item.getModificationTime());
info.setDirectory(item.isDirectory());
info.setAttribute(EFS.ATTRIBUTE_READ_ONLY, !item.isWritable());
info.setAttribute(EFS.ATTRIBUTE_EXECUTABLE, item.isExecutable());
info.setLength(item.getSize());
return info;
}
/**
* Get the remote tools execution manager associated with the connection.
* Will attempt to initialize and open the connection if necessary.
*
* @param monitor
* progress monitor
* @return remote tools execution manager
* @throws CoreException
*/
private IRemoteExecutionManager getExecutionManager(IProgressMonitor monitor) throws CoreException {
final RemoteToolsServices services = RemoteToolsServices.getInstance();
if (!services.isInitialized()) {
services.initialize();
if (!services.isInitialized()) {
throw new CoreException(new Status(IStatus.ERROR, RemoteToolsAdapterCorePlugin.getDefault().getBundle()
.getSymbolicName(), EFS.ERROR_INTERNAL, Messages.RemoteToolsFileStore_5, null));
}
}
final RemoteToolsConnectionManager connMgr = (RemoteToolsConnectionManager) services.getConnectionManager();
if (connMgr == null) {
throw new CoreException(new Status(IStatus.ERROR, RemoteToolsAdapterCorePlugin.getDefault().getBundle()
.getSymbolicName(), EFS.ERROR_INTERNAL, Messages.RemoteToolsFileStore_7, null));
}
final RemoteToolsConnection conn = (RemoteToolsConnection) connMgr.getConnection(fConnectionName);
if (conn == null) {
throw new CoreException(new Status(IStatus.ERROR, RemoteToolsAdapterCorePlugin.getDefault().getBundle()
.getSymbolicName(), EFS.ERROR_INTERNAL, NLS.bind(Messages.RemoteToolsFileStore_8, fConnectionName), null));
}
if (!conn.isOpen()) {
try {
conn.open(monitor);
} catch (Exception e) {
throw new CoreException(new Status(IStatus.ERROR, RemoteToolsAdapterCorePlugin.getDefault().getBundle()
.getSymbolicName(), EFS.ERROR_INTERNAL, e.getLocalizedMessage(), e));
}
if (monitor.isCanceled()) {
throw new CoreException(new Status(IStatus.ERROR, RemoteToolsAdapterCorePlugin.getDefault().getBundle()
.getSymbolicName(), EFS.ERROR_INTERNAL, Messages.RemoteToolsFileStore_12, null));
}
if (!conn.isOpen()) {
throw new CoreException(new Status(IStatus.ERROR, RemoteToolsAdapterCorePlugin.getDefault().getBundle()
.getSymbolicName(), EFS.ERROR_INTERNAL, NLS.bind(Messages.RemoteToolsFileStore_10, fConnectionName), null));
}
}
try {
return conn.createExecutionManager();
} catch (org.eclipse.ptp.remotetools.exception.RemoteConnectionException e) {
throw new CoreException(new Status(IStatus.ERROR, RemoteToolsAdapterCorePlugin.getDefault().getBundle()
.getSymbolicName(), EFS.ERROR_INTERNAL, e.getLocalizedMessage(), e));
}
}
/**
* Utility routing to get the file name from an absolute path.
*
* @param path
* path to extract file name from
* @return last segment of path, or the full path if it is root
*/
private String getNameFromPath(IPath path) {
if (path.isRoot()) {
return path.toString();
}
return path.lastSegment();
}
/**
* Gets the remote item associated with this file store. Will open the
* connection if necessary.
*
* @param monitor
* progress monitor
* @return remote item
* @throws CoreException
*/
private IRemoteItem getRemoteItem(IProgressMonitor monitor) throws CoreException {
final IRemoteExecutionManager mgr = getExecutionManager(monitor);
if (fRemoteItem == null) {
try {
IRemoteFileTools tools = mgr.getRemoteFileTools();
cacheRemoteItem(tools.getItem(fRemotePath.toString()));
} catch (org.eclipse.ptp.remotetools.exception.RemoteConnectionException e) {
throw new CoreException(new Status(IStatus.ERROR, RemoteToolsAdapterCorePlugin.getDefault().getBundle()
.getSymbolicName(), EFS.ERROR_INTERNAL, e.getLocalizedMessage(), e));
} catch (RemoteOperationException e) {
throw new CoreException(new Status(IStatus.ERROR, RemoteToolsAdapterCorePlugin.getDefault().getBundle()
.getSymbolicName(), EFS.ERROR_INTERNAL, e.getLocalizedMessage(), e));
} catch (CancelException e) {
throw new CoreException(new Status(IStatus.ERROR, RemoteToolsAdapterCorePlugin.getDefault().getBundle()
.getSymbolicName(), EFS.ERROR_INTERNAL, e.getLocalizedMessage(), e));
}
}
/*
* Always need to refresh attributes in case file has been modified
* since the last call.
*/
try {
fRemoteItem.refreshAttributes(monitor);
} catch (Exception e) {
e.printStackTrace();
throw new CoreException(new Status(IStatus.ERROR, RemoteToolsAdapterCorePlugin.getDefault().getBundle()
.getSymbolicName(), EFS.ERROR_INTERNAL, e.getLocalizedMessage(), e));
}
return fRemoteItem;
}
}