blob: f41aae9fdba351313969e0bc45b31391b086ba3e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.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.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.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.osgi.util.NLS;
import org.eclipse.remote.core.IRemoteConnection;
import org.eclipse.remote.core.IRemoteConnectionType;
import org.eclipse.remote.core.IRemoteServicesManager;
import org.eclipse.remote.core.RemoteServicesUtils;
import org.eclipse.remote.core.exception.RemoteConnectionException;
import org.eclipse.remote.internal.proxy.core.commands.ChildInfosCommand;
import org.eclipse.remote.internal.proxy.core.commands.DeleteCommand;
import org.eclipse.remote.internal.proxy.core.commands.FetchInfoCommand;
import org.eclipse.remote.internal.proxy.core.commands.GetInputStreamCommand;
import org.eclipse.remote.internal.proxy.core.commands.GetOutputStreamCommand;
import org.eclipse.remote.internal.proxy.core.commands.MkdirCommand;
import org.eclipse.remote.internal.proxy.core.commands.PutInfoCommand;
import org.eclipse.remote.proxy.core.exceptions.ProxyException;
public class ProxyFileStore extends FileStore {
/**
* Public factory method for obtaining ProxyFileStore instances.
*
* @param uri
* URI to get a fileStore for
* @return an ProxyFileStore instance for the URI.
*/
public static ProxyFileStore getInstance(URI uri) {
synchronized (instanceMap) {
ProxyFileStore store = instanceMap.get(uri.toString());
if (store == null) {
store = new ProxyFileStore(uri);
instanceMap.put(uri.toString(), store);
}
return store;
}
}
private static Map<String, ProxyFileStore> instanceMap = new HashMap<String, ProxyFileStore>();
private final IPath fRemotePath;
private final URI fURI;
private ProxyFileStore(URI uri) {
fURI = uri;
fRemotePath = RemoteServicesUtils.posixPath(uri.getPath());
}
private ProxyConnection checkConnection(IProgressMonitor monitor) throws RemoteConnectionException {
IRemoteServicesManager manager = Activator.getService(IRemoteServicesManager.class);
IRemoteConnectionType connectionType = manager.getConnectionType(fURI);
if (connectionType == null) {
throw new RemoteConnectionException(NLS.bind("No remote services found for URI {0}", fURI));
}
try {
IRemoteConnection connection = connectionType.getConnection(fURI);
if (connection == null) {
throw new RemoteConnectionException(NLS.bind("Invalid connection for URI {0}", fURI));
}
if (!connection.isOpen()) {
connection.open(monitor);
if (!connection.isOpen()) {
throw new RemoteConnectionException("Connection is not open");
}
}
return connection.getService(ProxyConnection.class);
} catch (CoreException e) {
throw new RemoteConnectionException(e);
}
}
/*
* (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 {
SubMonitor subMon = SubMonitor.convert(monitor, 10);
ProxyConnection connection = checkConnection(subMon.newChild(1));
ChildInfosCommand command = new ChildInfosCommand(connection, fRemotePath.toString());
try {
return command.exec(subMon.newChild(9));
} catch (ProxyException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), e.getMessage()));
}
}
/*
* (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 {
SubMonitor subMon = SubMonitor.convert(monitor, 10);
IFileInfo[] infos = childInfos(options, subMon.newChild(10));
String[] names = new String[infos.length];
for (int i = 0; i < infos.length; i++) {
names[i] = infos[i].getName();
}
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 {
SubMonitor subMon = SubMonitor.convert(monitor, 20);
ProxyConnection connection = checkConnection(subMon.newChild(1));
IFileInfo info = fetchInfo(EFS.NONE, subMon.newChild(9));
if (!subMon.isCanceled() && info.exists()) {
DeleteCommand command = new DeleteCommand(connection, options, fRemotePath.toString());
try {
command.exec(subMon.newChild(10));
} catch (ProxyException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), e.getMessage()));
}
}
subMon.setWorkRemaining(0);
}
/*
* (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 {
SubMonitor subMon = SubMonitor.convert(monitor, 10);
ProxyConnection connection = checkConnection(subMon.newChild(1));
FetchInfoCommand command = new FetchInfoCommand(connection, fRemotePath.toString());
try {
return command.exec(subMon.newChild(9));
} catch (ProxyException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), e.getMessage()));
}
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.core.filesystem.provider.FileStore#getChild(java.lang.String)
*/
@Override
public IFileStore getChild(String name) {
URI uri = ProxyFileSystem.getURIFor(ProxyFileSystem.getConnectionNameFor(fURI), fRemotePath.append(name).toString());
return getInstance(uri);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.filesystem.provider.FileStore#getName()
*/
@Override
public String getName() {
return getNameFromPath(fRemotePath);
}
/**
* 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();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.filesystem.provider.FileStore#getParent()
*/
@Override
public IFileStore getParent() {
if (fRemotePath.isRoot()) {
return null;
}
String parentPath = fRemotePath.toString();
if (fRemotePath.segmentCount() > 0) {
parentPath = fRemotePath.removeLastSegments(1).toString();
}
return getInstance(ProxyFileSystem.getURIFor(ProxyFileSystem.getConnectionNameFor(fURI), 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 {
SubMonitor subMon = SubMonitor.convert(monitor, 16);
ProxyConnection connection = checkConnection(subMon.newChild(1));
if ((options & EFS.SHALLOW) == EFS.SHALLOW) {
IFileStore parent = getParent();
if (parent != null && !parent.fetchInfo(EFS.NONE, subMon.newChild(5)).exists()) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), EFS.ERROR_WRITE,
NLS.bind("The parent of directory {0} does not exist", fRemotePath.toString()), null));
}
if (subMon.isCanceled()) {
return this;
}
}
subMon.setWorkRemaining(10);
try {
MkdirCommand command = new MkdirCommand(connection, options, fRemotePath.toString());
command.exec(subMon.newChild(5));
} catch (Exception e) {
// Ignore any exceptions
}
if (!subMon.isCanceled()) {
/*
* Check if the result exists and is a directory, throw an exception if neither.
*/
IFileInfo info = fetchInfo(EFS.NONE, subMon.newChild(5));
if (!subMon.isCanceled()) {
if (!info.exists()) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), EFS.ERROR_WRITE,
NLS.bind("The directory {0} could not be created", fRemotePath.toString()), null));
}
if (!info.isDirectory()) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), EFS.ERROR_WRONG_TYPE,
NLS.bind("A file of name {0} already exists", fRemotePath.toString()), 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 {
SubMonitor subMon = SubMonitor.convert(monitor, 20);
ProxyConnection connection = checkConnection(subMon.newChild(1));
IFileInfo info = fetchInfo(EFS.NONE, subMon.newChild(9));
if (!subMon.isCanceled()) {
if (!info.exists()) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), EFS.ERROR_READ,
NLS.bind("File {0} does not exist", fRemotePath.toString()), null));
}
if (info.isDirectory()) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), EFS.ERROR_WRONG_TYPE,
NLS.bind("{0} is a directory", fRemotePath.toString()), null));
}
GetInputStreamCommand command = new GetInputStreamCommand(connection, options, fRemotePath.toString());
try {
return command.exec(subMon.newChild(10));
} catch (ProxyException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), e.getMessage()));
}
}
return null;
}
/*
* (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 {
SubMonitor subMon = SubMonitor.convert(monitor, 20);
ProxyConnection connection = checkConnection(subMon.newChild(1));
IFileInfo info = fetchInfo(EFS.NONE, subMon.newChild(9));
if (!subMon.isCanceled()) {
if (info.isDirectory()) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), EFS.ERROR_WRONG_TYPE,
NLS.bind("{0} is a directory", fRemotePath.toString()), null));
}
GetOutputStreamCommand command = new GetOutputStreamCommand(connection, options, fRemotePath.toString());
try {
return command.exec(subMon.newChild(10));
} catch (ProxyException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), e.getMessage()));
}
}
return null;
}
/*
* (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 {
SubMonitor subMon = SubMonitor.convert(monitor, 10);
ProxyConnection connection = checkConnection(subMon.newChild(1));
PutInfoCommand command = new PutInfoCommand(connection, info, options, fRemotePath.toString());
try {
command.exec(subMon.newChild(9));
} catch (ProxyException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), e.getMessage()));
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.filesystem.provider.FileStore#toURI()
*/
@Override
public URI toURI() {
return fURI;
}
}