/** * Copyright (c) 2005-2007 IBM Corporation 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: * IBM - Initial API and implementation */ package org.eclipse.emf.edit.ui.util; import java.io.IOException; import java.io.InputStream; import java.util.Arrays; import java.util.List; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.content.IContentType; import org.eclipse.ui.IEditorDescriptor; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorRegistry; import org.eclipse.ui.PlatformUI; import org.eclipse.emf.common.ui.URIEditorInput; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.common.util.UniqueEList; import org.eclipse.emf.ecore.resource.URIConverter; import org.eclipse.emf.edit.ui.EMFEditUIPlugin; /** * @since 2.2.0 */ public class EditUIUtil { public static URI getURI(IEditorInput editorInput) { URI result = null; if (editorInput instanceof URIEditorInput) { result = ((URIEditorInput)editorInput).getURI().trimFragment(); } else { result = URI.createURI(editorInput.getName()); } return result; } /** * Returns the default editor for a given file name. This method is like {@link IEditorRegistry#getDefaultEditor(String)}, * but it will not return <code>null</code> unless all applicable content types have no associated editor. * * @param fileName the file name in the system * @return the descriptor of the default editor, or <code>null</code> if not found * @since 2.4 */ public static IEditorDescriptor getDefaultEditor(String fileName) { return fileName != null && fileName.length() != 0 ? getDefaultEditor(fileName, Platform.getContentTypeManager().findContentTypesFor(fileName)) : null; } /** * Returns the default editor for a given contents and file name. * <p> * If a file name is not provided, the entire content type registry will be queried. For performance reasons, it is * highly recommended to provide a file name if available. * * @param contents an input stream * @param fileName the file name associated to the contents, or <code>null</code> * @return the descriptor of the default editor, or <code>null</code> if not found * @since 2.4 */ public static IEditorDescriptor getDefaultEditor(InputStream contents, String fileName) { if (contents != null) { try { return getDefaultEditor(fileName, Platform.getContentTypeManager().findContentTypesFor(contents, fileName)); } catch (IOException e) { EMFEditUIPlugin.INSTANCE.log(e); } } return getDefaultEditor(fileName); } private static IEditorDescriptor getDefaultEditor(String fileName, IContentType[] contentTypes) { IEditorRegistry editorRegistry = PlatformUI.getWorkbench().getEditorRegistry(); if (contentTypes.length == 0) { return editorRegistry.getDefaultEditor(fileName, null); } IEditorDescriptor result = null; for (int i = 0; result == null && i < contentTypes.length; i++) { result = editorRegistry.getDefaultEditor(fileName, contentTypes[i]); } return result; } /** * Returns the default editor for a given URI. This method actually attempts to open an input stream for the URI and * uses its contents, along with the filename (the URI's last segment), to obtain appropriate content types. * <p> * If a URI converter is specified, it is used to open the stream. Otherwise, the global default * {@link URIConverter#INSTANCE instance} is used. * * @param uri a URI * @param uriConverter URI converter from which to obtain an input stream, or <code>null</code> * @return the descriptor of the default editor, or <code>null</code> if not found * @since 2.4 */ public static IEditorDescriptor getDefaultEditor(URI uri, URIConverter uriConverter) { String fileName = URI.decode(uri.lastSegment()); if (uriConverter == null) { uriConverter = URIConverter.INSTANCE; } InputStream stream = null; try { stream = uriConverter.createInputStream(uri); return getDefaultEditor(stream, fileName); } catch (IOException e) { EMFEditUIPlugin.INSTANCE.log(e); return getDefaultEditor(fileName); } finally { close(stream); } } private static void close(InputStream stream) { if (stream != null) { try { stream.close(); } catch (IOException e) { EMFEditUIPlugin.INSTANCE.log(e); } } } /** * Returns the editors for a given file name. This method is like {@link IEditorRegistry#getEditors(String)}, * but its result will include editors for all applicable content types. * * @param fileName the file name in the system * @param defaultsOnly if <code>true</code>, only the default editor for each content type will be included in the result * @return the descriptors of the editors * @since 2.4 */ public static IEditorDescriptor[] getEditors(String fileName, boolean defaultsOnly) { return fileName != null && fileName.length() != 0 ? getEditors(fileName, Platform.getContentTypeManager().findContentTypesFor(fileName), defaultsOnly) : new IEditorDescriptor[0]; } /** * Returns the editors for a given contents and file name. * <p> * If a file name is not provided, the entire content type registry will be queried. For performance reasons, it is * highly recommended to provide a file name if available. * * @param contents an input stream * @param fileName the file name associated to the contents, or <code>null</code> * @param defaultsOnly if <code>true</code>, only the default editor for each content type will be included in the result * @return the descriptors of the editors * @since 2.4 */ public static IEditorDescriptor[] getEditors(InputStream contents, String fileName, boolean defaultsOnly) { if (contents != null) { try { return getEditors(fileName, Platform.getContentTypeManager().findContentTypesFor(contents, fileName), defaultsOnly); } catch (IOException e) { EMFEditUIPlugin.INSTANCE.log(e); } } return getEditors(fileName, defaultsOnly); } private static IEditorDescriptor[] getEditors(String fileName, IContentType[] contentTypes, boolean defaultsOnly) { IEditorRegistry editorRegistry = PlatformUI.getWorkbench().getEditorRegistry(); if (contentTypes.length == 0) { return editorRegistry.getEditors(fileName, null); } List<IEditorDescriptor> result = new UniqueEList<IEditorDescriptor>(); for (IContentType contentType : contentTypes) { if (defaultsOnly) { IEditorDescriptor editor = editorRegistry.getDefaultEditor(fileName, contentType); if (editor != null) { result.add(editor); } } else { result.addAll(Arrays.asList(editorRegistry.getEditors(fileName, contentType))); } } return result.toArray(new IEditorDescriptor[result.size()]); } /** * Returns the editors for a given URI. This method actually attempts to open an input stream for the URI and * uses its contents, along with the filename (the URI's last segment), to obtain appropriate content types. * <p> * If a URI converter is specified, it is used to open the stream. Otherwise, the global default * {@link URIConverter#INSTANCE instance} is used. * * @param uri a URI * @param uriConverter a URI converter from which to obtain an input stream, or <code>null</code> * @param defaultsOnly if <code>true</code>, only the default editor for each content type will be included in the result * @return the descriptors of the editors * @since 2.4 */ public static IEditorDescriptor[] getEditors(URI uri, URIConverter uriConverter, boolean defaultsOnly) { String fileName = URI.decode(uri.lastSegment()); if (uriConverter == null) { uriConverter = URIConverter.INSTANCE; } InputStream stream = null; try { stream = uriConverter.createInputStream(uri); return getEditors(stream, fileName, defaultsOnly); } catch (IOException e) { EMFEditUIPlugin.INSTANCE.log(e); return getEditors(fileName, defaultsOnly); } finally { close(stream); } } }