Java tutorial
/******************************************************************************* * Copyright (c) 2014 Karlsruhe Institute of Technology, Germany * Technical University Darmstadt, Germany * Chalmers University of Technology, Sweden * 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: * Technical University Darmstadt - initial API and implementation and/or initial documentation *******************************************************************************/ package org.key_project.sed.ui.util; import java.net.URL; import java.util.Collections; import java.util.Deque; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; 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.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.debug.internal.ui.viewers.model.TreeModelContentProvider; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.debug.ui.IDebugView; import org.eclipse.jface.viewers.ContentViewer; import org.eclipse.jface.viewers.IContentProvider; import org.eclipse.jface.viewers.ILazyTreeContentProvider; import org.eclipse.jface.viewers.ILazyTreePathContentProvider; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.TreePath; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Widget; import org.eclipse.ui.IViewPart; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchWindow; import org.key_project.sed.core.annotation.ISEDAnnotationType; import org.key_project.sed.core.model.ISEDDebugElement; import org.key_project.sed.core.model.ISEDDebugNode; import org.key_project.sed.core.model.ISEDDebugTarget; import org.key_project.sed.core.provider.SEDDebugNodeContentProvider; import org.key_project.sed.core.provider.SEDDebugTargetContentProvider; import org.key_project.sed.core.util.LogUtil; import org.key_project.sed.core.util.SEDPreorderIterator; import org.key_project.sed.ui.Activator; import org.key_project.sed.ui.action.ISEDAnnotationAction; import org.key_project.sed.ui.action.ISEDAnnotationLinkAction; import org.key_project.sed.ui.action.ISEDAnnotationLinkEditAction; import org.key_project.sed.ui.edit.ISEDAnnotationEditor; import org.key_project.util.eclipse.JobUtil; import org.key_project.util.eclipse.WorkbenchUtil; import org.key_project.util.eclipse.job.AbstractDependingOnObjectsJob; import org.key_project.util.eclipse.job.ScheduledJobCollector; import org.key_project.util.eclipse.swt.SWTUtil; import org.key_project.util.java.ArrayUtil; import org.key_project.util.java.CollectionUtil; import org.key_project.util.java.IFilter; import org.key_project.util.java.ObjectUtil; import org.key_project.util.java.StringUtil; import org.key_project.util.java.thread.AbstractRunnableWithException; import org.key_project.util.java.thread.AbstractRunnableWithResult; import org.key_project.util.java.thread.IRunnableWithException; import org.key_project.util.java.thread.IRunnableWithResult; /** * Provides static methods which makes working with the Eclipse Debug UI and * SED UI easier. * @author Martin Hentschel */ @SuppressWarnings("restriction") public final class SEDUIUtil { /** * The ID Of the extension point with the annotation actions. */ public static final String ANNOTATION_ACTIONS = "org.key_project.sed.ui.annotationActions"; /** * The ID Of the extension point with the annotation editors. */ public static final String ANNOTATION_EDITORS = "org.key_project.sed.ui.annotationEditors"; /** * The ID Of the extension point with the annotation link actions. */ public static final String ANNOTATION_LINK_ACTIONS = "org.key_project.sed.ui.annotationLinkActions"; /** * The ID Of the extension point with the annotation link edit actions. */ public static final String ANNOTATION_LINK_EDIT_ACTIONS = "org.key_project.sed.ui.annotationLinkEditActions"; /** * The ID Of the extension point with the annotation type images. */ public static final String ANNOTATION_TYPE_IMAGES = "org.key_project.sed.ui.annotationTypeImages"; /** * Contains all available {@link SEDAnnotationActionDescription}s. */ private static final List<SEDAnnotationActionDescription> annotationActionDescriptions = createAnnotationActionDescriptions(); /** * Contains all available {@link SEDAnnotationLinkActionDescription}s. */ private static final List<SEDAnnotationLinkActionDescription> annotationLinkActionDescriptions = createAnnotationLinkActionDescriptions(); /** * All available {@link ISEDAnnotationLinkEditAction}s. */ private static final Map<String, ISEDAnnotationLinkEditAction> annotationLinkEditActions = createAnnotationLinkEditActions(); /** * All available {@link Image}s of {@link ISEDAnnotationType}s. */ private static final Map<String, Image> annotationTypeImages = createAnnotationTypeImages(); /** * Forbid instances. */ private SEDUIUtil() { } /** * Selects the given elements in the given {@link IDebugView}. * @param parentPart The current {@link IWorkbenchPart} which requests the selection change. * @param debugView The {@link IDebugView} to change selection in. * @param selection The new selection to set in the {@link IDebugView}. */ public static void selectInDebugView(IWorkbenchPart parentPart, final IDebugView debugView, ISelection selection) { selectInDebugView(parentPart, debugView, SWTUtil.toList(selection)); } /** * Selects the given elements in the given {@link IDebugView}. * @param parentPart The current {@link IWorkbenchPart} which requests the selection change. * @param debugView The {@link IDebugView} to change selection in. * @param selection The new selection to set in the {@link IDebugView}. */ public static void selectInDebugView(IWorkbenchPart parentPart, final IDebugView debugView, final List<?> selection) { // Make sure that the old selected business objects are different to the new one ISelection oldSelection = debugView.getViewer().getSelection(); if (!selection.equals(SWTUtil.toList(oldSelection))) { // Change selection in debug view if new elements are selected in a Job because the debug view uses Jobs itself to expand the debug model and it is required to wait for them. AbstractDependingOnObjectsJob.cancelJobs(parentPart); Job selectJob = new AbstractDependingOnObjectsJob("Synchronizing selection", parentPart) { @Override protected IStatus run(IProgressMonitor monitor) { try { // Expand viewer up to the elements to select. final Viewer debugViewer = debugView.getViewer(); if (debugViewer instanceof TreeViewer) { TreeViewer treeViewer = (TreeViewer) debugViewer; for (Object element : selection) { try { monitor.beginTask(getName(), IProgressMonitor.UNKNOWN); monitor.subTask("Collecting unknown elements"); Deque<Object> expandQue = collectUnknownElementsInParentHierarchy(treeViewer, element, monitor); monitor.beginTask(getName(), expandQue.size() + 1); monitor.subTask("Expanding unknown elements"); injectElements(treeViewer, expandQue, monitor); } catch (DebugException e) { LogUtil.getLogger() .logError("Can't expand debug view to element \"" + element + "\".", e); } } } // Select new elements monitor.subTask("Select element"); ISelection newSelection = SWTUtil.createSelection(selection); SWTUtil.select(debugViewer, newSelection, true); monitor.worked(1); monitor.done(); return Status.OK_STATUS; } catch (OperationCanceledException e) { return Status.CANCEL_STATUS; } } }; selectJob.schedule(); } } /** * Expands all given elements in the {@link IDebugView}. * @param parentPart The current {@link IWorkbenchPart} which requests the selection change. * @param debugView The {@link IDebugView} to change selection in. * @param toExpand The elements to expand. */ public static void expandInDebugView(IWorkbenchPart parentPart, final IDebugView debugView, final List<?> toExpand) { // Change selection in debug view if new elements are selected in a Job because the debug view uses Jobs itself to expand the debug model and it is required to wait for them. AbstractDependingOnObjectsJob.cancelJobs(parentPart); Job selectJob = new AbstractDependingOnObjectsJob("Expanding elements", parentPart) { @Override protected IStatus run(IProgressMonitor monitor) { try { final Viewer debugViewer = debugView.getViewer(); if (debugViewer instanceof TreeViewer) { // Collect elements to expand monitor.beginTask("Collecting unknown leafs", IProgressMonitor.UNKNOWN); List<ISEDDebugElement> leafs = new LinkedList<ISEDDebugElement>(); TreeViewer treeViewer = (TreeViewer) debugViewer; for (Object element : toExpand) { try { if (element instanceof ILaunch) { for (IDebugTarget target : ((ILaunch) element).getDebugTargets()) { if (target instanceof ISEDDebugTarget) { collectElementsToExpand(monitor, treeViewer, (ISEDDebugTarget) target, leafs); } } } else if (element instanceof ISEDDebugElement) { collectElementsToExpand(monitor, treeViewer, (ISEDDebugElement) element, leafs); } } catch (DebugException e) { LogUtil.getLogger().logError("Can't collect leafs of \"" + element + "\".", e); } } monitor.done(); // Inject unknown elements monitor.beginTask("Injecting paths to leafs (" + leafs.size() + ")", leafs.size()); for (ISEDDebugElement element : leafs) { try { SWTUtil.checkCanceled(monitor); monitor.subTask("Collecting unknown elements"); Deque<Object> expandQue = collectUnknownElementsInParentHierarchy(treeViewer, element, monitor); monitor.subTask("Injecting unknown elements"); injectElements(treeViewer, expandQue, monitor); monitor.worked(1); } catch (DebugException e) { LogUtil.getLogger().logError("Can't inject debug view element \"" + element + "\".", e); } } monitor.done(); // Expand elements monitor.beginTask("Expanding elements", toExpand.size()); for (Object element : toExpand) { SWTUtil.checkCanceled(monitor); SWTUtil.expandToLevel(treeViewer, element, TreeViewer.ALL_LEVELS); } monitor.done(); } monitor.done(); return Status.OK_STATUS; } catch (OperationCanceledException e) { return Status.CANCEL_STATUS; } } protected void collectElementsToExpand(IProgressMonitor monitor, TreeViewer treeViewer, ISEDDebugElement element, List<ISEDDebugElement> toFill) throws DebugException { SEDPreorderIterator iterator = new SEDPreorderIterator(element); while (iterator.hasNext()) { SWTUtil.checkCanceled(monitor); ISEDDebugElement next = iterator.next(); if (next instanceof ISEDDebugNode) { ISEDDebugNode node = (ISEDDebugNode) next; if (node.getChildren().length == 0) { // Test for leaf if (isUnknownInTreeViewer(treeViewer, node)) { // Test if leaf is unknown in the TreeViewer toFill.add(next); } } } monitor.worked(0); } } }; selectJob.schedule(); } /** * <p> * Collects all elements in the parent hierarchy starting from the given one * which are unknown in the given {@link TreeViewer}. * </p> * <p> * Unknown elements are possible if an {@link ILazyTreeContentProvider} or * an {@link ILazyTreePathContentProvider} is used. * </p> * @param treeViewer The {@link TreeViewer} to search in. * @param element The element to start search for unknown elements. * @param monitor The {@link IProgressMonitor} to use. * @return A {@link Deque} which contains all unknown elements in order from root to given element. * @throws DebugException Occurred Exception. */ protected static Deque<Object> collectUnknownElementsInParentHierarchy(final TreeViewer treeViewer, Object element, IProgressMonitor monitor) throws DebugException { Deque<Object> expandQue = new LinkedList<Object>(); while (element != null) { SWTUtil.checkCanceled(monitor); // Check if the element is unknown in tree if (isUnknownInTreeViewer(treeViewer, element)) { // Element is not known, add to deque and continue with parent. expandQue.addFirst(element); // Update current element for next loop iteration. element = getParent(element); } else { // Element is known in tree, search can be stopped. element = null; } } return expandQue; } /** * Checks if the given {@link Object} is unknown in the {@link TreeViewer}. * @param treeViewer The {@link TreeViewer}. * @param toTest The {@link Object} to test. * @return {@code true} is unknown, {@code false} is known. */ protected static boolean isUnknownInTreeViewer(final TreeViewer treeViewer, final Object toTest) { if (!treeViewer.getControl().isDisposed()) { IRunnableWithResult<Boolean> run = new AbstractRunnableWithResult<Boolean>() { @Override public void run() { Widget item = treeViewer.testFindItem(toTest); setResult(item == null); } }; treeViewer.getControl().getDisplay().syncExec(run); return run.getResult() != null && run.getResult().booleanValue(); } else { return false; } } /** * Computes the parent of the given element, because the used * {@link ILazyTreePathContentProvider} implementation * of the debug viewer returns {@code null} via * {@link ILazyTreePathContentProvider#getParents(Object)}. * @param element The current element. * @return The parent element if available or {@code null} otherwise. * @throws DebugException Occurred Exception. */ public static Object getParent(Object element) throws DebugException { if (element instanceof ISEDDebugNode) { return SEDDebugNodeContentProvider.getDefaultInstance().getDebugNodeParent(element); } else if (element instanceof ISEDDebugTarget) { return SEDDebugTargetContentProvider.getDefaultInstance().getParent(element); } else { return null; } } /** * Returns the children of the given {@link Object} shown in * the viewer of view "Debug". * @param element The element to get children for. * @return The available children. * @throws DebugException Occurred Exception. */ public static Object[] getChildren(Object element) throws DebugException { if (element instanceof ISEDDebugTarget) { return SEDDebugTargetContentProvider.getDefaultInstance().getAllChildren(element); } else if (element instanceof ISEDDebugNode) { return SEDDebugNodeContentProvider.getDefaultInstance().getAllDebugNodeChildren(element); } else { return null; } } /** * Injects all unknown elements of the {@link TreeViewer} in the * parent hierarchy order defined by the given {@link Deque}. * @param treeViewer The {@link TreeViewer} to make elements known in. * @param injectQue The {@link Deque} which contains the unknown elements from parent to leaf. * @param monitor The {@link IProgressMonitor} to use. * @throws DebugException Occurred Exception */ protected static void injectElements(final TreeViewer treeViewer, Deque<Object> injectQue, final IProgressMonitor monitor) throws DebugException { SWTUtil.checkCanceled(monitor); // Check if something must be done if (!CollectionUtil.isEmpty(injectQue)) { // Check if the provider is of the expected form. IContentProvider cp = treeViewer.getContentProvider(); if (cp instanceof ILazyTreePathContentProvider) { final ILazyTreePathContentProvider lazyContentProvider = (ILazyTreePathContentProvider) cp; // Create tree path to last known element final LinkedList<Object> tpElements = new LinkedList<Object>(); Object knownParent = getParent(injectQue.getFirst()); while (knownParent != null) { SWTUtil.checkCanceled(monitor); tpElements.addFirst(knownParent); knownParent = getParent(knownParent); } // Injects elements starting at the root to make them familiar in tree for (final Object toInject : injectQue) { SWTUtil.checkCanceled(monitor); // Compute index on parent Object parent = getParent(toInject); final int viewIndex = ArrayUtil.indexOf(getChildren(parent), toInject); if (viewIndex >= 0) { // Create tree path to current element final TreePath tp = new TreePath(tpElements.toArray()); // Create job collector to collect update jobs started by the Debug API IFilter<Job> jobFilter = new IFilter<Job>() { @Override public boolean select(Job element) { String className = element.getClass().getName(); return className.startsWith("org.eclipse.debug") || className.startsWith("org.eclipse.ui.internal.progress"); } }; ScheduledJobCollector collector = new ScheduledJobCollector(jobFilter); try { // Start collecting update jobs started by the debug view collector.start(); IRunnableWithException run = new AbstractRunnableWithException() { @Override public void run() { try { // Inject the element into the TreeViewer lazyContentProvider.updateChildCount(tp, 0); lazyContentProvider.updateElement(tp, viewIndex); } catch (Exception e) { setException(e); } } }; if (!treeViewer.getControl().isDisposed()) { treeViewer.getControl().getDisplay().syncExec(run); if (run.getException() != null) { throw new DebugException(LogUtil.getLogger().createErrorStatus( run.getException().getMessage(), run.getException())); } } else { monitor.setCanceled(true); } } finally { // Stop collecting update jobs collector.stop(); } // Wait until all update jobs have finished before Job[] jobs = collector.getJobs(); for (Job job : jobs) { SWTUtil.checkCanceled(monitor); JobUtil.waitFor(job, 10); } // Wait until the element is known by the viewer since sometimes waiting for jobs is not enough. int numOfTries = 0; while (!treeViewer.getControl().isDisposed() && SWTUtil.testFindItem(treeViewer, toInject) == null && numOfTries < 200) { // Try at most for two seconds SWTUtil.checkCanceled(monitor); try { Thread.sleep(10); } catch (InterruptedException e) { // Nothing to do. } finally { numOfTries++; } } // Update tree path for next loop iteration tpElements.add(toInject); // Update monitor monitor.worked(1); } else { // Something has changed in between and injection is not possible. monitor.setCanceled(true); } } } } } /** * Returns all available annotation action descriptions. * @return All available annotation action descriptions. */ public static List<SEDAnnotationActionDescription> getAnnotationActionDescriptions() { return annotationActionDescriptions; } /** * Creates all available {@link SEDAnnotationActionDescription}. * @return The available {@link SEDAnnotationActionDescription}. */ private static List<SEDAnnotationActionDescription> createAnnotationActionDescriptions() { List<SEDAnnotationActionDescription> descriptions = new LinkedList<SEDAnnotationActionDescription>(); // Add drivers registered by the extension point IExtensionRegistry registry = Platform.getExtensionRegistry(); if (registry != null) { IExtensionPoint point = registry.getExtensionPoint(ANNOTATION_ACTIONS); if (point != null) { // Analyze the extension point IExtension[] extensions = point.getExtensions(); for (IExtension extension : extensions) { IConfigurationElement[] configElements = extension.getConfigurationElements(); for (IConfigurationElement configElement : configElements) { try { String text = configElement.getAttribute("text"); ISEDAnnotationAction action = (ISEDAnnotationAction) configElement .createExecutableExtension("class"); String imagePath = configElement.getAttribute("icon"); String toolTipText = configElement.getAttribute("toolTipText"); Image image = null; ; if (!StringUtil.isEmpty(imagePath)) { URL url = Activator.getDefault().getBundle().getResource(imagePath); if (url != null) { image = new Image(Display.getDefault(), url.openStream()); } } descriptions.add(new SEDAnnotationActionDescription(text, image, toolTipText, action)); } catch (Exception e) { LogUtil.getLogger().logError(e); } } } } else { LogUtil.getLogger().logError("Extension point \"" + ANNOTATION_ACTIONS + "\" doesn't exist."); } } else { LogUtil.getLogger().logError("Extension point registry is not loaded."); } return Collections.unmodifiableList(descriptions); } /** * Returns all available annotation action descriptions. * @return All available annotation action descriptions. */ public static List<SEDAnnotationLinkActionDescription> getAnnotationLinkActionDescriptions() { return annotationLinkActionDescriptions; } /** * Creates all available {@link SEDAnnotationActionDescription}. * @return The available {@link SEDAnnotationActionDescription}. */ private static List<SEDAnnotationLinkActionDescription> createAnnotationLinkActionDescriptions() { List<SEDAnnotationLinkActionDescription> descriptions = new LinkedList<SEDAnnotationLinkActionDescription>(); // Add drivers registered by the extension point IExtensionRegistry registry = Platform.getExtensionRegistry(); if (registry != null) { IExtensionPoint point = registry.getExtensionPoint(ANNOTATION_LINK_ACTIONS); if (point != null) { // Analyze the extension point IExtension[] extensions = point.getExtensions(); for (IExtension extension : extensions) { IConfigurationElement[] configElements = extension.getConfigurationElements(); for (IConfigurationElement configElement : configElements) { try { String text = configElement.getAttribute("text"); ISEDAnnotationLinkAction action = (ISEDAnnotationLinkAction) configElement .createExecutableExtension("class"); String imagePath = configElement.getAttribute("icon"); String toolTipText = configElement.getAttribute("toolTipText"); Image image = null; ; if (!StringUtil.isEmpty(imagePath)) { URL url = Activator.getDefault().getBundle().getResource(imagePath); if (url != null) { image = new Image(Display.getDefault(), url.openStream()); } } descriptions .add(new SEDAnnotationLinkActionDescription(text, image, toolTipText, action)); } catch (Exception e) { LogUtil.getLogger().logError(e); } } } } else { LogUtil.getLogger().logError("Extension point \"" + ANNOTATION_LINK_ACTIONS + "\" doesn't exist."); } } else { LogUtil.getLogger().logError("Extension point registry is not loaded."); } return Collections.unmodifiableList(descriptions); } /** * Provides the basic implementation of action descriptions. * @author Martin Hentschel */ public static abstract class AbstractActionDescription { /** * The text. */ private final String text; /** * The image. */ private final Image image; /** * The tool tip text. */ private final String toolTipText; /** * Constructor. * @param text The text. * @param image The image. * @param toolTipText The tool tip text. */ public AbstractActionDescription(String text, Image image, String toolTipText) { this.text = text; this.image = image; this.toolTipText = toolTipText; } /** * Returns the text. * @return The text. */ public String getText() { return text; } /** * Returns the image. * @return The image. */ public Image getImage() { return image; } /** * Returns the tool tip text. * @return The tool tip text. */ public String getToolTipText() { return toolTipText; } } /** * An annotation action description with the content * provided via the extension point {@link SEDUIUtil#ANNOTATION_ACTIONS}. * @author Martin Hentschel */ public static final class SEDAnnotationActionDescription extends AbstractActionDescription { /** * The {@link ISEDAnnotationAction}. */ private final ISEDAnnotationAction action; /** * Constructor. * @param text The text. * @param image The image. * @param toolTipText The tool tip text. * @param action The {@link ISEDAnnotationAction}. */ public SEDAnnotationActionDescription(String text, Image image, String toolTipText, ISEDAnnotationAction action) { super(text, image, toolTipText); this.action = action; } /** * Returns the {@link ISEDAnnotationAction}. * @return The {@link ISEDAnnotationAction}. */ public ISEDAnnotationAction getAction() { return action; } } /** * An annotation action description with the content * provided via the extension point {@link SEDUIUtil#ANNOTATION_LINK_ACTIONS}. * @author Martin Hentschel */ public static final class SEDAnnotationLinkActionDescription extends AbstractActionDescription { /** * The {@link ISEDAnnotationLinkAction}. */ private final ISEDAnnotationLinkAction action; /** * Constructor. * @param text The text. * @param image The image. * @param toolTipText The tool tip text. * @param action The {@link ISEDAnnotationLinkAction}. */ public SEDAnnotationLinkActionDescription(String text, Image image, String toolTipText, ISEDAnnotationLinkAction action) { super(text, image, toolTipText); this.action = action; } /** * Returns the {@link ISEDAnnotationLinkAction}. * @return The {@link ISEDAnnotationLinkAction}. */ public ISEDAnnotationLinkAction getAction() { return action; } } /** * Returns the {@link ISEDAnnotationEditor} for the given {@link ISEDAnnotationType}. * @param type The {@link ISEDAnnotationType}. * @return A fresh created {@link ISEDAnnotationEditor} or {@code null} if not available. */ public static ISEDAnnotationEditor getAnnotationEditor(ISEDAnnotationType type) { return type != null ? getAnnotationEditor(type.getTypeId()) : null; } /** * Returns the {@link ISEDAnnotationEditor} for the given annotation type ID. * @param typeId The given annotation type ID. * @return A fresh created {@link ISEDAnnotationEditor} or {@code null} if not available. */ public static ISEDAnnotationEditor getAnnotationEditor(String typeId) { ISEDAnnotationEditor result = null; // Add drivers registered by the extension point IExtensionRegistry registry = Platform.getExtensionRegistry(); if (registry != null) { IExtensionPoint point = registry.getExtensionPoint(ANNOTATION_EDITORS); if (point != null) { // Analyze the extension point IExtension[] extensions = point.getExtensions(); int i = 0; while (result == null && i < extensions.length) { IConfigurationElement[] configElements = extensions[i].getConfigurationElements(); for (IConfigurationElement configElement : configElements) { try { String annotationTypeID = configElement.getAttribute("annotationTypeID"); if (ObjectUtil.equals(annotationTypeID, typeId)) { result = (ISEDAnnotationEditor) configElement.createExecutableExtension("class"); } } catch (Exception e) { LogUtil.getLogger().logError(e); } } i++; } } else { LogUtil.getLogger().logError("Extension point \"" + ANNOTATION_EDITORS + "\" doesn't exist."); } } else { LogUtil.getLogger().logError("Extension point registry is not loaded."); } return result; } /** * Returns the {@link ISEDAnnotationLinkEditAction} for the given annotation type id. * @param annotationTypeID The annotation type id. * @return The {@link ISEDAnnotationLinkEditAction} if available or {@code null} otherwise. */ public static ISEDAnnotationLinkEditAction getAnnotationLinkEditAction(String annotationTypeID) { return annotationLinkEditActions.get(annotationTypeID); } /** * Lists all available {@link ISEDAnnotationLinkEditAction}s. * @return All available {@link ISEDAnnotationLinkEditAction}s. */ private static Map<String, ISEDAnnotationLinkEditAction> createAnnotationLinkEditActions() { Map<String, ISEDAnnotationLinkEditAction> result = new HashMap<String, ISEDAnnotationLinkEditAction>(); // Add drivers registered by the extension point IExtensionRegistry registry = Platform.getExtensionRegistry(); if (registry != null) { IExtensionPoint point = registry.getExtensionPoint(ANNOTATION_LINK_EDIT_ACTIONS); if (point != null) { // Analyze the extension point IExtension[] extensions = point.getExtensions(); for (IExtension extension : extensions) { IConfigurationElement[] configElements = extension.getConfigurationElements(); for (IConfigurationElement configElement : configElements) { try { String annotationTypeID = configElement.getAttribute("annotationTypeID"); ISEDAnnotationLinkEditAction editAction = result.get(annotationTypeID); if (editAction == null) { result.put(annotationTypeID, (ISEDAnnotationLinkEditAction) configElement .createExecutableExtension("class")); } else { LogUtil.getLogger().logError("Annotion link edit action for annotation type \"" + annotationTypeID + "\" already found."); } } catch (Exception e) { LogUtil.getLogger().logError(e); } } } } else { LogUtil.getLogger() .logError("Extension point \"" + ANNOTATION_LINK_EDIT_ACTIONS + "\" doesn't exist."); } } else { LogUtil.getLogger().logError("Extension point registry is not loaded."); } return result; } /** * Returns the {@link IDebugView} shown in the given {@link Shell} if available. * @param shell The {@link Shell} to search the {@link IDebugView} in. * @return The found {@link IDebugView} or {@code null} if not available. */ public static IDebugView getDebugView(Shell shell) { IWorkbenchWindow window = WorkbenchUtil.findWorkbenchWindow(shell); if (window != null) { IViewPart view = window.getActivePage().findView(IDebugUIConstants.ID_DEBUG_VIEW); return view instanceof IDebugView ? (IDebugView) view : null; } else { return null; } } /** * Returns the image of the given {@link ISEDAnnotationType}. * @param type The {@link ISEDAnnotationType}. * @return The found {@link Image} or {@code null} if not available. */ public static Image getAnnotationTypeImage(ISEDAnnotationType type) { if (type != null) { return getAnnotationTypeImage(type.getTypeId()); } else { return null; } } /** * Returns the image for the annotation type ID. * @param annotationTypeID The annotation type ID. * @return The found {@link Image} or {@code null} if not available. */ public static Image getAnnotationTypeImage(String annotationTypeID) { return annotationTypeImages.get(annotationTypeID); } /** * Creates all available annotation type images. * @return The available annotation type images. */ private static Map<String, Image> createAnnotationTypeImages() { Map<String, Image> result = new HashMap<String, Image>(); // Add drivers registered by the extension point IExtensionRegistry registry = Platform.getExtensionRegistry(); if (registry != null) { IExtensionPoint point = registry.getExtensionPoint(ANNOTATION_TYPE_IMAGES); if (point != null) { // Analyze the extension point IExtension[] extensions = point.getExtensions(); for (IExtension extension : extensions) { IConfigurationElement[] configElements = extension.getConfigurationElements(); for (IConfigurationElement configElement : configElements) { try { String annotationTypeID = configElement.getAttribute("annotationTypeID"); Image image = result.get(annotationTypeID); if (image == null) { String imagePath = configElement.getAttribute("icon"); image = null; ; if (!StringUtil.isEmpty(imagePath)) { URL url = Activator.getDefault().getBundle().getResource(imagePath); if (url != null) { image = new Image(Display.getDefault(), url.openStream()); result.put(annotationTypeID, image); } } } else { LogUtil.getLogger().logError("Annotion link edit action for annotation type \"" + annotationTypeID + "\" already found."); } } catch (Exception e) { LogUtil.getLogger().logError(e); } } } } else { LogUtil.getLogger().logError("Extension point \"" + ANNOTATION_TYPE_IMAGES + "\" doesn't exist."); } } else { LogUtil.getLogger().logError("Extension point registry is not loaded."); } return result; } /** * Returns the {@link TreeModelContentProvider} used in the given {@link IDebugView}. * @param debugView The {@link IDebugView} to get its {@link TreeModelContentProvider}. * @return The {@link TreeModelContentProvider} or {@code null} if not available. */ public static TreeModelContentProvider getContentProvider(IDebugView debugView) { TreeModelContentProvider result = null; if (debugView != null) { Viewer viewer = debugView.getViewer(); if (viewer instanceof ContentViewer) { IContentProvider cp = ((ContentViewer) viewer).getContentProvider(); if (cp instanceof TreeModelContentProvider) { result = (TreeModelContentProvider) cp; } } } return result; } }