aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorszarnekow2009-03-12 16:10:06 (EDT)
committersefftinge2009-03-12 16:10:06 (EDT)
commita580428f3816b2603069236cde8bd3dac5e301a6 (patch)
tree3fbe5e91a01b57992a1ff97eff0ff4d4bd417513
parente5a7c073654e2860e64b0364b64197e5bc7ab877 (diff)
downloadorg.eclipse.xtext-a580428f3816b2603069236cde8bd3dac5e301a6.zip
org.eclipse.xtext-a580428f3816b2603069236cde8bd3dac5e301a6.tar.gz
org.eclipse.xtext-a580428f3816b2603069236cde8bd3dac5e301a6.tar.bz2
Feature: Navigate into resources from jars, navigate inside these resources, too
-rw-r--r--plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/hyperlinking/OpenDeclarationAction.java103
-rw-r--r--plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/ReadonlyArchiveStorage.java68
-rw-r--r--plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/ReadonlyFileStorage.java53
-rw-r--r--plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/ReadonlyStorage.java32
-rw-r--r--plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextReadonlyEditorInput.java67
-rw-r--r--plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/model/XtextDocument.java10
6 files changed, 308 insertions, 25 deletions
diff --git a/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/hyperlinking/OpenDeclarationAction.java b/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/hyperlinking/OpenDeclarationAction.java
index 19db946..d5981c6 100644
--- a/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/hyperlinking/OpenDeclarationAction.java
+++ b/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/hyperlinking/OpenDeclarationAction.java
@@ -1,14 +1,21 @@
package org.eclipse.xtext.ui.common.editor.hyperlinking;
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+
import org.apache.log4j.Logger;
import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
@@ -16,7 +23,10 @@ import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.ui.core.ILocationInFileProvider;
+import org.eclipse.xtext.ui.core.editor.ReadonlyArchiveStorage;
+import org.eclipse.xtext.ui.core.editor.ReadonlyFileStorage;
import org.eclipse.xtext.ui.core.editor.XtextEditor;
+import org.eclipse.xtext.ui.core.editor.XtextReadonlyEditorInput;
import org.eclipse.xtext.ui.core.editor.model.UnitOfWork;
/**
@@ -29,7 +39,7 @@ import org.eclipse.xtext.ui.core.editor.model.UnitOfWork;
public class OpenDeclarationAction extends Action {
// logger available to subclasses
- protected final Logger logger = Logger.getLogger(getClass());
+ private static final Logger logger = Logger.getLogger(OpenDeclarationAction.class);
private final URI uri;
@@ -53,36 +63,81 @@ public class OpenDeclarationAction extends Action {
public void doOpen(final URI uri) {
IFile file = getContainingResourceSetFile(uri);
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ IEditorPart openEditor = null;
try {
- IEditorPart openEditor = IDE.openEditor(page, file);
- if (openEditor instanceof XtextEditor) {
- final XtextEditor edit = (XtextEditor) openEditor;
- if (uri.fragment()!=null) {
- edit.getDocument().readOnly(new UnitOfWork<Object>(){
-
- public Object exec(XtextResource resource) throws Exception {
- EObject object = resource.getEObject(uri.fragment());
- Region region = locationProvider.getLocation(object);
- edit.selectAndReveal(region.getOffset(),region.getLength());
- return null;
- }});
- }
- } else if (openEditor instanceof ISelectionProvider) {
- //TODO: use ISelectionProvider instead of ITextEditor
+ if (file != null) {
+ openEditor = IDE.openEditor(page, file);
+ } else if (uri.isArchive()) {
+ // TODO don't fall back to java.io
+ IEditorInput input = new XtextReadonlyEditorInput(new ReadonlyArchiveStorage(uri));
+ openEditor = IDE.openEditor(page, input, PlatformUI.getWorkbench().getEditorRegistry()
+ .getDefaultEditor(uri.lastSegment()).getId());
+ } else {
+ // fall back: URI is bundle resource uri and has to converted
+ URL url = FileLocator.toFileURL(new URL(uri.scheme()+ ":" +uri.devicePath()));
+ URI urlAsUri = URI.createURI(url.toString());
+ String path = urlAsUri.toFileString();
+ File ioFile = new File(path);
+ // TODO don't fall back to java.io
+ IEditorInput input = new XtextReadonlyEditorInput(new ReadonlyFileStorage(ioFile, uri));
+ openEditor = IDE.openEditor(page, input, PlatformUI.getWorkbench().getEditorRegistry()
+ .getDefaultEditor(uri.lastSegment()).getId());
}
- }
- catch (PartInitException partInitException) {
+ } catch (PartInitException partInitException) {
logger.error("Error while opening editor part for EMF URI '" + uri + "'",
partInitException);
+ } catch (IOException e) {
+ logger.error("Error while opening editor part for EMF URI '" + uri + "'", e);
+ }
+ if (openEditor != null && openEditor instanceof XtextEditor) {
+ final XtextEditor edit = (XtextEditor) openEditor;
+ if (uri.fragment()!=null) {
+ edit.getDocument().readOnly(new UnitOfWork<Object>(){
+ public Object exec(XtextResource resource) throws Exception {
+ EObject object = resource.getEObject(uri.fragment());
+ Region region = locationProvider.getLocation(object);
+ edit.selectAndReveal(region.getOffset(),region.getLength());
+ return null;
+ }});
+ }
+ } else if (openEditor instanceof ISelectionProvider) {
+ //TODO: use ISelectionProvider instead of ITextEditor
}
}
private IFile getContainingResourceSetFile(URI uri) {
- IFile targetFile = uri.isPlatformResource() ?
- ResourcesPlugin.getWorkspace().getRoot().getFile(
- new Path(uri.toPlatformString(true)))
- : ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(
- new Path(uri.toFileString()));
- return targetFile;
+ String path = null;
+ if (uri.isPlatformResource()) {
+ path = uri.toPlatformString(true);
+ } else if (uri.isPlatformPlugin()) {
+ path = uri.toPlatformString(true);
+ } else if (uri.isFile()) {
+ path = uri.toFileString();
+ } else if (uri.isArchive()) {
+ URI archiveUri = URI.createURI(uri.authority());
+ String archive = null;
+ if (archiveUri.isFile()) {
+ archive = archiveUri.toFileString();
+ } else if (archiveUri.isPlatformResource()) {
+ archive = archiveUri.toPlatformString(true);
+ } else {
+ archive = archiveUri.toString();
+ }
+ path = uri.scheme() + ":" + archive + uri.path();
+ } else {
+ path = uri.toString();
+ }
+ IFile result = null;
+ if (uri.isPlatformResource()) {
+ result = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(path));
+ } else {
+ result = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(new Path(path));
+ if (result == null) {
+ IResource res = ResourcesPlugin.getWorkspace().getRoot().findMember(path);
+ if (res != null && (res instanceof IFile))
+ result = (IFile) res;
+ }
+ }
+ return result;
}
}
diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/ReadonlyArchiveStorage.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/ReadonlyArchiveStorage.java
new file mode 100644
index 0000000..c6639dd
--- /dev/null
+++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/ReadonlyArchiveStorage.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.eclipse.xtext.ui.core.editor;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.common.util.WrappedException;
+
+/**
+ * @author Sebastian Zarnekow - Initial contribution and API
+ */
+public class ReadonlyArchiveStorage extends ReadonlyStorage {
+
+ private final ZipFile file;
+
+ private final ZipEntry entry;
+
+ public ReadonlyArchiveStorage(URI uri) throws IOException {
+ super(URI.createURI(uri.scheme() + ":" + uri.devicePath()));
+ URI archiveUri = URI.createURI(uri.authority());
+ String archive = null;
+ if (archiveUri.isFile()) {
+ archive = archiveUri.toFileString();
+ } else if (archiveUri.isPlatformResource()) {
+ archive = archiveUri.toPlatformString(true);
+ } else {
+ archive = archiveUri.toString();
+ }
+ archive = archive.substring(0, archive.length() - 1);
+ File file = new File(archive);
+ if (!file.exists())
+ throw new IOException("file does not exist: " + uri);
+ this.file = new ZipFile(file);
+ String path = uri.path().substring(1);
+ this.entry = this.file.getEntry(path);
+ }
+
+ public InputStream getContents() throws CoreException {
+ try {
+ InputStream result = file.getInputStream(entry);
+ return result;
+ } catch (IOException e) {
+ throw new WrappedException(e);
+ }
+ }
+
+ public IPath getFullPath() {
+ return new Path(getURI().toString());
+ }
+
+ public String getName() {
+ return entry.getName();
+ }
+
+}
diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/ReadonlyFileStorage.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/ReadonlyFileStorage.java
new file mode 100644
index 0000000..c1192e1
--- /dev/null
+++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/ReadonlyFileStorage.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.eclipse.xtext.ui.core.editor;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.common.util.WrappedException;
+
+/**
+ * @author Sebastian Zarnekow - Initial contribution and API
+ */
+public class ReadonlyFileStorage extends ReadonlyStorage {
+
+ private final File file;
+
+ public ReadonlyFileStorage(File file, URI uri) throws IOException {
+ super(URI.createURI(uri.scheme()+ ":" +uri.devicePath()));
+ this.file = file;
+ if (!file.exists() || file.isDirectory())
+ throw new IOException("file does not exist or is a directory: " + file.getCanonicalPath());
+ }
+
+ public InputStream getContents() throws CoreException {
+ try {
+ return new FileInputStream(file);
+ }
+ catch (FileNotFoundException e) {
+ throw new WrappedException(e);
+ }
+ }
+
+ public IPath getFullPath() {
+ return new Path(getURI().toString());
+ }
+
+ public String getName() {
+ return file.getName();
+ }
+
+}
diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/ReadonlyStorage.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/ReadonlyStorage.java
new file mode 100644
index 0000000..03b5ee6
--- /dev/null
+++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/ReadonlyStorage.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.eclipse.xtext.ui.core.editor;
+
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.emf.common.util.URI;
+
+/**
+ * @author Sebastian Zarnekow - Initial contribution and API
+ */
+public abstract class ReadonlyStorage extends PlatformObject implements IStorage {
+
+ private final URI uri;
+
+ protected ReadonlyStorage(URI uri) {
+ this.uri = uri;
+ }
+ public boolean isReadOnly() {
+ return true;
+ }
+
+ public URI getURI() {
+ return uri;
+ }
+
+}
diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextReadonlyEditorInput.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextReadonlyEditorInput.java
new file mode 100644
index 0000000..23f0426
--- /dev/null
+++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextReadonlyEditorInput.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.eclipse.xtext.ui.core.editor;
+
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.IPersistableElement;
+import org.eclipse.ui.IStorageEditorInput;
+
+/**
+ * @author Sebastian Zarnekow - Initial contribution and API
+ */
+public class XtextReadonlyEditorInput extends PlatformObject implements IStorageEditorInput {
+
+ private final ReadonlyStorage storage;
+
+ public XtextReadonlyEditorInput(ReadonlyStorage storage) {
+ this.storage = storage;
+ }
+
+ public IStorage getStorage() throws CoreException {
+ return storage;
+ }
+
+ public boolean exists() {
+ return true;
+ }
+
+ public ImageDescriptor getImageDescriptor() {
+ return null;
+ }
+
+ public String getName() {
+ return storage.getName();
+ }
+
+ public IPersistableElement getPersistable() {
+ return null;
+ }
+
+ public String getToolTipText() {
+ return storage.getName();
+ }
+
+ public URI getURI() {
+ return storage.getURI();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return (obj == this || obj != null && (obj instanceof XtextReadonlyEditorInput) &&
+ storage.getFullPath().equals(((XtextReadonlyEditorInput)obj).storage.getFullPath()));
+ }
+
+ @Override
+ public int hashCode() {
+ return storage.getFullPath().hashCode();
+ }
+}
diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/model/XtextDocument.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/model/XtextDocument.java
index 37c99eb..e70df63 100644
--- a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/model/XtextDocument.java
+++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/model/XtextDocument.java
@@ -34,6 +34,7 @@ import org.eclipse.ui.IStorageEditorInput;
import org.eclipse.ui.ide.ResourceUtil;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.resource.XtextResourceSet;
+import org.eclipse.xtext.ui.core.editor.XtextReadonlyEditorInput;
import org.eclipse.xtext.ui.core.editor.model.IXtextDocumentContentObserver.Processor;
import org.eclipse.xtext.ui.core.editor.utils.ValidationJob;
import org.eclipse.xtext.ui.core.util.JdtClasspathUriResolver;
@@ -71,19 +72,26 @@ public class XtextDocument extends Document implements IXtextDocument {
}
IPath path = null;
+ Resource aResource = null;
+ URI uri = null;
if (file != null) {
path = file.getFullPath();
+ uri = URI.createPlatformResourceURI(path.toString(), true);
+ } else if (editorInput instanceof XtextReadonlyEditorInput){
+ uri = ((XtextReadonlyEditorInput) editorInput).getURI();
} else {
IStorageEditorInput storageInput = (IStorageEditorInput) editorInput;
try {
// TODO get the FQN of the resource
path = storageInput.getStorage().getFullPath();
+ uri = URI.createPlatformResourceURI(path.toString(), true);
}
catch (CoreException e) {
throw new WrappedException(e);
}
}
- Resource aResource = resourceSet.createResource(URI.createPlatformResourceURI(path.toString(), true));
+
+ aResource = resourceSet.createResource(uri);
if (!(aResource instanceof XtextResource))
throw new IllegalStateException("The resource factory registered for " + path
+ " is not an XtextResourceFactory. Make sure the right resource factory has been registered.");