/******************************************************************************* * Copyright (c) 2000, 2015 QNX Software Systems 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: * QNX Software Systems - Initial API and implementation * Markus Schorn (Wind River Systems) * Norbert Ploett (Siemens AG) * Anton Leherbauer (Wind River Systems) * Ed Swartz (Nokia) *******************************************************************************/ package org.eclipse.cdt.internal.autotools.ui.editors.automake; import java.io.ByteArrayInputStream; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.IBinary; import org.eclipse.cdt.core.model.IBuffer; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.IIncludeReference; import org.eclipse.cdt.core.model.ISourceReference; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.IWorkingCopy; import org.eclipse.cdt.core.resources.FileStorage; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.core.filebuffers.FileBuffers; import org.eclipse.core.filesystem.URIUtil; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IStorage; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; 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.IEditorPart; import org.eclipse.ui.IEditorRegistry; import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.editors.text.EditorsUI; import org.eclipse.ui.part.FileEditorInput; public class EditorUtility { /** * The ID of the default text editor */ public static final String DEFAULT_TEXT_EDITOR_ID = EditorsUI.DEFAULT_TEXT_EDITOR_ID; private EditorUtility () { } private static IEditorPart openInEditor(IEditorInput input, String editorID, boolean activate) throws PartInitException { if (input != null) { IWorkbenchPage p= CUIPlugin.getActivePage(); if (p != null) { return p.openEditor(input, editorID, activate); } } return null; } private static IEditorInput getEditorInput(ICElement element) { while (element != null) { if (element instanceof ISourceReference) { ITranslationUnit tu = ((ISourceReference)element).getTranslationUnit(); if (tu != null) { element = tu; } } if (element instanceof IWorkingCopy && ((IWorkingCopy) element).isWorkingCopy()) element= ((IWorkingCopy) element).getOriginalElement(); if (element instanceof ITranslationUnit) { ITranslationUnit unit= (ITranslationUnit) element; IResource resource= unit.getResource(); if (resource instanceof IFile) { return new FileEditorInput((IFile) resource); } return new ExternalEditorInput(unit, new FileStorage(unit.getPath())); } if (element instanceof IBinary) { return new ExternalEditorInput(getStorage((IBinary)element), (IPath)null); } element= element.getParent(); } return null; } public static IEditorInput getEditorInput(Object input) { if (input instanceof ICElement) { return getEditorInput((ICElement) input); } if (input instanceof IFile) { return new FileEditorInput((IFile) input); } if (input instanceof IStorage) { return new ExternalEditorInput((IStorage)input); } return null; } /** * Utility method to open an editor for the given file system location * using {@link #getEditorInputForLocation(IPath, ICElement)} to create * the editor input. * * @param location a file system location * @param element an element related to the target file, may be <code>null</code> * @throws PartInitException */ public static IEditorPart openInEditor(IPath location, ICElement element) throws PartInitException { IEditorInput input= getEditorInputForLocation(location, element); return EditorUtility.openInEditor(input, getEditorID(input, element), true); } /** * Utility method to get an editor input for the given file system location. * If the location denotes a workspace file, a <code>FileEditorInput</code> * is returned, otherwise, the input is an <code>IStorageEditorInput</code> * assuming the location points to an existing file in the file system. * The <code>ICElement</code> is used to determine the associated project * in case the location can not be resolved to a workspace <code>IFile</code>. * * @param location a valid file system location * @param context an element related to the target file, may be <code>null</code> * @return an editor input */ public static IEditorInput getEditorInputForLocation(IPath location, ICElement context) { IFile resource= getWorkspaceFileAtLocation(location, context); if (resource != null) { return new FileEditorInput(resource); } if (context == null) { // try to synthesize a context for a location appearing on a project's // include paths try { ICProject[] projects = CCorePlugin.getDefault().getCoreModel().getCModel().getCProjects(); outerFor: for (int i = 0; i < projects.length; i++) { IIncludeReference[] includeReferences = projects[i].getIncludeReferences(); for (int j = 0; j < includeReferences.length; j++) { if (includeReferences[j].isOnIncludeEntry(location)) { context = projects[i]; break outerFor; } } } if (context == null && projects.length > 0) { // last resort: just take any of them context= projects[0]; } } catch (CModelException e) { } } if (context != null) { // try to get a translation unit from the location and associated element ICProject cproject= context.getCProject(); if (cproject != null) { ITranslationUnit unit = CoreModel.getDefault().createTranslationUnitFrom(cproject, location); if (unit != null) { return new ExternalEditorInput(unit, new FileStorage(location)); } // no translation unit - still try to get a sensible marker resource // from the associated element IResource markerResource= cproject.getProject(); return new ExternalEditorInput(new FileStorage(location), markerResource); } } return new ExternalEditorInput(new FileStorage(location)); } /** * Utility method to resolve a file system location to a workspace resource. * If a context element is given and there are multiple matches in the workspace, * a resource with the same project of the context element are preferred. * * @param location a valid file system location * @param context an element related to the target file, may be <code>null</code> * @return an <code>IFile</code> or <code>null</code> */ private static IFile getWorkspaceFileAtLocation(IPath location, ICElement context) { IFile file= FileBuffers.getWorkspaceFileAtLocation(location); if (file == null) { // try to find a linked resource IProject project= null; if (context != null) { ICProject cProject= context.getCProject(); if (cProject != null) { project= cProject.getProject(); } } IFile bestMatch= null; IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot(); IFile[] files= root.findFilesForLocationURI(URIUtil.toURI(location)); for (int i= 0; i < files.length; i++) { file= files[i]; if (file.isAccessible()) { if (project != null && file.getProject() == project) { bestMatch= file; break; } if (bestMatch == null) { bestMatch= file; if (project == null) { break; } } } } return bestMatch; } return file; } /** * Determine the editor id from the given file name using * the workspace-wide content-type definitions. * * @param name the file name * @return a valid editor id, never <code>null</code> */ public static String getEditorID(String name) { IEditorRegistry registry = PlatformUI.getWorkbench().getEditorRegistry(); if (registry != null) { IEditorDescriptor descriptor = registry.getDefaultEditor(name); if (descriptor != null) { return descriptor.getId(); } } return DEFAULT_TEXT_EDITOR_ID; } /** * Determine the editor id from the given editor input and optional input object. * When a translation unit can be obtained, the project-specific content-type * mechanism is used to determine the correct editor id. * If that fails, the editor id is determined by file name and extension using * the workspace-wide content-type definitions. * * @param input the editor input * @param inputObject the input object (used to create the editor input) or <code>null</code> * @return a valid editor id, never <code>null</code> */ public static String getEditorID(IEditorInput input, Object inputObject) { ITranslationUnit tunit = null; if (inputObject instanceof ITranslationUnit) { tunit= (ITranslationUnit)inputObject; } else if (input instanceof IFileEditorInput) { IFileEditorInput editorInput = (IFileEditorInput)input; IFile file = editorInput.getFile(); ICElement celement = CoreModel.getDefault().create(file); if (celement instanceof ITranslationUnit) { tunit = (ITranslationUnit)celement; } } else if (input instanceof ITranslationUnitEditorInput) { ITranslationUnitEditorInput editorInput = (ITranslationUnitEditorInput)input; tunit = editorInput.getTranslationUnit(); } if (tunit != null) { // Choose an editor based on the content type String contentTypeId= tunit.getContentTypeId(); if (contentTypeId != null) { IContentType contentType= Platform.getContentTypeManager().getContentType(contentTypeId); IEditorRegistry registry = PlatformUI.getWorkbench().getEditorRegistry(); IEditorDescriptor desc= registry.getDefaultEditor(input.getName(), contentType); if (desc != null) { return desc.getId(); } } // Choose an editor based on the language (obsolete?) if (tunit.isCLanguage()) { return CUIPlugin.EDITOR_ID; } else if (tunit.isCXXLanguage()) { return CUIPlugin.EDITOR_ID; } else if (tunit.isASMLanguage()) { return "org.eclipse.cdt.ui.editor.asm.AsmEditor"; //$NON-NLS-1$ } } // Choose an editor based on filename/extension String editorId = getEditorID(input.getName()); return editorId; } public static IStorage getStorage(IBinary bin) { IStorage store = null; try { IBuffer buffer = bin.getBuffer(); if (buffer != null) { store = new FileStorage (new ByteArrayInputStream(buffer.getContents().getBytes()), bin.getPath()); } } catch (CModelException e) { // nothing; } return store; } }