/******************************************************************************* * Copyright (c) 2012 itemis AG (http://www.itemis.eu) 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 *******************************************************************************/ package org.xpect.ui.services; import java.util.Iterator; import org.apache.log4j.Logger; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IStorage; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.common.util.WrappedException; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.PartInitException; import org.eclipse.ui.ide.IDE; import org.eclipse.ui.part.FileEditorInput; import org.eclipse.xtext.resource.ILocationInFileProvider; import org.eclipse.xtext.resource.XtextResource; import org.eclipse.xtext.ui.editor.IURIEditorOpener; import org.eclipse.xtext.ui.editor.XtextEditor; import org.eclipse.xtext.ui.editor.XtextReadonlyEditorInput; import org.eclipse.xtext.ui.editor.utils.EditorUtils; import org.eclipse.xtext.ui.resource.IStorage2UriMapper; import org.eclipse.xtext.util.ITextRegion; import org.eclipse.xtext.util.Pair; import org.eclipse.xtext.util.concurrent.IUnitOfWork; import org.xpect.ui.XpectPluginActivator; import org.xpect.ui.util.XpectFileAccess; import com.google.inject.Inject; /** * @author Moritz Eysholdt - Initial contribution and API */ public class XtLanguageSpecificURIEditorOpener implements IURIEditorOpener { private static final Logger logger = Logger.getLogger(XtLanguageSpecificURIEditorOpener.class); @Inject private IStorage2UriMapper mapper; @Inject(optional = true) private IWorkbench workbench; public IEditorPart open(URI uri, boolean select) { return open(uri, null, -1, select); } public IEditorPart open(URI uri, EReference crossReference, int indexInList, boolean select) { Iterator<Pair<IStorage, IProject>> storages = mapper.getStorages(uri.trimFragment()).iterator(); if (storages != null && storages.hasNext()) { try { IStorage storage = storages.next().getFirst(); IEditorInput editorInput = (storage instanceof IFile) ? new FileEditorInput((IFile) storage) : new XtextReadonlyEditorInput(storage); IWorkbenchPage activePage = workbench.getActiveWorkbenchWindow().getActivePage(); IEditorPart editor = IDE.openEditor(activePage, editorInput, XpectPluginActivator.XT_EDITOR_ID); selectAndReveal(editor, uri, crossReference, indexInList, select); return EditorUtils.getXtextEditor(editor); } catch (WrappedException e) { logger.error("Error while opening editor part for EMF URI '" + uri + "'", e.getCause()); } catch (PartInitException partInitException) { logger.error("Error while opening editor part for EMF URI '" + uri + "'", partInitException); } } return null; } protected void selectAndReveal(IEditorPart openEditor, final URI uri, final EReference crossReference, final int indexInList, final boolean select) { final XtextEditor xtextEditor = EditorUtils.getXtextEditor(openEditor); if (xtextEditor != null) { xtextEditor.getDocument().readOnly(new IUnitOfWork.Void<XtextResource>() { @Override public void process(XtextResource resource) throws Exception { if (resource == null) return; EObject object = findEObjectByURI(uri, resource); if (object == null) return; ILocationInFileProvider locationProvider = ((XtextResource) object.eResource()).getResourceServiceProvider().get(ILocationInFileProvider.class); ITextRegion location = (crossReference != null) ? locationProvider.getSignificantTextRegion(object, crossReference, indexInList) : locationProvider .getSignificantTextRegion(object); if (select) { xtextEditor.selectAndReveal(location.getOffset(), location.getLength()); } else { xtextEditor.reveal(location.getOffset(), location.getLength()); } } }); } } /** * @since 2.2 */ protected EObject findEObjectByURI(final URI uri, XtextResource resource) { if (uri.fragment() != null) { try { XtextResource xpectResource = XpectFileAccess.getXpectResource(resource); EObject result = xpectResource.getEObject(uri.fragment()); return result; } catch (WrappedException e) { } catch (IllegalArgumentException e) { } try { EObject result = resource.getEObject(uri.fragment()); return result; } catch (Exception e) { } } return null; } }