/** * Copyright (C) 2001-2017 by RapidMiner and the contributors * * Complete list of developers available at our web site: * * http://rapidminer.com * * This program is free software: you can redistribute it and/or modify it under the terms of the * GNU Affero General Public License as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License along with this program. * If not, see http://www.gnu.org/licenses/. */ package com.rapidminer.io.remote; import java.io.File; import java.io.FileFilter; import java.io.FilenameFilter; import java.io.IOException; /** * A class for files that are not on the local hard drive. It is used to hold information about * files that can be accessed remotely. The file names are assumed to be of the following form * "/NameOfRemoteFileSystem/Folder/Subfolder(s)/Filename", for example * "/Dropbox/Photos/Sample Album" or "/Dropbox/Photos/Sample Album/sample.png". * * <p> * Most of the methods of {@link File} cannot be used for {@link RemoteFile} since they access the * hard drive; thus they are overwritten by methods doing nothing. By default all remote files are * read-only and cannot be renamed or deleted. Usual properties as the size, the last modified time * and if the file is a directory cannot be obtained from the hard drive; hence they have to be set * to archive the expected behavior. * * @author Gisa Schaefer * @since 6.1.0 */ public class RemoteFile extends File { private static final long serialVersionUID = -3955270339797739703L; private Boolean directoryProperty = null; private long modifiedLast = 0; private long sizeInBytes = 0; /** * Calls the constructor of {@link File}. * * @param pathname * a path of the following form * "/NameOfRemoteFileSystem/Folder/Subfolder(s)/Filename" */ public RemoteFile(String pathname) { super(pathname); } /** * Calls the constructor of {@link File}. * * @param parent * a folder * @param fileName * name of the file that is to be constructed inside the folder */ public RemoteFile(File parent, String fileName) { super(parent, fileName); } /** * Calls the constructor of {@link File} and sets the directoryProperty. * * @param pathname * a path of the following form * "/NameOfRemoteFileSystem/Folder/Subfolder(s)/Filename" * @param directoryProperty * <code>true</code> if the constructed file is a directory */ public RemoteFile(String pathname, Boolean directoryProperty) { super(pathname); this.directoryProperty = directoryProperty; } @Override public boolean equals(Object obj) { if (obj != null && obj.getClass() == this.getClass()) { return ((RemoteFile) obj).getPath().equals(this.getPath()); } return false; } /** * Sets the flag which decides if the file is a directory. If this flag is not set or set to * <code> null </code> then {@link #isDirectory()} returns <code>false</code>, otherwise it * returns this flag. * * @param directoryProperty */ public void setDirectoryProperty(Boolean directoryProperty) { this.directoryProperty = directoryProperty; } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} returns the remote file with the parent * path name if it is not just "/" and <code>null</code> otherwise. */ @Override public File getParentFile() { RemoteFile file = new RemoteFile(getParent()); if (new RemoteFile("/").equals(file)) { return null; } return file; } /** * Returns the last time the file was modified (in milliseconds since the epoch) if it has been * set by {@link #setLastModified}, <code>0</code> otherwise. */ @Override public long lastModified() { return modifiedLast; } /** * Sets the last time the file was modified (in milliseconds since the epoch) - needed since * remote files cannot get this information from the hard drive. * * @param time * non-negative number representing the milliseconds since the epoch */ @Override public boolean setLastModified(long time) { if (time < 0) { throw new IllegalArgumentException("Negative time"); } modifiedLast = time; return true; } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} always returns <code>true</code>. */ @Override public boolean canRead() { return true; } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} returns the file itself. */ @Override public File getCanonicalFile() throws IOException { return this; } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} always returns <code>true</code>. */ @Override public boolean exists() { return true; } /** * If the flag directoryProperty is not set via {@link #setDirectoryProperty()} or set to * <code> null </code> then this method returns <code>false</code>, otherwise it returns the * flag directoryProperty. */ @Override public boolean isDirectory() { if (directoryProperty == null) { return false; } else { return directoryProperty; } } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} does nothing and always returns * <code>false</code>. */ @Override public boolean renameTo(File dest) { return false; } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} does nothing and always returns * <code>false</code>. */ @Override public boolean delete() { return false; } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} checks if the path starts with a separator. */ @Override public boolean isAbsolute() { return getPath().startsWith(File.separator); } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} returns {@link #getPath}. */ @Override public String getAbsolutePath() { return getPath(); } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} returns {@link #getPath}. */ @Override public String getCanonicalPath() throws IOException { return getPath(); } /** * Returns the size in bytes if it has been set by {@link #setSizeInBytes}, <code>0</code> * otherwise. */ @Override public long length() { return sizeInBytes; } /** * Sets the size (in bytes) of a file - needed since remote files cannot get this information * from the hard drive. * * @param sizeInBytes * non-negative number representing the size of the file in bytes */ public void setSizeInBytes(long sizeInBytes) { if (sizeInBytes < 0) { throw new IllegalArgumentException("Negative size"); } this.sizeInBytes = sizeInBytes; } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} returns the file itself. */ @Override public File getAbsoluteFile() { return this; } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} always returns <code>false</code>. */ @Override public boolean canWrite() { return false; } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} returns <code>true</code> if the file is * not a directory. */ @Override public boolean isFile() { return !isDirectory(); } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} always returns <code>false</code>. */ @Override public boolean isHidden() { return false; } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} does nothing and always returns * <code>false</code>. */ @Override public boolean createNewFile() throws IOException { return false; } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} throws an UnsupportedOperationException. */ @Override public void deleteOnExit() { throw new UnsupportedOperationException(); } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} always returns <code>null</code>. */ @Override public String[] list() { return null; } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} always returns <code>null</code>. */ @Override public String[] list(FilenameFilter filter) { return null; } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} always returns <code>null</code>. */ @Override public File[] listFiles() { return null; } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} always returns <code>null</code>. */ @Override public File[] listFiles(FilenameFilter filter) { return null; } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} always returns <code>null</code>. */ @Override public File[] listFiles(FileFilter filter) { return null; } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} does nothing and always returns * <code>false</code>. */ @Override public boolean mkdir() { return false; } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} does nothing and always returns * <code>false</code>. */ @Override public boolean mkdirs() { return false; } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} always returns <code>false</code>. */ @Override public boolean canExecute() { return false; } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} always returns <code>0L</code>. */ @Override public long getTotalSpace() { return 0L; } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} always returns <code>0L</code>. */ @Override public long getFreeSpace() { return 0L; } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} always returns <code>0L</code>. */ @Override public long getUsableSpace() { return 0L; } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} does nothing and always returns * <code>false</code>. */ @Override public boolean setReadOnly() { return false; } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} does nothing and always returns * <code>false</code>. */ @Override public boolean setWritable(boolean writable, boolean ownerOnly) { return false; } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} does nothing and always returns * <code>false</code>. */ @Override public boolean setWritable(boolean writable) { return false; } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} does nothing and always returns * <code>false</code>. */ @Override public boolean setReadable(boolean readable, boolean ownerOnly) { return false; } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} does nothing and always returns * <code>false</code>. */ @Override public boolean setReadable(boolean readable) { return false; } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} does nothing and always returns * <code>false</code>. */ @Override public boolean setExecutable(boolean executable, boolean ownerOnly) { return false; } /** * {@inheritDoc} * * <p> * The default implementation for {@link RemoteFile} does nothing and always returns * <code>false</code>. */ @Override public boolean setExecutable(boolean executable) { return false; } }