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