/***************************************************************************************** * Copyright (c) 2009 Andrey Loskutov. 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 Contributor: Andrey Loskutov - * initial API and implementation ****************************************************************************************/ package de.loskutov.anyedit.actions; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtension; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import de.loskutov.anyedit.AnyEditToolsPlugin; import de.loskutov.anyedit.IOpenEditorParticipant; import de.loskutov.anyedit.ui.editor.AbstractEditor; public class OpenFile extends AbstractOpenAction { static WeakReference<List<IOpenEditorParticipant>> weakRef = new WeakReference<List<IOpenEditorParticipant>>(null); public OpenFile() { super(); } @Override protected void handleAction(IDocument doc, ISelectionProvider selectionProvider, IEditorInput currentInput) { List<IOpenEditorParticipant> participants = getParticipants(); IFile file; try { file = guessFile(participants, doc, selectionProvider, currentInput); } catch (OperationCanceledException e) { return; } IEditorPart editorPart = openEditor(participants, doc, selectionProvider, currentInput, file); if (editorPart != null) { goToLine(participants, doc, selectionProvider, editorPart); } } private IFile guessFile(List<IOpenEditorParticipant> participants, IDocument doc, ISelectionProvider selectionProvider, IEditorInput currentInput) { for (int i = 0; i < participants.size(); i++) { IOpenEditorParticipant participant = participants.get(i); IFile file; try { file = participant.guessFile(doc, selectionProvider, currentInput, getViewPart()); } catch (OperationCanceledException e) { // forward throw e; } catch (Throwable e) { AnyEditToolsPlugin.logError("Error with '" + participant + "' in guessFile() call", e); continue; } if (file != null) { return file; } } return null; } private IEditorPart openEditor(List<IOpenEditorParticipant> participants, IDocument doc, ISelectionProvider selectionProvider, IEditorInput currentInput, IFile file) { for (int i = 0; i < participants.size(); i++) { IOpenEditorParticipant participant = participants.get(i); IEditorPart part = null; try { part = participant.openEditor(doc, selectionProvider, currentInput, file); } catch (OperationCanceledException e) { return null; } catch (Throwable e) { AnyEditToolsPlugin.logError("Error with '" + participant + "' in openEditor() call", e); continue; } if (part != null) { return part; } } return null; } private void goToLine(List<IOpenEditorParticipant> participants, IDocument doc, ISelectionProvider selectionProvider, IEditorPart editorPart) { for (int i = 0; i < participants.size(); i++) { IOpenEditorParticipant participant = participants.get(i); int line = -1; try { line = participant.guessLine(doc, selectionProvider, editorPart); } catch (OperationCanceledException e) { return; } catch (Throwable e) { AnyEditToolsPlugin.logError("Error with '" + participant + "' in guessLine() call", e); continue; } if (line >= 0) { if (line >= 0) { AbstractEditor aeditor = new AbstractEditor(editorPart); aeditor.selectAndReveal(line); } return; } } } private static List<IOpenEditorParticipant> getParticipants() { List<IOpenEditorParticipant> participants = weakRef.get(); if(participants == null){ participants = new ArrayList<IOpenEditorParticipant>(); weakRef = new WeakReference<List<IOpenEditorParticipant>>(participants); } else { return participants; } IExtensionRegistry registry = Platform.getExtensionRegistry(); IExtensionPoint point = registry.getExtensionPoint(AnyEditToolsPlugin.getId() + ".openEditorParticipants"); if (point == null) { return participants; } IExtension[] extensions = point.getExtensions(); for (int i = 0; i < extensions.length; i++) { IConfigurationElement[] elements = extensions[i].getConfigurationElements(); for (int j = 0; j < elements.length; j++) { Object object; try { object = elements[j].createExecutableExtension("class"); } catch (Throwable e) { AnyEditToolsPlugin.logError("Bad 'IOpenEditorParticipant': " + elements[j].getAttribute("class"), e); continue; } if (object instanceof IOpenEditorParticipant) { participants.add((IOpenEditorParticipant) object); } } } if (participants.size() <= 1) { return participants; } Collections.sort(participants, new Comparator<IOpenEditorParticipant>() { @Override public int compare(IOpenEditorParticipant o1, IOpenEditorParticipant o2) { if (o1 == null || o2 == null) { return 0; } // inverted order return getPrio(o2).compareTo(getPrio(o1)); } }); return participants; } private static Integer getPrio(IOpenEditorParticipant participant) { int prio = participant.getPriority(); prio = prio > IOpenEditorParticipant.PRIO_HIGH ? IOpenEditorParticipant.PRIO_HIGH : prio < IOpenEditorParticipant.PRIO_LOW ? IOpenEditorParticipant.PRIO_LOW : prio; return Integer.valueOf(prio); } }