package org.xmind.ui.internal.editor;
import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.URI;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.osgi.util.NLS;
import org.eclipse.ui.IEditorInput;
import org.osgi.framework.Bundle;
import org.xmind.core.IWorkbook;
import org.xmind.ui.internal.MindMapUIPlugin;
public class MME {
private static Bundle ideBundle = null;
private static boolean noIDE = false;
public static IEditorInput createNonExistingEditorInput() {
return new WorkbookEditorInput();
}
public static IEditorInput createNamedEditorInput(String name) {
return new WorkbookEditorInput(name);
}
public static IEditorInput createTemplatedEditorInput(
InputStream templateStream) {
return new WorkbookEditorInput(null, templateStream);
}
public static IEditorInput createTemplatedEditorInput(String name,
InputStream templateStream) {
return new WorkbookEditorInput(name, templateStream);
}
public static IEditorInput createLoadedEditorInput(IWorkbook workbook) {
return new WorkbookEditorInput(workbook);
}
public static IEditorInput createLoadedEditorInput(String name,
IWorkbook workbook) {
return new WorkbookEditorInput(name, workbook);
}
/**
* Creates an editor input using the given file. Note that if there's
* Eclipse IDE running, the result will be an
* {@link org.eclipse.ui.ide.FileStoreEditorInput}; otherwise an instance of
* {@link FileEditorInput} will be returned.
*
* @param path
* The absolute path of a file
* @return A new editor input representing the given file
* @throws CoreException
* if the creation failed
*/
public static IEditorInput createFileEditorInput(String path)
throws CoreException {
if (path == null)
throw new IllegalArgumentException("Path is null"); //$NON-NLS-1$
return createFileEditorInput(new File(path));
}
/**
* Creates an editor input using the given file. Note that if there's
* Eclipse IDE running, the result will be an
* {@link org.eclipse.ui.ide.FileStoreEditorInput}; otherwise an instance of
* {@link FileEditorInput} will be returned.
*
* @param file
* The file
* @return A new editor input representing the given file.
* @throws CoreException
* if the creation failed
*/
public static IEditorInput createFileEditorInput(File file)
throws CoreException {
if (file == null)
throw new IllegalArgumentException("File is null"); //$NON-NLS-1$
Bundle ide = getIDE();
if (ide != null) {
IFileStore fileStore = EFS.getStore(file.toURI());
return createFileEditorInput(ide, fileStore);
}
return new FileEditorInput(file);
}
/**
* Creates an editor input using the given file store.
* <p>
* <b>IMPORTANT:</b> This method should ONLY be called when there's Eclipse
* IDE in the runtime environment.
* </p>
*
* @param fileStore
* @return
* @throws CoreException
* if the creation failed
* @throws IllegalStateException
* if the Eclipse IDE plugin isn't in the runtime environment
*/
public static IEditorInput createFileEditorInput(IFileStore fileStore)
throws CoreException {
if (fileStore == null)
throw new IllegalArgumentException("File store is null"); //$NON-NLS-1$
Bundle ide = getIDE();
if (ide != null) {
return createFileEditorInput(ide, fileStore);
}
throw new IllegalStateException(
"Can't create editor input using IFileStore when no Eclipse IDE plugin is resolved."); //$NON-NLS-1$
}
/*
* We don't depend on org.eclipse.ui.ide, so we have to use class loader.
*/
@SuppressWarnings("unchecked")
private static IEditorInput createFileEditorInput(Bundle ide,
IFileStore fileStore) throws CoreException {
if (fileStore == null)
throw new IllegalArgumentException("File store is null"); //$NON-NLS-1$
try {
Class clazz = ide
.loadClass("org.eclipse.ui.ide.FileStoreEditorInput"); //$NON-NLS-1$
Constructor c = clazz.getConstructor(IFileStore.class);
return (IEditorInput) c.newInstance(fileStore);
} catch (Throwable e) {
IStatus status = new Status(IStatus.ERROR,
MindMapUIPlugin.PLUGIN_ID,
"Unable to create FileStoreEditorInput."); //$NON-NLS-1$
throw new CoreException(status);
}
}
/**
* Creates an editor input using the given file.
* <p>
* <b>IMPORTANT:</b> This method should ONLY be called when there's Eclipse
* IDE in the runtime environment.
* </p>
*
* @param file
* The file
* @return A new editor input representing the given file.
* @throws CoreException
* if the creation failed
* @throws IllegalStateException
* if the Eclipse IDE isn't in the runtime environment
*/
public static IEditorInput createFileEditorInput(IFile file)
throws CoreException {
if (file == null)
throw new IllegalArgumentException("File is null"); //$NON-NLS-1$
Bundle ide = getIDE();
if (ide != null) {
return createFileEditorInput(ide, file);
}
throw new IllegalStateException(
"Can't create editor input using IFile when no Eclipse IDE plugin is resolved."); //$NON-NLS-1$
}
/*
* We don't depend on org.eclipse.ui.ide, so we have to use class loader.
*/
@SuppressWarnings("unchecked")
private static IEditorInput createFileEditorInput(Bundle ide, IFile file)
throws CoreException {
try {
Class clazz = ide.loadClass("org.eclipse.ui.part.FileEditorInput"); //$NON-NLS-1$
Constructor c = clazz.getConstructor(IFile.class);
Object input = c.newInstance(file);
return (IEditorInput) input;
} catch (Throwable e) {
IStatus status = new Status(IStatus.ERROR,
MindMapUIPlugin.PLUGIN_ID, NLS.bind(
"Failed to create IDE's FileEditorInput: {0}", file //$NON-NLS-1$
.getFullPath()));
throw new CoreException(status);
}
}
public static File getFile(Object input) {
IFileStore fileStore = getFileStore(input);
if (fileStore != null) {
try {
return fileStore.toLocalFile(0, new NullProgressMonitor());
} catch (CoreException ignore) {
}
}
return null;
}
public static IFileStore getFileStore(Object input) {
IFileStore fileStore = (IFileStore) getAdapter(input, IFileStore.class);
if (fileStore == null) {
File file = (File) getAdapter(input, File.class);
if (file != null) {
try {
fileStore = EFS.getStore(file.toURI());
} catch (CoreException ignore) {
}
}
}
if (fileStore == null) {
fileStore = forceFileStore(input);
}
return fileStore;
}
static Object getAdapter(Object adaptable, Class adapterType) {
if (adaptable instanceof IAdaptable) {
return ((IAdaptable) adaptable).getAdapter(adapterType);
}
return Platform.getAdapterManager().getAdapter(adaptable, adapterType);
}
@SuppressWarnings("unchecked")
private static IFileStore forceFileStore(Object adaptable) {
if (!(isInplementation(adaptable, "org.eclipse.ui.IURIEditorInput"))) //$NON-NLS-1$
return null;
Class clazz = adaptable.getClass();
try {
// For 'org.eclipse.ui.IURIEditorInput':
// we don't directly depend on org.eclipse.ui.ide,
// so we have to count on reflection.
//FIXME design an extension point for this
Method method = clazz.getMethod("getURI"); //$NON-NLS-1$
// if (method.isAccessible()) {
Object result = method.invoke(adaptable);
if (result instanceof URI) {
return EFS.getStore((URI) result);
}
// }
} catch (Throwable ignore) {
}
return null;
}
private static boolean isInplementation(Object obj, String interfaceName) {
Class[] interfaces = obj.getClass().getInterfaces();
return hasInterface(interfaces, interfaceName);
}
private static boolean hasInterface(Class[] interfaces, String interfaceName) {
if (interfaces.length == 0)
return false;
for (Class c : interfaces) {
if (isClass(c, interfaceName)) {
return true;
}
if (hasInterface(c.getInterfaces(), interfaceName))
return true;
}
return false;
}
private static boolean isClass(Class c, String className) {
return className.equals(c.getName());
}
private static Bundle getIDE() {
if (ideBundle == null && !noIDE) {
ideBundle = Platform.getBundle("org.eclipse.ui.ide"); //$NON-NLS-1$
noIDE = (ideBundle == null);
}
return ideBundle;
}
}