Fixed: [ Issue 45 ] Protobuf-dt should be able to open files outside workspace https://code.google.com/p/protobuf-dt/issues/detail?id=45 Hyperlinking among types in external files works!
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/ProtobufUiModule.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/ProtobufUiModule.java index c7b82d9..9f6c7ab 100644 --- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/ProtobufUiModule.java +++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/ProtobufUiModule.java
@@ -9,10 +9,13 @@ package com.google.eclipse.protobuf.ui; import static com.google.inject.name.Names.named; +import static org.eclipse.ui.PlatformUI.isWorkbenchRunning; import org.eclipse.jface.text.hyperlink.IHyperlinkDetector; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.eclipse.ui.views.contentoutline.IContentOutlinePage; +import org.eclipse.xtext.ui.LanguageSpecific; +import org.eclipse.xtext.ui.editor.IURIEditorOpener; import org.eclipse.xtext.ui.editor.IXtextEditorCallback; import org.eclipse.xtext.ui.editor.model.XtextDocumentProvider; import org.eclipse.xtext.ui.editor.outline.actions.IOutlineContribution; @@ -20,6 +23,7 @@ import com.google.eclipse.protobuf.scoping.IFileUriResolver; import com.google.eclipse.protobuf.ui.builder.AutoAddNatureEditorCallback; +import com.google.eclipse.protobuf.ui.editor.ProtobufUriEditorOpener; import com.google.eclipse.protobuf.ui.editor.hyperlinking.ProtobufHyperlinkDetector; import com.google.eclipse.protobuf.ui.editor.model.ProtobufDocumentProvider; import com.google.eclipse.protobuf.ui.outline.LinkWithEditor; @@ -81,4 +85,11 @@ public void configureDocumentProvider(Binder binder) { binder.bind(XtextDocumentProvider.class).to(ProtobufDocumentProvider.class); } + + @Override public void configureLanguageSpecificURIEditorOpener(Binder binder) { + if (!isWorkbenchRunning())return; + binder.bind(IURIEditorOpener.class) + .annotatedWith(LanguageSpecific.class) + .to(ProtobufUriEditorOpener.class); + } }
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/ProtobufUriEditorOpener.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/ProtobufUriEditorOpener.java new file mode 100644 index 0000000..892de15 --- /dev/null +++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/ProtobufUriEditorOpener.java
@@ -0,0 +1,47 @@ +/* + * Copyright (c) 2011 Google Inc. + * + * 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 com.google.eclipse.protobuf.ui.editor; + +import static com.google.eclipse.protobuf.ui.util.Resources.URI_SCHEME_FOR_FILES; +import static org.eclipse.xtext.ui.editor.utils.EditorUtils.getXtextEditor; + +import org.apache.log4j.Logger; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.PartInitException; +import org.eclipse.xtext.ui.editor.LanguageSpecificURIEditorOpener; + +import com.google.eclipse.protobuf.ui.util.Resources; +import com.google.inject.Inject; + +/** + * @author alruiz@google.com (Alex Ruiz) + */ +public class ProtobufUriEditorOpener extends LanguageSpecificURIEditorOpener { + + private static Logger logger = Logger.getLogger(ProtobufUriEditorOpener.class); + + @Inject private Resources resources; + + /** {@inheritDoc} */ + @Override public IEditorPart open(URI uri, EReference crossReference, int indexInList, boolean select) { + if (URI_SCHEME_FOR_FILES.equals(uri.scheme())) { + try { + IEditorPart editor = resources.openProtoFileInFileSystem(uri.trimFragment()); + selectAndReveal(editor, uri, crossReference, indexInList, select); + return getXtextEditor(editor); + } catch (PartInitException e) { + logger.error("Unable to open " + uri.toString(), e); + } + } + return super.open(uri, crossReference, indexInList, select); + } + +}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/hyperlinking/ImportHyperlink.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/hyperlinking/ImportHyperlink.java index 93c741d..26c901a 100644 --- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/hyperlinking/ImportHyperlink.java +++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/hyperlinking/ImportHyperlink.java
@@ -8,16 +8,13 @@ */ package com.google.eclipse.protobuf.ui.editor.hyperlinking; -import org.eclipse.core.filesystem.EFS; -import org.eclipse.core.filesystem.IFileStore; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.runtime.Path; +import static com.google.eclipse.protobuf.ui.util.Resources.URI_SCHEME_FOR_FILES; + +import org.apache.log4j.Logger; import org.eclipse.emf.common.util.URI; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.hyperlink.IHyperlink; -import org.eclipse.ui.*; -import org.eclipse.ui.ide.FileStoreEditorInput; -import org.eclipse.ui.part.FileEditorInput; +import org.eclipse.ui.PartInitException; import com.google.eclipse.protobuf.ui.util.Resources; @@ -28,6 +25,8 @@ */ class ImportHyperlink implements IHyperlink { + private static Logger logger = Logger.getLogger(ImportHyperlink.class); + private final URI importUri; private final IRegion region; private final Resources resources; @@ -40,28 +39,11 @@ public void open() { String scheme = importUri.scheme(); - if ("platform".equals(scheme)) openFromWorkspace(); - if ("file".equals(scheme)) openFromFileSystem(); - } - - private void openFromWorkspace() { - IFile file = resources.file(importUri); - IEditorInput editorInput = new FileEditorInput(file); - openFile(editorInput, "com.google.eclipse.protobuf.Protobuf"); - } - - private void openFromFileSystem() { - IFileStore fileStore = EFS.getLocalFileSystem().getStore(new Path(importUri.toFileString())); - IEditorInput editorInput = new FileStoreEditorInput(fileStore); - openFile(editorInput, "com.google.eclipse.protobuf.Protobuf"/*"org.eclipse.ui.DefaultTextEditor"*/); - } - - private void openFile(IEditorInput editorInput, String editorId) { - IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); try { - page.openEditor(editorInput, editorId); + if ("platform".equals(scheme)) resources.openProtoFileInPlatform(importUri); + if (URI_SCHEME_FOR_FILES.equals(scheme)) resources.openProtoFileInFileSystem(importUri); } catch (PartInitException e) { - e.printStackTrace(); + logger.error("Unable to open " + importUri.toString(), e); } }
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/model/ProtobufDocumentProvider.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/model/ProtobufDocumentProvider.java index 2094ffa..ab59060 100644 --- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/model/ProtobufDocumentProvider.java +++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/model/ProtobufDocumentProvider.java
@@ -6,6 +6,7 @@ package com.google.eclipse.protobuf.ui.editor.model; import static com.google.eclipse.protobuf.ui.ProtobufUiModule.PLUGIN_ID; +import static com.google.eclipse.protobuf.ui.util.Resources.URI_SCHEME_FOR_FILES; import static java.util.Collections.singletonMap; import static org.eclipse.core.runtime.IStatus.ERROR; import static org.eclipse.emf.common.util.URI.createURI; @@ -46,7 +47,6 @@ public class ProtobufDocumentProvider extends XtextDocumentProvider { private static final String ENCODING = "UTF-8"; - private static final String FILE_SCHEME = "file"; @Inject private Closeables closeables; @Inject private IssueResolutionProvider issueResolutionProvider; @@ -111,8 +111,8 @@ private File fileFrom(IURIEditorInput input) { URI uri = input.getURI(); String scheme = uri.getScheme(); - if (scheme != FILE_SCHEME) { - String cleanUri = uri.toString().replaceFirst(scheme, FILE_SCHEME); + if (scheme != URI_SCHEME_FOR_FILES) { + String cleanUri = uri.toString().replaceFirst(scheme, URI_SCHEME_FOR_FILES); uri = URI.create(cleanUri); } return new File(uri);
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/Resources.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/Resources.java index 77ddd63..777cbab 100644 --- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/Resources.java +++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/Resources.java
@@ -8,12 +8,16 @@ */ package com.google.eclipse.protobuf.ui.util; +import org.eclipse.core.filesystem.EFS; +import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.resources.*; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.emf.common.util.URI; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.ui.*; +import org.eclipse.ui.ide.FileStoreEditorInput; +import org.eclipse.ui.part.FileEditorInput; import org.eclipse.ui.views.navigator.ResourceNavigator; import com.google.inject.Singleton; @@ -26,6 +30,8 @@ @Singleton public class Resources { + public static final String URI_SCHEME_FOR_FILES = "file"; + /** * Returns the project that contains the resource at the given URI. * @param resourceUri the given URI. @@ -61,6 +67,36 @@ } /** + * Opens the .proto file identified by the given URI. The .proto file exists in the workspace. + * @param uri the URI of the file to open. + * @return an open and active editor, or {@code null} if an external editor was opened. + * @throws PartInitException if the editor cannot be opened or initialized. + */ + public IEditorPart openProtoFileInPlatform(URI uri) throws PartInitException { + IFile file = file(uri); + IEditorInput editorInput = new FileEditorInput(file); + return openFile(editorInput); + } + + /** + * Opens the .proto file identified by the given URI. The .proto file does not exist in the workspace, therefore is + * opened from the file system. + * @param uri the URI of the file to open. + * @return an open and active editor, or {@code null} if an external editor was opened. + * @throws PartInitException if the editor cannot be created or initialized. + */ + public IEditorPart openProtoFileInFileSystem(URI uri) throws PartInitException { + IFileStore fileStore = EFS.getLocalFileSystem().getStore(new Path(uri.toFileString())); + IEditorInput editorInput = new FileStoreEditorInput(fileStore); + return openFile(editorInput/*"org.eclipse.ui.DefaultTextEditor"*/); + } + + private IEditorPart openFile(IEditorInput editorInput) throws PartInitException { + IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + return page.openEditor(editorInput, "com.google.eclipse.protobuf.Protobuf"); + } + + /** * Returns a handle to a workspace file identified by the given URI. * @param uri the given URI. * @return a handle to a workspace file identified by the given URI or {@code null} if the URI does not belong to a