| /******************************************************************************* |
| * 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.internal.proxy.core.messages.Messages; |
| import org.eclipse.remote.proxy.protocol.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(Messages.ProxyFileStore_0, fURI)); |
| } |
| |
| try { |
| IRemoteConnection connection = connectionType.getConnection(fURI); |
| if (connection == null) { |
| throw new RemoteConnectionException(NLS.bind(Messages.ProxyFileStore_1, fURI)); |
| } |
| if (!connection.isOpen()) { |
| connection.open(monitor); |
| if (!connection.isOpen()) { |
| throw new RemoteConnectionException(Messages.ProxyFileStore_2); |
| } |
| } |
| return connection.getService(ProxyConnection.class); |
| } catch (CoreException e) { |
| throw new RemoteConnectionException(e); |
| } |
| } |
| |
| @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.getResult(subMon.newChild(9)); |
| } catch (ProxyException e) { |
| throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), e.getMessage())); |
| } |
| } |
| |
| @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; |
| } |
| |
| @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.getResult(subMon.newChild(10)); |
| } catch (ProxyException e) { |
| throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), e.getMessage())); |
| } |
| } |
| subMon.setWorkRemaining(0); |
| } |
| |
| @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.getResult(subMon.newChild(9)); |
| } catch (ProxyException e) { |
| throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), e.getMessage())); |
| } |
| } |
| |
| @Override |
| public IFileStore getChild(String name) { |
| URI uri = ProxyFileSystem.getURIFor(ProxyFileSystem.getConnectionNameFor(fURI), fRemotePath.append(name).toString()); |
| return getInstance(uri); |
| } |
| |
| @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(); |
| } |
| |
| @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)); |
| } |
| |
| @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(Messages.ProxyFileStore_3, fRemotePath.toString()), null)); |
| } |
| if (subMon.isCanceled()) { |
| return this; |
| } |
| } |
| subMon.setWorkRemaining(10); |
| |
| try { |
| MkdirCommand command = new MkdirCommand(connection, options, fRemotePath.toString()); |
| command.getResult(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(Messages.ProxyFileStore_4, fRemotePath.toString()), null)); |
| } |
| if (!info.isDirectory()) { |
| throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), EFS.ERROR_WRONG_TYPE, |
| NLS.bind(Messages.ProxyFileStore_5, fRemotePath.toString()), null)); |
| } |
| } |
| } |
| |
| return this; |
| } |
| |
| @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(Messages.ProxyFileStore_6, fRemotePath.toString()), null)); |
| } |
| if (info.isDirectory()) { |
| throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), EFS.ERROR_WRONG_TYPE, |
| NLS.bind(Messages.ProxyFileStore_7, fRemotePath.toString()), null)); |
| } |
| GetInputStreamCommand command = new GetInputStreamCommand(connection, options, fRemotePath.toString()); |
| try { |
| return command.getResult(subMon.newChild(10)); |
| } catch (ProxyException e) { |
| throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), e.getMessage())); |
| } |
| } |
| return null; |
| } |
| |
| @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(Messages.ProxyFileStore_7, fRemotePath.toString()), null)); |
| } |
| GetOutputStreamCommand command = new GetOutputStreamCommand(connection, options, fRemotePath.toString()); |
| try { |
| return command.getResult(subMon.newChild(10)); |
| } catch (ProxyException e) { |
| throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), e.getMessage())); |
| } |
| } |
| return null; |
| } |
| |
| @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.getResult(subMon.newChild(9)); |
| } catch (ProxyException e) { |
| throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), e.getMessage())); |
| } |
| } |
| |
| @Override |
| public URI toURI() { |
| return fURI; |
| } |
| } |