/**
* This file is protected by Copyright.
* Please refer to the COPYRIGHT file distributed with this source distribution.
*
* This file is part of REDHAWK IDE.
*
* 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 gov.redhawk.efs.sca.internal;
import gov.redhawk.efs.sca.internal.cache.IFileCache;
import gov.redhawk.efs.sca.internal.cache.ScaFileCache;
import gov.redhawk.sca.efs.ScaFileSystemPlugin;
import gov.redhawk.sca.util.Debug;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLEncoder;
import java.util.concurrent.Callable;
import mil.jpeojtrs.sca.util.CFErrorFormatter;
import mil.jpeojtrs.sca.util.CFErrorFormatter.FileOperation;
import mil.jpeojtrs.sca.util.CFErrorFormatter.FileOperation2;
import mil.jpeojtrs.sca.util.CorbaUtils;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.filesystem.provider.FileInfo;
import org.eclipse.core.filesystem.provider.FileStore;
import org.eclipse.core.runtime.CoreException;
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.core.runtime.SubProgressMonitor;
import org.eclipse.osgi.util.NLS;
import org.omg.CORBA.BAD_OPERATION;
import org.omg.CORBA.SystemException;
import org.omg.CORBA.TCKind;
import CF.DataType;
import CF.File;
import CF.FileException;
import CF.FileSystemOperations;
import CF.InvalidFileName;
import CF.FilePackage.InvalidFilePointer;
import CF.FileSystemPackage.FileInformationType;
import CF.FileSystemPackage.FileType;
public class ScaFileStore extends FileStore {
private static enum ScaFileInformationDataType {
CREATED_TIME,
MODIFIED_TIME,
LAST_ACCESS_TIME,
IOR_AVAILABLE,
READ_ONLY,
EXECUTABLE
}
private static final Debug DEBUG = new Debug(ScaFileSystemPlugin.ID, "fileStore");
private final URI fsInitRef;
private final ScaFileEntry entry;
private IFileCache cache;
public ScaFileStore(final URI fsInitRef, final ScaFileEntry entry) {
this.fsInitRef = fsInitRef;
this.entry = entry;
cache = ScaFileCache.INSTANCE.getCache(this);
}
public URI getFsInitRef() {
return fsInitRef;
}
public ScaFileEntry getEntry() {
return this.entry;
}
public FileSystemOperations getScaFileSystem() throws CoreException {
return cache.getScaFileSystem();
}
private boolean exists() throws CoreException {
final String path = this.entry.getAbsolutePath();
try {
return getScaFileSystem().exists(path);
} catch (final SystemException e) {
throw new CoreException(new Status(IStatus.ERROR, ScaFileSystemPlugin.ID, "File System Exception: " + this.entry.getUri(), e));
} catch (final InvalidFileName e) {
throw new CoreException(new Status(IStatus.ERROR, ScaFileSystemPlugin.ID, CFErrorFormatter.format(e, FileOperation.Exists, path), e));
}
}
private boolean isDirectory() {
return cache.isDirectory();
}
@Override
public String[] childNames(final int options, IProgressMonitor monitor) throws CoreException {
return cache.childNames(options, monitor);
}
public String[] internalChildNames(final int options, IProgressMonitor monitor) throws CoreException {
final String path = this.entry.getAbsolutePath();
monitor = SubMonitor.convert(monitor, Messages.ScaFileStore__Child_Names_Task_Name, IProgressMonitor.UNKNOWN);
try {
if (!isDirectory()) {
return FileStore.EMPTY_STRING_ARRAY;
}
final FileInformationType[] result = CorbaUtils.invoke(new Callable<FileInformationType[]>() {
@Override
public FileInformationType[] call() throws Exception {
String listPath = path + "/*"; //$NON-NLS-1$
try {
return getScaFileSystem().list(listPath);
} catch (FileException e) {
throw new CoreException(new Status(IStatus.ERROR, ScaFileSystemPlugin.ID, CFErrorFormatter.format(e, FileOperation.List, listPath), e));
} catch (InvalidFileName e) {
throw new CoreException(new Status(IStatus.ERROR, ScaFileSystemPlugin.ID, CFErrorFormatter.format(e, FileOperation.List, listPath), e));
}
}
}, monitor);
final String[] children = new String[result.length];
for (int i = 0; i < result.length; i++) {
final FileInformationType file = result[i];
children[i] = file.name;
}
return children;
} catch (final InterruptedException e) {
throw new CoreException(new Status(IStatus.ERROR, ScaFileSystemPlugin.ID, NLS.bind(Messages.ScaFileStore__Child_Names_Error, path), e));
} finally {
monitor.done();
}
}
public static IFileInfo translate(final FileInformationType typeInfo) {
final FileInfo info = new FileInfo(typeInfo.name);
// If path is a directory we will get the contents of the
// directory
info.setLength(typeInfo.size);
for (final DataType t : typeInfo.fileProperties) {
ScaFileInformationDataType scaDataType;
try {
scaDataType = ScaFileInformationDataType.valueOf(t.id);
} catch (final IllegalArgumentException e) {
continue;
}
switch (scaDataType) {
case MODIFIED_TIME:
switch (t.value.type().kind().value()) {
case TCKind._tk_long:
info.setLastModified(t.value.extract_long() * 1000L); // SUPPRESS CHECKSTYLE MagicNumber
break;
case TCKind._tk_ulong:
info.setLastModified(t.value.extract_ulong() * 1000L); // SUPPRESS CHECKSTYLE MagicNumber
break;
case TCKind._tk_ulonglong:
info.setLastModified(t.value.extract_ulonglong() * 1000L); // SUPPRESS CHECKSTYLE MagicNumber
break;
default:
break;
}
break;
case READ_ONLY:
try {
info.setAttribute(EFS.ATTRIBUTE_READ_ONLY, t.value.extract_boolean());
} catch (BAD_OPERATION e) {
ScaFileSystemPlugin.logError("Non-boolean value for read-only property in FileInformationType", null);
}
break;
case EXECUTABLE:
try {
info.setAttribute(EFS.ATTRIBUTE_EXECUTABLE, t.value.extract_boolean());
} catch (BAD_OPERATION e) {
ScaFileSystemPlugin.logError("Non-boolean value for executable property in FileInformationType", null);
}
break;
default:
// Unhandled property
break;
}
}
info.setExists(true);
switch (typeInfo.kind.value()) {
case FileType._FILE_SYSTEM:
case FileType._DIRECTORY:
info.setDirectory(true);
break;
case FileType._PLAIN:
info.setDirectory(false);
break;
default:
break;
}
return info;
}
@Override
public IFileInfo fetchInfo(final int options, IProgressMonitor monitor) throws CoreException {
final String path = this.entry.getAbsolutePath();
monitor = SubMonitor.convert(monitor, Messages.ScaFileStore__Fetch_Info_Task_Name, IProgressMonitor.UNKNOWN);
try {
IFileInfo retVal;
final FileInformationType[] result = CorbaUtils.invoke(new Callable<FileInformationType[]>() {
@Override
public FileInformationType[] call() throws Exception {
try {
return getScaFileSystem().list(path);
} catch (FileException e) {
throw new CoreException(new Status(IStatus.ERROR, ScaFileSystemPlugin.ID, CFErrorFormatter.format(e, FileOperation.List, path), e));
} catch (InvalidFileName e) {
throw new CoreException(new Status(IStatus.ERROR, ScaFileSystemPlugin.ID, CFErrorFormatter.format(e, FileOperation.List, path), e));
}
}
}, monitor);
if (result.length == 0) {
final FileInfo info = new FileInfo(getName());
info.setExists(false);
retVal = info;
} else {
retVal = ScaFileStore.translate(result[0]);
}
return retVal;
} catch (final InterruptedException e) {
throw new CoreException(new Status(IStatus.ERROR, ScaFileSystemPlugin.ID, NLS.bind(Messages.ScaFileStore__Fetch_Info_Error, path), e));
} finally {
monitor.done();
}
}
@Override
public IFileStore getChild(final String name) {
final URI uri = this.entry.getUri();
org.eclipse.emf.common.util.URI tmp = org.eclipse.emf.common.util.URI.createURI(uri.toString());
String encName;
try {
encName = URLEncoder.encode(name, "UTF-8"); //$NON-NLS-1$
tmp = tmp.appendSegment(encName);
final URI childUri = URI.create(tmp.toString());
final ScaFileStore child = new ScaFileStore(this.fsInitRef, new ScaFileEntry(childUri));
return child;
} catch (final UnsupportedEncodingException e) {
ScaFileStore.DEBUG.catching(e);
return EFS.getNullFileSystem().getStore(uri);
}
}
@Override
public String getName() {
return this.entry.getName();
}
@Override
public IFileStore getParent() {
final URI uri = this.entry.getParentUri();
if (uri == null) {
return null;
}
try {
return EFS.getStore(uri);
} catch (final CoreException e) {
return null;
}
}
@Override
public InputStream openInputStream(final int options, final IProgressMonitor monitor) throws CoreException {
return cache.openInputStream();
}
@Override
public OutputStream openOutputStream(final int options, IProgressMonitor monitor) throws CoreException {
final String path = this.entry.getAbsolutePath();
monitor = SubMonitor.convert(monitor, NLS.bind(Messages.ScaFileStore__Open_Output_Stream_Task_Name, path), IProgressMonitor.UNKNOWN);
try {
final IFileInfo info = this.fetchInfo();
boolean exists = info.exists();
final boolean append = EFS.APPEND == (EFS.APPEND & options);
if (info.getAttribute(EFS.ATTRIBUTE_READ_ONLY)) {
throw new CoreException(
new Status(IStatus.ERROR, ScaFileSystemPlugin.ID, NLS.bind(Messages.ScaFileStore__Open_Output_Stream_Error_Read_Only, path)));
}
if (exists && !append) {
this.delete(options, new SubProgressMonitor(monitor, 1));
exists = false;
}
File file;
FileSystemOperations fs = getScaFileSystem();
if (!exists) {
try {
file = fs.create(path);
} catch (InvalidFileName e) {
throw new CoreException(new Status(IStatus.ERROR, ScaFileSystemPlugin.ID, CFErrorFormatter.format(e, FileOperation.Create, path), e));
} catch (FileException e) {
throw new CoreException(new Status(IStatus.ERROR, ScaFileSystemPlugin.ID, CFErrorFormatter.format(e, FileOperation.Create, path), e));
}
} else {
try {
file = fs.open(path, false);
} catch (InvalidFileName e) {
throw new CoreException(new Status(IStatus.ERROR, ScaFileSystemPlugin.ID, CFErrorFormatter.format(e, FileOperation.Open, path), e));
} catch (FileException e) {
throw new CoreException(new Status(IStatus.ERROR, ScaFileSystemPlugin.ID, CFErrorFormatter.format(e, FileOperation.Open, path), e));
}
}
try {
return new ScaFileOutputStream(file, append);
} catch (final InvalidFilePointer e) {
throw new CoreException(new Status(IStatus.ERROR, ScaFileSystemPlugin.ID, CFErrorFormatter.format(e, path), e));
} catch (FileException e) {
throw new CoreException(new Status(IStatus.ERROR, ScaFileSystemPlugin.ID, CFErrorFormatter.format(e, FileOperation.Seek, path), e));
}
} catch (final SystemException e) {
throw new CoreException(
new Status(IStatus.ERROR, ScaFileSystemPlugin.ID, NLS.bind(Messages.ScaFileStore__Open_Output_Stream_Error_System, path), e));
} finally {
monitor.done();
}
}
@Override
public URI toURI() {
return this.entry.getUri();
}
@Override
public IFileInfo[] childInfos(final int options, IProgressMonitor monitor) throws CoreException {
return cache.childInfos(options, monitor);
}
public IFileInfo[] internalChildInfos(final int options, IProgressMonitor monitor) throws CoreException {
final String path = this.entry.getAbsolutePath();
monitor = SubMonitor.convert(monitor, Messages.ScaFileStore__Getting_Child_Info_Task, IProgressMonitor.UNKNOWN);
try {
if (!isDirectory()) {
return FileStore.EMPTY_FILE_INFO_ARRAY;
}
final FileInformationType[] result = CorbaUtils.invoke(new Callable<FileInformationType[]>() {
@Override
public FileInformationType[] call() throws Exception {
final String listPath = path + "/*"; //$NON-NLS-1$
try {
return getScaFileSystem().list(listPath);
} catch (FileException e) {
throw new CoreException(new Status(IStatus.ERROR, ScaFileSystemPlugin.ID, CFErrorFormatter.format(e, FileOperation.List, listPath), e));
}
}
}, monitor);
final IFileInfo[] retVal = new IFileInfo[result.length];
for (int i = 0; i < result.length; i++) {
retVal[i] = ScaFileStore.translate(result[i]);
}
return retVal;
} catch (final InterruptedException e) {
throw new CoreException(new Status(IStatus.ERROR, ScaFileSystemPlugin.ID, NLS.bind(Messages.ScaFileStore__Child_Info_Error, path), e));
} finally {
monitor.done();
}
}
@Override
public void delete(final int options, final IProgressMonitor monitor) throws CoreException {
final String path = this.entry.getAbsolutePath();
final SubMonitor subMonitor = SubMonitor.convert(monitor, NLS.bind(Messages.ScaFileStore__Deleting_Task, path), IProgressMonitor.UNKNOWN);
try {
if (!exists()) {
return;
}
FileSystemOperations fs = getScaFileSystem();
if (fetchInfo().isDirectory()) {
final IFileStore[] childStore = childStores(EFS.NONE, subMonitor.newChild(1));
final SubMonitor deleteChildrenMonitor = subMonitor.newChild(1);
deleteChildrenMonitor.beginTask("Deleting contained items...", childStore.length);
for (final IFileStore store : childStore) {
store.delete(options, deleteChildrenMonitor.newChild(1));
}
fs.remove(path + "/*");
fs.rmdir(path);
subMonitor.worked(1);
} else {
fs.remove(path);
}
} catch (final FileException e) {
throw new CoreException(new Status(IStatus.ERROR, ScaFileSystemPlugin.ID, CFErrorFormatter.format(e, FileOperation.Delete, path), e));
} catch (final InvalidFileName e) {
throw new CoreException(new Status(IStatus.ERROR, ScaFileSystemPlugin.ID, CFErrorFormatter.format(e, FileOperation.Delete, path), e));
} catch (final SystemException e) {
throw new CoreException(new Status(IStatus.ERROR, ScaFileSystemPlugin.ID, NLS.bind(Messages.ScaFileStore__Deleting_Error_System, path), e));
} finally {
subMonitor.done();
}
}
@Override
public IFileStore mkdir(final int options, IProgressMonitor monitor) throws CoreException {
final String path = this.entry.getAbsolutePath();
final IFileInfo info = fetchInfo();
if (info.exists()) {
if (info.isDirectory()) {
return this;
} else {
throw new CoreException(
new Status(IStatus.ERROR, ScaFileSystemPlugin.ID, NLS.bind(Messages.ScaFileStore__Mkdir_Error_File_Exists, path), null));
}
}
monitor = SubMonitor.convert(monitor, NLS.bind(Messages.ScaFileStore__Mkdir_Task_Name, path), IProgressMonitor.UNKNOWN);
try {
getScaFileSystem().mkdir(path);
return this;
} catch (final FileException e) {
throw new CoreException(new Status(IStatus.ERROR, ScaFileSystemPlugin.ID, CFErrorFormatter.format(e, FileOperation.Mkdir, path), e));
} catch (final InvalidFileName e) {
throw new CoreException(new Status(IStatus.ERROR, ScaFileSystemPlugin.ID, CFErrorFormatter.format(e, FileOperation.Mkdir, path), e));
} catch (final SystemException e) {
throw new CoreException(new Status(IStatus.ERROR, ScaFileSystemPlugin.ID, NLS.bind(Messages.ScaFileStore__Mkdir_Error_System, path), e));
} finally {
monitor.done();
}
}
@Override
public void putInfo(final IFileInfo info, final int options, final IProgressMonitor monitor) throws CoreException {
ScaFileStore.DEBUG.enteringMethod(info, options, monitor);
// Nothin to do here
}
@Override
public java.io.File toLocalFile(final int options, final IProgressMonitor monitor) throws CoreException {
return cache.toLocalFile();
// return super.toLocalFile(options | EFS.CACHE, monitor);
}
@Override
public void move(final IFileStore destination, final int options, final IProgressMonitor monitor) throws CoreException {
if (destination instanceof ScaFileStore) {
final ScaFileStore scaDest = (ScaFileStore) destination;
FileSystemOperations fs = null;
FileSystemOperations destFs = null;
fs = getScaFileSystem();
destFs = scaDest.getScaFileSystem();
final String path = this.entry.getAbsolutePath();
final String destPath = scaDest.entry.getAbsolutePath();
try {
if (fs == destFs) {
fs.move(path, destPath);
}
} catch (final InvalidFileName e) {
throw new CoreException(new Status(IStatus.ERROR, ScaFileSystemPlugin.ID, CFErrorFormatter.format(e, FileOperation2.Move, path, destPath), e));
} catch (final FileException e) {
throw new CoreException(new Status(IStatus.ERROR, ScaFileSystemPlugin.ID, CFErrorFormatter.format(e, FileOperation2.Move, path, destPath), e));
}
} else {
super.move(destination, options, monitor);
}
}
@Override
protected void copyFile(final IFileInfo sourceInfo, final IFileStore destination, final int options, final IProgressMonitor monitor) throws CoreException {
if (destination instanceof ScaFileStore) {
final ScaFileStore scaDest = (ScaFileStore) destination;
final String path = this.entry.getAbsolutePath();
final String destPath = scaDest.entry.getAbsolutePath();
FileSystemOperations fs = null;
FileSystemOperations destFs = null;
try {
fs = getScaFileSystem();
destFs = scaDest.getScaFileSystem();
if (fs == destFs) {
fs.copy(path, destPath);
}
} catch (final InvalidFileName e) {
throw new CoreException(new Status(IStatus.ERROR, ScaFileSystemPlugin.ID, CFErrorFormatter.format(e, FileOperation2.Copy, path, destPath), e));
} catch (final FileException e) {
throw new CoreException(new Status(IStatus.ERROR, ScaFileSystemPlugin.ID, CFErrorFormatter.format(e, FileOperation2.Copy, path, destPath), e));
}
} else {
super.copyFile(sourceInfo, destination, options, monitor);
}
}
}