blob: a63525b9656e9b262f63e7ee33dcc0fa1fa9c803 [file] [log] [blame]
/*
* Copyright (c) 2014, 2015 Eike Stepper (Berlin, Germany) and others.
* 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
*
* Contributors:
* Eike Stepper - initial API and implementation
*/
package org.eclipse.oomph.setup.ui;
import org.eclipse.oomph.setup.internal.core.SetupContext;
import org.eclipse.oomph.setup.internal.core.util.SetupCoreUtil;
import org.eclipse.emf.common.ui.URIEditorInput;
import org.eclipse.emf.common.ui.viewer.IViewerProvider;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.domain.IEditingDomainProvider;
import org.eclipse.emf.edit.ui.util.EditUIUtil;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IPersistableElement;
import org.eclipse.ui.IStorageEditorInput;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.ide.FileStoreEditorInput;
import org.eclipse.ui.part.FileEditorInput;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author Eike Stepper
*/
public final class SetupEditorSupport
{
/**
* The job family used by the setup editor for loading the model using a resource mirror.
*/
public static final Object FAMILY_MODEL_LOAD = new Object();
public static final String EDITOR_ID = "org.eclipse.oomph.setup.presentation.SetupEditorID";
public static final String TEXT_EDITOR_ID = "org.eclipse.ui.DefaultTextEditor";
public static IEditorPart getEditor(final IWorkbenchPage page, final URI uri, boolean force, LoadHandler... loadHandlers)
{
try
{
URIConverter uriConverter = SetupCoreUtil.createResourceSet().getURIConverter();
final String fragment = uri.fragment();
final URI normalizedURI = uriConverter.normalize(uri.trimFragment());
final IEditorInput editorInput = getEditorInput(normalizedURI);
IEditorPart editor = findEditor(EDITOR_ID, page, uriConverter, editorInput);
if (editor != null)
{
page.activate(editor);
}
else if (force)
{
editor = page.openEditor(editorInput, EDITOR_ID, true, IWorkbenchPage.MATCH_ID | IWorkbenchPage.MATCH_INPUT);
}
// If there is an editor...
if (editor != null)
{
// Convert the handlers to a list, and if there is a fragment, add a handler for selecting the object associated with that fragment.
final List<LoadHandler> handlers = new ArrayList<LoadHandler>(Arrays.asList(loadHandlers));
if (fragment != null)
{
handlers.add(0, new LoadHandler()
{
@Override
protected void loaded(IEditorPart editor, EditingDomain domain, Resource resource)
{
EObject eObject = resource.getEObject(fragment);
if (eObject != null)
{
((IViewerProvider)editor).getViewer().setSelection(new StructuredSelection(eObject), true);
}
}
});
}
// If there are handlers...
if (!handlers.isEmpty())
{
final IEditorPart finalEditor = editor;
Job job = new Job("Loading Setup Editor")
{
@Override
protected IStatus run(IProgressMonitor monitor)
{
try
{
// Wait for the model load jobs to complete.
Job.getJobManager().join(SetupEditorSupport.FAMILY_MODEL_LOAD, monitor);
Shell shell = page.getWorkbenchWindow().getShell();
if (!shell.isDisposed())
{
shell.getDisplay().asyncExec(new Runnable()
{
public void run()
{
URI uri = EditUIUtil.getURI(editorInput);
for (LoadHandler handler : handlers)
{
handler.loaded(finalEditor, uri);
}
}
});
}
return Status.OK_STATUS;
}
catch (Exception ex)
{
return SetupUIPlugin.INSTANCE.getStatus(ex);
}
}
};
// Hide the job and schedule it.
job.setSystem(true);
job.schedule();
}
return editor;
}
}
catch (Exception ex)
{
SetupUIPlugin.INSTANCE.log(ex);
}
return null;
}
public static IEditorPart getTextEditor(final IWorkbenchPage page, final URI uri)
{
try
{
URIConverter uriConverter = SetupCoreUtil.createResourceSet().getURIConverter();
final URI normalizedURI = uriConverter.normalize(uri.trimFragment());
final IEditorInput editorInput = getTextEditorInput(normalizedURI);
IEditorPart editor = findEditor(TEXT_EDITOR_ID, page, uriConverter, editorInput);
if (editor != null)
{
page.activate(editor);
}
else
{
editor = page.openEditor(editorInput, TEXT_EDITOR_ID, true, IWorkbenchPage.MATCH_ID | IWorkbenchPage.MATCH_INPUT);
}
return editor;
}
catch (Exception ex)
{
SetupUIPlugin.INSTANCE.log(ex);
}
return null;
}
private static IEditorPart findEditor(String editorID, IWorkbenchPage page, URIConverter uriConverter, IEditorInput input)
{
URI resourceURI = EditUIUtil.getURI(input);
for (IEditorReference editorReference : page.getEditorReferences())
{
if (editorReference.getId().equals(editorID))
{
try
{
IEditorInput editorInput = editorReference.getEditorInput();
URI editorResourceURI = EditUIUtil.getURI(editorInput);
if (editorResourceURI != null)
{
editorResourceURI = uriConverter.normalize(editorResourceURI).trimFragment();
if (editorResourceURI.equals(resourceURI))
{
return editorReference.getEditor(true);
}
}
}
catch (PartInitException ex)
{
SetupUIPlugin.INSTANCE.log(ex);
}
}
}
return null;
}
private static IEditorInput getTextEditorInput(final URI normalizedURI)
{
IEditorInput editorInput = getEditorInput(normalizedURI);
if (editorInput instanceof URIEditorInput)
{
URIEditorInput uriEditorInput = (URIEditorInput)editorInput;
final URI uri = uriEditorInput.getURI();
if (uri.isFile())
{
IFileStore store = EFS.getLocalFileSystem().getStore(new Path(uri.toFileString()));
return new FileStoreEditorInput(store);
}
return new IStorageEditorInput()
{
public <T> T getAdapter(Class<T> adapter)
{
return null;
}
public String getToolTipText()
{
return uri.toString();
}
public IPersistableElement getPersistable()
{
return null;
}
public String getName()
{
return uri.lastSegment();
}
public ImageDescriptor getImageDescriptor()
{
return null;
}
public boolean exists()
{
return true;
}
public IStorage getStorage() throws CoreException
{
return new IStorage()
{
public <T> T getAdapter(Class<T> adapter)
{
return null;
}
public boolean isReadOnly()
{
return true;
}
public String getName()
{
return uri.lastSegment();
}
public IPath getFullPath()
{
return new Path(uri.toString());
}
public InputStream getContents() throws CoreException
{
URIConverter uriConverter = SetupCoreUtil.createResourceSet().getURIConverter();
try
{
return uriConverter.createInputStream(uri);
}
catch (IOException ex)
{
SetupUIPlugin.INSTANCE.coreException(ex);
return null;
}
}
};
}
};
}
return editorInput;
}
private static IEditorInput getEditorInput(URI normalizedURI)
{
normalizedURI = SetupContext.resolveUser(normalizedURI);
if (normalizedURI.isFile())
{
FileEditorInput editorInput = getFileEditorInput(normalizedURI);
if (editorInput != null)
{
return editorInput;
}
}
if (normalizedURI.isPlatformResource())
{
IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(normalizedURI.toPlatformString(true)));
if (file.isAccessible())
{
return new FileEditorInput(file);
}
}
return new URIEditorInput(normalizedURI, normalizedURI.lastSegment());
}
private static FileEditorInput getFileEditorInput(URI uri)
{
if (uri.isFile())
{
try
{
IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(new java.net.URI(uri.toString()));
for (IFile file : files)
{
if (file.isAccessible())
{
return new FileEditorInput(file);
}
}
}
catch (URISyntaxException ex)
{
SetupUIPlugin.INSTANCE.log(ex);
}
}
return null;
}
private SetupEditorSupport()
{
}
/**
* @author Ed Merks
*/
public static class LoadHandler
{
public void loaded(IEditorPart editor, URI uri)
{
loaded(editor, ((IEditingDomainProvider)editor).getEditingDomain(), uri);
}
protected void loaded(IEditorPart editorPart, EditingDomain domain, URI uri)
{
Resource resource = domain.getResourceSet().getResource(uri, false);
if (resource != null)
{
loaded(editorPart, domain, resource);
}
}
protected void loaded(IEditorPart editor, EditingDomain domain, Resource resource)
{
}
}
}