blob: 4fa27121a6a4182cace8400e92da94b4f449f02f [file] [log] [blame]
/*******************************************************************************
* 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
* Martin Oberhuber (Wind River) - [170317] add symbolic link support to API
*******************************************************************************/
package org.eclipse.core.filesystem.provider;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.core.internal.filesystem.local.LocalFileNativesManager;
/**
* This class should be used by file system providers in their implementation
* of API methods that return {@link IFileInfo} objects.
*
* @since org.eclipse.core.filesystem 1.0
* @noextend This class is not intended to be subclassed by clients.
*/
public class FileInfo implements IFileInfo {
/**
* Internal attribute indicating if the file is a directory
*/
private static final int ATTRIBUTE_DIRECTORY = 1 << 0;
/**
* Internal attribute indicating if the file exists.
*/
private static final int ATTRIBUTE_EXISTS = 1 << 16;
/**
* Bit field of file attributes. Initialized to specify a writable resource.
*/
private int attributes = EFS.ATTRIBUTE_OWNER_WRITE | EFS.ATTRIBUTE_OWNER_READ;
private int errorCode = NONE;
/**
* The last modified time.
*/
private long lastModified = EFS.NONE;
/**
* The file length.
*/
private long length = EFS.NONE;
/**
* The file name.
*/
private String name = ""; //$NON-NLS-1$
/**
* The target file name if this is a symbolic link
*/
private String linkTarget = null;
/**
* Creates a new file information object with default values.
*/
public FileInfo() {
super();
}
/**
* Creates a new file information object. All values except the file name
* will have default values.
*
* @param name The name of this file
*/
public FileInfo(String name) {
super();
this.name = name;
}
/**
* Convenience method to clear a masked region of the attributes bit field.
*
* @param mask The mask to be cleared
*/
private void clear(int mask) {
attributes &= ~mask;
}
@Override
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
// We know this object is cloneable.
return null;
}
}
/**
* @since 1.5
*/
@Override
public int compareTo(IFileInfo o) {
return name.compareTo(o.getName());
}
@Override
public boolean exists() {
return getAttribute(ATTRIBUTE_EXISTS);
}
/**
* @since 1.4
*/
@Override
public int getError() {
return errorCode;
}
@Override
public boolean getAttribute(int attribute) {
if (attribute == EFS.ATTRIBUTE_READ_ONLY && isAttributeSuported(EFS.ATTRIBUTE_OWNER_WRITE))
return (!isSet(EFS.ATTRIBUTE_OWNER_WRITE)) || isSet(EFS.ATTRIBUTE_IMMUTABLE);
else if (attribute == EFS.ATTRIBUTE_EXECUTABLE && isAttributeSuported(EFS.ATTRIBUTE_OWNER_EXECUTE))
return isSet(EFS.ATTRIBUTE_OWNER_EXECUTE);
else
return isSet(attribute);
}
@Override
public String getStringAttribute(int attribute) {
if (attribute == EFS.ATTRIBUTE_LINK_TARGET)
return this.linkTarget;
return null;
}
@Override
public long getLastModified() {
return lastModified;
}
@Override
public long getLength() {
return length;
}
@Override
public String getName() {
return name;
}
@Override
public boolean isDirectory() {
return isSet(ATTRIBUTE_DIRECTORY);
}
private boolean isSet(long mask) {
return (attributes & mask) != 0;
}
private void set(int mask) {
attributes |= mask;
}
@Override
public void setAttribute(int attribute, boolean value) {
if (attribute == EFS.ATTRIBUTE_READ_ONLY && isAttributeSuported(EFS.ATTRIBUTE_OWNER_WRITE)) {
if (value) {
clear(EFS.ATTRIBUTE_OWNER_WRITE | EFS.ATTRIBUTE_OTHER_WRITE | EFS.ATTRIBUTE_GROUP_WRITE);
set(EFS.ATTRIBUTE_IMMUTABLE);
} else {
set(EFS.ATTRIBUTE_OWNER_WRITE | EFS.ATTRIBUTE_OWNER_READ);
clear(EFS.ATTRIBUTE_IMMUTABLE);
}
} else if (attribute == EFS.ATTRIBUTE_EXECUTABLE && isAttributeSuported(EFS.ATTRIBUTE_OWNER_EXECUTE)) {
if (value)
set(EFS.ATTRIBUTE_OWNER_EXECUTE);
else
clear(EFS.ATTRIBUTE_OWNER_EXECUTE | EFS.ATTRIBUTE_GROUP_EXECUTE | EFS.ATTRIBUTE_OTHER_EXECUTE);
} else {
if (value)
set(attribute);
else
clear(attribute);
}
}
private static boolean isAttributeSuported(int value) {
return (LocalFileNativesManager.getSupportedAttributes() & value) != 0;
}
/**
* Sets whether this is a file or directory.
*
* @param value <code>true</code> if this is a directory, and <code>false</code>
* if this is a file.
*/
public void setDirectory(boolean value) {
if (value)
set(ATTRIBUTE_DIRECTORY);
else
clear(ATTRIBUTE_DIRECTORY);
}
/**
* Sets whether this file or directory exists.
*
* @param value <code>true</code> if this file exists, and <code>false</code>
* otherwise.
*/
public void setExists(boolean value) {
if (value)
set(ATTRIBUTE_EXISTS);
else
clear(ATTRIBUTE_EXISTS);
}
/**
* Sets the error code indicating whether an I/O error was encountered when accessing the file.
*
* @param errorCode {@link IFileInfo#IO_ERROR} if this file has an I/O error,
* and {@link IFileInfo#NONE} otherwise.
* @since 1.4
*/
public void setError(int errorCode) {
this.errorCode = errorCode;
}
@Override
public void setLastModified(long value) {
lastModified = value;
}
/**
* Sets the length of this file. A value of {@link EFS#NONE}
* indicates the file does not exist, is a directory, or the length could not be computed.
*
* @param value the length of this file, or {@link EFS#NONE}
*/
public void setLength(long value) {
this.length = value;
}
/**
* Sets the name of this file.
*
* @param name The file name
*/
public void setName(String name) {
if (name == null)
throw new IllegalArgumentException();
this.name = name;
}
/**
* Sets or clears a String attribute, e.g. symbolic link target.
*
* @param attribute The kind of attribute to set. Currently only
* {@link EFS#ATTRIBUTE_LINK_TARGET} is supported.
* @param value The String attribute, or <code>null</code> to clear
* the attribute
* @since org.eclipse.core.filesystem 1.1
*/
public void setStringAttribute(int attribute, String value) {
if (attribute == EFS.ATTRIBUTE_LINK_TARGET)
this.linkTarget = value;
}
/**
* For debugging purposes only.
*/
@Override
public String toString() {
return name;
}
}