Copyright (c) 2005, 2015 IBM Corporation and others. This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which accompanies this distribution, and is available at https://www.eclipse.org/legal/epl-2.0/ SPDX-License-Identifier: EPL-2.0 Contributors: IBM Corporation - initial API and implementation James Blackburn (Broadcom Corp.) - ongoing development
/******************************************************************************* * Copyright (c) 2005, 2015 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation * James Blackburn (Broadcom Corp.) - ongoing development *******************************************************************************/
package org.eclipse.core.filesystem.provider; import java.io.*; import java.net.URI; import org.eclipse.core.filesystem.*; import org.eclipse.core.internal.filesystem.*; import org.eclipse.core.runtime.*; import org.eclipse.osgi.util.NLS;
The abstract superclass of all IFileStore implementations. All file stores must subclass this base class, implementing all abstract methods according to their specification in the IFileStore API.

Clients may subclass this class.

Since:org.eclipse.core.filesystem 1.0
/** * The abstract superclass of all {@link IFileStore} implementations. All * file stores must subclass this base class, implementing all abstract * methods according to their specification in the {@link IFileStore} API. * <p> * Clients may subclass this class. * </p> * @since org.eclipse.core.filesystem 1.0 */
public abstract class FileStore extends PlatformObject implements IFileStore {
A file info array of size zero that can be used as a return value for methods that return IFileInfo[] to avoid creating garbage objects.
/** * A file info array of size zero that can be used as a return value for methods * that return IFileInfo[] to avoid creating garbage objects. */
protected static final IFileInfo[] EMPTY_FILE_INFO_ARRAY = {};
A string array of size zero that can be used as a return value for methods that return String[] to avoid creating garbage objects.
/** * A string array of size zero that can be used as a return value for methods * that return String[] to avoid creating garbage objects. */
protected static final String[] EMPTY_STRING_ARRAY = {};
Transfers the contents of an input stream to an output stream, using a large buffer.
Params:
  • source – The input stream to transfer
  • destination – The destination stream of the transfer
  • length – the size of the file or -1 if not known
  • path – A path representing the data being transferred for use in error messages.
  • monitor – A progress monitor
Throws:
/** * Transfers the contents of an input stream to an output stream, using a large * buffer. * * @param source The input stream to transfer * @param destination The destination stream of the transfer * @param length the size of the file or -1 if not known * @param path A path representing the data being transferred for use in error * messages. * @param monitor A progress monitor * @throws CoreException */
private static final void transferStreams(InputStream source, OutputStream destination, long length, String path, IProgressMonitor monitor) throws CoreException { byte[] buffer = new byte[8192]; SubMonitor subMonitor = SubMonitor.convert(monitor, length >= 0 ? 1 + (int) (length / buffer.length) : 1000); try { while (true) { int bytesRead = -1; try { bytesRead = source.read(buffer); } catch (IOException e) { String msg = NLS.bind(Messages.failedReadDuringWrite, path); Policy.error(EFS.ERROR_READ, msg, e); } try { if (bytesRead == -1) { destination.close(); break; } destination.write(buffer, 0, bytesRead); } catch (IOException e) { String msg = NLS.bind(Messages.couldNotWrite, path); Policy.error(EFS.ERROR_WRITE, msg, e); } subMonitor.worked(1); } } finally { Policy.safeClose(source); Policy.safeClose(destination); } }
The default implementation of IFileStore.childInfos(int, IProgressMonitor). Subclasses should override this method where a more efficient implementation is possible. This default implementation calls fetchInfo() on each child, which will result in a file system call for each child.
/** * The default implementation of {@link IFileStore#childInfos(int, IProgressMonitor)}. * Subclasses should override this method where a more efficient implementation * is possible. This default implementation calls {@link #fetchInfo()} on each * child, which will result in a file system call for each child. */
@Override public IFileInfo[] childInfos(int options, IProgressMonitor monitor) throws CoreException { IFileStore[] childStores = childStores(options, monitor); IFileInfo[] childInfos = new IFileInfo[childStores.length]; for (int i = 0; i < childStores.length; i++) { childInfos[i] = childStores[i].fetchInfo(); } return childInfos; } @Override public abstract String[] childNames(int options, IProgressMonitor monitor) throws CoreException;
The default implementation of IFileStore.childStores(int, IProgressMonitor). Subclasses may override.
/** * The default implementation of {@link IFileStore#childStores(int, IProgressMonitor)}. * Subclasses may override. */
@Override public IFileStore[] childStores(int options, IProgressMonitor monitor) throws CoreException { String[] children = childNames(options, monitor); IFileStore[] wrapped = new IFileStore[children.length]; for (int i = 0; i < wrapped.length; i++) wrapped[i] = getChild(children[i]); return wrapped; }
The default implementation of IFileStore.copy(IFileStore, int, IProgressMonitor). This implementation performs a copy by using other primitive methods. Subclasses may override this method.
/** * The default implementation of {@link IFileStore#copy(IFileStore, int, IProgressMonitor)}. * This implementation performs a copy by using other primitive methods. * Subclasses may override this method. */
@Override public void copy(IFileStore destination, int options, IProgressMonitor monitor) throws CoreException { final IFileInfo sourceInfo = fetchInfo(EFS.NONE, null); if (sourceInfo.isDirectory()) { copyDirectory(sourceInfo, destination, options, monitor); } else { copyFile(sourceInfo, destination, options, monitor); } }
Recursively copies a directory as specified by IFileStore.copy(IFileStore, int, IProgressMonitor).
Params:
  • sourceInfo – The current file information for the source of the move
  • destination – The destination of the copy.
  • options – bit-wise or of option flag constants ( EFS.OVERWRITE or EFS.SHALLOW).
  • monitor – a progress monitor, or null if progress reporting and cancellation are not desired
Throws:
  • CoreException – if this method fails. Reasons include:
    • This store does not exist.
    • A file of the same name already exists at the copy destination.
/** * Recursively copies a directory as specified by * {@link IFileStore#copy(IFileStore, int, IProgressMonitor)}. * * @param sourceInfo The current file information for the source of the move * @param destination The destination of the copy. * @param options bit-wise or of option flag constants ( * {@link EFS#OVERWRITE} or {@link EFS#SHALLOW}). * @param monitor a progress monitor, or <code>null</code> if progress * reporting and cancellation are not desired * @exception CoreException if this method fails. Reasons include: * <ul> * <li> This store does not exist.</li> * <li> A file of the same name already exists at the copy destination.</li> * </ul> */
protected void copyDirectory(IFileInfo sourceInfo, IFileStore destination, int options, IProgressMonitor monitor) throws CoreException { IFileStore[] children = null; int opWork = 1; if ((options & EFS.SHALLOW) == 0) { children = childStores(EFS.NONE, null); opWork += children.length; } SubMonitor subMonitor = SubMonitor.convert(monitor, opWork); subMonitor.subTask(NLS.bind(Messages.copying, toString())); // create directory destination.mkdir(EFS.NONE, subMonitor.newChild(1)); // copy attributes transferAttributes(sourceInfo, destination); if (children == null) return; // copy children for (IFileStore c : children) { c.copy(destination.getChild(c.getName()), options, subMonitor.newChild(1)); } }
Params:
  • sourceInfo – The current file information for the source of the move
  • destination – The destination of the copy.
  • options – bit-wise or of option flag constants ( EFS.OVERWRITE or EFS.SHALLOW).
  • monitor – a progress monitor, or null if progress reporting and cancellation are not desired
Throws:
  • CoreException – if this method fails. Reasons include:
    • This store does not exist.
    • The OVERWRITE flag is not specified and a file of the same name already exists at the copy destination.
    • A directory of the same name already exists at the copy destination.
/** * Copies a file as specified by * {@link IFileStore#copy(IFileStore, int, IProgressMonitor)}. * @param sourceInfo The current file information for the source of the move * @param destination The destination of the copy. * @param options bit-wise or of option flag constants ( * {@link EFS#OVERWRITE} or {@link EFS#SHALLOW}). * @param monitor a progress monitor, or <code>null</code> if progress * reporting and cancellation are not desired * @exception CoreException if this method fails. Reasons include: * <ul> * <li> This store does not exist.</li> * <li> The <code>OVERWRITE</code> flag is not specified and a file of the * same name already exists at the copy destination.</li> * <li> A directory of the same name already exists at the copy destination.</li> * </ul> */
protected void copyFile(IFileInfo sourceInfo, IFileStore destination, int options, IProgressMonitor monitor) throws CoreException { if ((options & EFS.OVERWRITE) == 0 && destination.fetchInfo().exists()) Policy.error(EFS.ERROR_EXISTS, NLS.bind(Messages.fileExists, destination)); long length = sourceInfo.getLength(); String sourcePath = toString(); SubMonitor subMonitor = SubMonitor.convert(monitor, NLS.bind(Messages.copying, sourcePath), 100); InputStream in = null; OutputStream out = null; try { in = openInputStream(EFS.NONE, subMonitor.newChild(1)); out = destination.openOutputStream(EFS.NONE, subMonitor.newChild(1)); transferStreams(in, out, length, sourcePath, subMonitor.newChild(98)); transferAttributes(sourceInfo, destination); } catch (CoreException e) { Policy.safeClose(in); Policy.safeClose(out); //if we failed to write, try to cleanup the half written file if (!destination.fetchInfo(0, null).exists()) destination.delete(EFS.NONE, null); throw e; } }
The default implementation of IFileStore.delete(int, IProgressMonitor). This implementation always throws an exception indicating that deletion is not supported by this file system. This method should be overridden for all file systems on which deletion is supported.
Params:
  • options – bit-wise or of option flag constants
  • monitor – a progress monitor, or null if progress reporting and cancellation are not desired
/** * The default implementation of {@link IFileStore#delete(int, IProgressMonitor)}. * This implementation always throws an exception indicating that deletion * is not supported by this file system. This method should be overridden * for all file systems on which deletion is supported. * * @param options bit-wise or of option flag constants * @param monitor a progress monitor, or <code>null</code> if progress * reporting and cancellation are not desired */
@Override public void delete(int options, IProgressMonitor monitor) throws CoreException { Policy.error(EFS.ERROR_DELETE, NLS.bind(Messages.noImplDelete, toString())); }
This implementation of Object.equals(Object) defines equality based on the file store's URI. Subclasses should override this method to return true if and only if the two file stores represent the same resource in the backing file system. Issues to watch out for include whether the file system is case-sensitive, and whether trailing slashes are considered significant. Subclasses that override this method should also override hashCode().
Params:
  • obj – The object to compare with the receiver for equality
Returns:true if this object is equal to the provided object, and false otherwise.
Since:org.eclipse.core.filesystem 1.1
/** * This implementation of {@link Object#equals(Object)} defines * equality based on the file store's URI. Subclasses should override * this method to return <code>true</code> if and only if the two file stores * represent the same resource in the backing file system. Issues to watch * out for include whether the file system is case-sensitive, and whether trailing * slashes are considered significant. Subclasses that override this method * should also override {@link #hashCode()}. * * @param obj The object to compare with the receiver for equality * @return <code>true</code> if this object is equal to the provided object, * and <code>false</code> otherwise. * @since org.eclipse.core.filesystem 1.1 */
@Override public boolean equals(Object obj) { if (this == obj) return true; if (!(obj instanceof FileStore)) return false; return toURI().equals(((FileStore) obj).toURI()); }
The default implementation of IFileStore.fetchInfo(). This implementation forwards to IFileStore.fetchInfo(int, IProgressMonitor). Subclasses may override this method.
/** * The default implementation of {@link IFileStore#fetchInfo()}. * This implementation forwards to {@link IFileStore#fetchInfo(int, IProgressMonitor)}. * Subclasses may override this method. */
@Override public IFileInfo fetchInfo() { try { return fetchInfo(EFS.NONE, null); } catch (CoreException e) { //there was an error contacting the file system, so treat it as non-existent file FileInfo result = new FileInfo(getName()); result.setExists(false); return result; } } @Override public abstract IFileInfo fetchInfo(int options, IProgressMonitor monitor) throws CoreException;
Deprecated:use getFileStore(IPath) instead
/** * @deprecated use {@link #getFileStore(IPath)} instead */
@Deprecated @Override public IFileStore getChild(IPath path) { IFileStore result = this; for (int i = 0, imax = path.segmentCount(); i < imax; i++) result = result.getChild(path.segment(i)); return result; }
The default implementation of IFileStore.getFileStore(IPath) Subclasses may override.
Since:org.eclipse.core.filesystem 1.2
/** * The default implementation of {@link IFileStore#getFileStore(IPath)} * Subclasses may override. * * @since org.eclipse.core.filesystem 1.2 */
@Override public IFileStore getFileStore(IPath path) { IFileStore result = this; String segment = null; for (int i = 0, imax = path.segmentCount(); i < imax; i++) { segment = path.segment(i); if (segment.equals(".")) //$NON-NLS-1$ continue; else if (segment.equals("..") && result.getParent() != null) //$NON-NLS-1$ result = result.getParent(); else result = result.getChild(segment); } return result; } @Override public abstract IFileStore getChild(String name);
The default implementation of IFileStore.getFileSystem(). Subclasses may override.
/** * The default implementation of {@link IFileStore#getFileSystem()}. * Subclasses may override. */
@Override public IFileSystem getFileSystem() { try { return EFS.getFileSystem(toURI().getScheme()); } catch (CoreException e) { //this will only happen if toURI() has been incorrectly implemented throw new RuntimeException(e); } } @Override public abstract String getName(); @Override public abstract IFileStore getParent();
This implementation of Object.hashCode() uses a definition of equality based on equality of the file store's URI. Subclasses that override equals(Object) should also override this method to ensure the contract of Object.hashCode() is honored.
Returns:A hash code value for this file store
Since:org.eclipse.core.filesystem 1.1
/** * This implementation of {@link Object#hashCode()} uses a definition * of equality based on equality of the file store's URI. Subclasses that * override {@link #equals(Object)} should also override this method * to ensure the contract of {@link Object#hashCode()} is honored. * * @return A hash code value for this file store * @since org.eclipse.core.filesystem 1.1 */
@Override public int hashCode() { return toURI().hashCode(); }
The default implementation of IFileStore.isParentOf(IFileStore). This implementation performs parent calculation using other primitive methods. Subclasses may override this method.
Params:
  • other – The store to test for parentage.
Returns:true if this store is a parent of the provided store, and false otherwise.
/** * The default implementation of {@link IFileStore#isParentOf(IFileStore)}. * This implementation performs parent calculation using other primitive methods. * Subclasses may override this method. * * @param other The store to test for parentage. * @return <code>true</code> if this store is a parent of the provided * store, and <code>false</code> otherwise. */
@Override public boolean isParentOf(IFileStore other) { while (true) { other = other.getParent(); if (other == null) return false; if (this.equals(other)) return true; } }
The default implementation of IFileStore.mkdir(int, IProgressMonitor). This implementation always throws an exception indicating that this file system is read only. This method should be overridden for all writable file systems.
Params:
  • options – bit-wise or of option flag constants
  • monitor – a progress monitor, or null if progress reporting and cancellation are not desired
/** * The default implementation of {@link IFileStore#mkdir(int, IProgressMonitor)}. * This implementation always throws an exception indicating that this file system * is read only. This method should be overridden for all writable file systems. * * @param options bit-wise or of option flag constants * @param monitor a progress monitor, or <code>null</code> if progress * reporting and cancellation are not desired */
@Override public IFileStore mkdir(int options, IProgressMonitor monitor) throws CoreException { Policy.error(EFS.ERROR_WRITE, NLS.bind(Messages.noImplWrite, toString())); return null;//can't get here }
The default implementation of IFileStore.move(IFileStore, int, IProgressMonitor). This implementation performs a move by using other primitive methods. Subclasses may override this method.
/** * The default implementation of {@link IFileStore#move(IFileStore, int, IProgressMonitor)}. * This implementation performs a move by using other primitive methods. * Subclasses may override this method. */
@Override public void move(IFileStore destination, int options, IProgressMonitor monitor) throws CoreException { try { SubMonitor subMonitor = SubMonitor.convert(monitor, NLS.bind(Messages.moving, destination.toString()), 100); copy(destination, options & EFS.OVERWRITE, subMonitor.newChild(70)); delete(EFS.NONE, subMonitor.newChild(30)); } catch (CoreException e) { //throw new error to indicate failure occurred during a move String message = NLS.bind(Messages.couldNotMove, toString()); Policy.error(EFS.ERROR_WRITE, message, e); } } @Override public abstract InputStream openInputStream(int options, IProgressMonitor monitor) throws CoreException;
The default implementation of IFileStore.openOutputStream(int, IProgressMonitor). This implementation always throws an exception indicating that this file system is read only. This method should be overridden for all writable file systems.

Implementations of this method are responsible for ensuring that the exact sequence of bytes written to the output stream are returned on a subsequent call to openInputStream(int, IProgressMonitor), unless there have been intervening modifications to the file in the file system. For example, the implementation of this method must not perform conversion of line terminator characters on text data in the stream.

Params:
  • options – bit-wise or of option flag constants
  • monitor – a progress monitor, or null if progress reporting and cancellation are not desired
/** * The default implementation of {@link IFileStore#openOutputStream(int, IProgressMonitor)}. * This implementation always throws an exception indicating that this file system * is read only. This method should be overridden for all writable file systems. * <p> * Implementations of this method are responsible for ensuring that the exact sequence * of bytes written to the output stream are returned on a subsequent call to * {@link #openInputStream(int, IProgressMonitor)}, unless there have been * intervening modifications to the file in the file system. For example, the implementation * of this method must not perform conversion of line terminator characters on text * data in the stream. * * @param options bit-wise or of option flag constants * @param monitor a progress monitor, or <code>null</code> if progress * reporting and cancellation are not desired */
@Override public OutputStream openOutputStream(int options, IProgressMonitor monitor) throws CoreException { Policy.error(EFS.ERROR_WRITE, NLS.bind(Messages.noImplWrite, toString())); return null;//can't get here }
The default implementation of IFileStore.putInfo(IFileInfo, int, IProgressMonitor). This implementation always throws an exception indicating that this file system is read only. This method should be overridden for all writable file systems.
Params:
  • options – bit-wise or of option flag constants
  • monitor – a progress monitor, or null if progress reporting and cancellation are not desired
/** * The default implementation of {@link IFileStore#putInfo(IFileInfo, int, IProgressMonitor)}. * This implementation always throws an exception indicating that this file system * is read only. This method should be overridden for all writable file systems. * * @param options bit-wise or of option flag constants * @param monitor a progress monitor, or <code>null</code> if progress * reporting and cancellation are not desired */
@Override public void putInfo(IFileInfo info, int options, IProgressMonitor monitor) throws CoreException { Policy.error(EFS.ERROR_WRITE, NLS.bind(Messages.noImplWrite, toString())); }
The default implementation of IFileStore.toLocalFile(int, IProgressMonitor). When the EFS.CACHE option is specified, this method returns a cached copy of this store in the local file system, or null if this store does not exist.
/** * The default implementation of {@link IFileStore#toLocalFile(int, IProgressMonitor)}. * When the {@link EFS#CACHE} option is specified, this method returns * a cached copy of this store in the local file system, or <code>null</code> if * this store does not exist. */
@Override public java.io.File toLocalFile(int options, IProgressMonitor monitor) throws CoreException { //caching is the only recognized option if (options != EFS.CACHE) return null; return FileCache.getCache().cache(this, monitor); }
Default implementation of IFileStore.toString(). This default implementation returns a string equal to the one returned by #toURI().toString(). Subclasses may override to provide a more specific string representation of this store.
Returns:A string representation of this store.
/** * Default implementation of {@link IFileStore#toString()}. This default implementation * returns a string equal to the one returned by #toURI().toString(). Subclasses * may override to provide a more specific string representation of this store. * * @return A string representation of this store. */
@Override public String toString() { return toURI().toString(); } @Override public abstract URI toURI(); private void transferAttributes(IFileInfo sourceInfo, IFileStore destination) throws CoreException { int options = EFS.SET_ATTRIBUTES | EFS.SET_LAST_MODIFIED; destination.putInfo(sourceInfo, options, null); } }