Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Leherbauer2011-09-21 07:51:29 -0400
committerAnton Leherbauer2011-12-21 08:11:35 -0500
commitc7803d38e9dfeae5e842eaca263450268f12a3dc (patch)
treea8c10f066148a9843b9d8b60c55ea894bb5f7e3c /debug/org.eclipse.cdt.debug.ui
parent2dea3d4a339d49579b06d13399e66adb03556fd8 (diff)
downloadorg.eclipse.cdt-c7803d38e9dfeae5e842eaca263450268f12a3dc.tar.gz
org.eclipse.cdt-c7803d38e9dfeae5e842eaca263450268f12a3dc.tar.xz
org.eclipse.cdt-c7803d38e9dfeae5e842eaca263450268f12a3dc.zip
Bug 366942 - [disassembly] Extension point for contributing ruler columns
Diffstat (limited to 'debug/org.eclipse.cdt.debug.ui')
-rw-r--r--debug/org.eclipse.cdt.debug.ui/META-INF/MANIFEST.MF1
-rw-r--r--debug/org.eclipse.cdt.debug.ui/plugin.properties3
-rw-r--r--debug/org.eclipse.cdt.debug.ui/plugin.xml1
-rw-r--r--debug/org.eclipse.cdt.debug.ui/schema/disassemblyRulerColumns.exsd269
-rw-r--r--debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/preferences/StringSetSerializer.java56
-rw-r--r--debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/disassembly/rulers/AbstractContributedRulerColumn.java66
-rw-r--r--debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/disassembly/rulers/IColumnSupport.java62
-rw-r--r--debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/disassembly/rulers/IContributedRulerColumn.java99
-rw-r--r--debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/disassembly/rulers/RulerColumnDescriptor.java309
-rw-r--r--debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/disassembly/rulers/RulerColumnPreferenceAdapter.java89
-rw-r--r--debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/disassembly/rulers/RulerColumnRegistry.java294
11 files changed, 1249 insertions, 0 deletions
diff --git a/debug/org.eclipse.cdt.debug.ui/META-INF/MANIFEST.MF b/debug/org.eclipse.cdt.debug.ui/META-INF/MANIFEST.MF
index e353bd2dc7..934302b9c8 100644
--- a/debug/org.eclipse.cdt.debug.ui/META-INF/MANIFEST.MF
+++ b/debug/org.eclipse.cdt.debug.ui/META-INF/MANIFEST.MF
@@ -33,6 +33,7 @@ Export-Package:
org.eclipse.cdt.debug.ui.breakpointactions,
org.eclipse.cdt.debug.ui.breakpoints,
org.eclipse.cdt.debug.ui.disassembly,
+ org.eclipse.cdt.debug.ui.disassembly.rulers,
org.eclipse.cdt.debug.ui.editors,
org.eclipse.cdt.debug.ui.importexecutable,
org.eclipse.cdt.debug.ui.preferences,
diff --git a/debug/org.eclipse.cdt.debug.ui/plugin.properties b/debug/org.eclipse.cdt.debug.ui/plugin.properties
index 719707c823..c60a7ff9ee 100644
--- a/debug/org.eclipse.cdt.debug.ui/plugin.properties
+++ b/debug/org.eclipse.cdt.debug.ui/plugin.properties
@@ -226,3 +226,6 @@ CastingCategory.name = Cast to Type or Array
# Pin & Clone
PinView.name = Pin to Debug Context
OpenNewView.name = Open New View
+
+# Disassembly Ruler Column extension point
+extPoint.disassemblyRulerColumn=Disassembly Ruler Column
diff --git a/debug/org.eclipse.cdt.debug.ui/plugin.xml b/debug/org.eclipse.cdt.debug.ui/plugin.xml
index 7bb1df689b..bcff9995a9 100644
--- a/debug/org.eclipse.cdt.debug.ui/plugin.xml
+++ b/debug/org.eclipse.cdt.debug.ui/plugin.xml
@@ -5,6 +5,7 @@
<extension-point id="CDebuggerPage" name="%CDebuggerPage" schema="schema/CDebuggerPage.exsd"/>
<extension-point id="BreakpointActionPage" name="%BreakpointActionPage" schema="schema/BreakpointActionPage.exsd"/>
<extension-point id="breakpointContribution" name="%breakpointContribution" schema="schema/BreakpointUIContribution.exsd"/>
+ <extension-point id="disassemblyRulerColumns" name="%extPoint.disassemblyRulerColumn" schema="schema/disassemblyRulerColumns.exsd"/>
<!-- Extensions -->
<extension
diff --git a/debug/org.eclipse.cdt.debug.ui/schema/disassemblyRulerColumns.exsd b/debug/org.eclipse.cdt.debug.ui/schema/disassemblyRulerColumns.exsd
new file mode 100644
index 0000000000..5a8315aaaa
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/schema/disassemblyRulerColumns.exsd
@@ -0,0 +1,269 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.cdt.debug.ui" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.cdt.debug.ui" id="disassemblyRulerColumns" name="Disassembly Ruler Column"/>
+ </appInfo>
+ <documentation>
+ Ruler column contributions are line based information areas that are normally shown in the vertical ruler area of the disassembly.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appInfo>
+ <meta.element />
+ </appInfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="column" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+ a fully qualified identifier of the target extension point
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+ an optional identifier of the extension instance
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ an optional name of the extension instance
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="column">
+ <annotation>
+ <appInfo>
+ <meta.element labelAttribute="name" icon="icon"/>
+ </appInfo>
+ <documentation>
+ The specification of a ruler column contribution.
+ </documentation>
+ </annotation>
+ <complexType>
+ <sequence>
+ <choice minOccurs="1" maxOccurs="unbounded">
+ <element ref="targetId"/>
+ <element ref="targetClass"/>
+ </choice>
+ <element ref="placement"/>
+ </sequence>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ the unique id of this column
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ an optional name of the column, may be used in the user interface (e.g. in preference pages)
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="icon" type="string">
+ <annotation>
+ <documentation>
+ an optional icon for the column. May be used in the user interface, for example on preference pages.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="resource"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ the class implementing the column; must implement &lt;code&gt;org.eclipse.cdt.debug.ui.disassembly.rulers.IContributedRulerColumn&lt;/code&gt;
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.cdt.debug.ui.disassembly.rulers.IContributedRulerColumn"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="enabled" type="boolean" use="default" value="true">
+ <annotation>
+ <documentation>
+ the default enablement state of this column
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="global" type="boolean" use="default" value="true">
+ <annotation>
+ <documentation>
+ controls whether toggling the visibility of this column operates on all targeted disassembly parts, or only the active disassembly part. If true, the ruler is added to all applicable parts when the user enables the column; if false, the ruler is only added to the active disassembly part.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="includeInMenu" type="boolean" use="default" value="true">
+ <annotation>
+ <documentation>
+ whether to include a &quot;Show/Hide&quot; menu entry for this column in the ruler context menu
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="targetId">
+ <annotation>
+ <documentation>
+ Describes a disassembly part that the column is contributed to.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ the part id of the target disassembly part
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.ui.editors/editor/@id"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="targetClass">
+ <annotation>
+ <documentation>
+ Describes a disassembly part class that the column is contributed to. Subclasses of the specified class are also targeted by this colum contribution.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ the fully qualified name of a class implementing IWorkbenchPart. The class does not need to be instantiatable.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.ui.IWorkbenchPart"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="placement">
+ <annotation>
+ <documentation>
+ Describes the placement of this ruler column relative to other contributed columns. A column may request to be placed &lt;em&gt;before&lt;/em&gt; or &lt;em&gt;after&lt;/em&gt; other known columns (identified by their &lt;tt&gt;id&lt;/tt&gt;). Columns that would end up at the same position are ordered by &lt;em&gt;gravity&lt;/em&gt; (see below). If the ordering is contradicting or no ordering can be found that fulfills all placement requests, some placement requirements are dropped until the placement can be achieved. If a column does not fully specify its placement it will be placed at an arbitrary but consistent location.
+ </documentation>
+ </annotation>
+ <complexType>
+ <sequence minOccurs="0" maxOccurs="unbounded">
+ <choice>
+ <element ref="before"/>
+ <element ref="after"/>
+ </choice>
+ </sequence>
+ <attribute name="gravity" type="string" use="default" value="1.0">
+ <annotation>
+ <documentation>
+ a float number between 0.0 and 1.0 that tells how close the column wants to be to the editor, where 0.0 means as far away as possible and 1.0 means as close as possible. After all &lt;i&gt;before&lt;/i&gt; and &lt;i&gt;after&lt;/i&gt; constraints are evaluated, columns that would end up at the same position are ordered by their &lt;i&gt;gravity&lt;/i&gt; value.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="before">
+ <annotation>
+ <documentation>
+ Requests placement before another column. The meaning of &lt;i&gt;before&lt;/i&gt; is similar to the SWT.LEAD flag: In left-to-right environments, &lt;i&gt;before&lt;/i&gt; means &lt;i&gt;to the left of&lt;/i&gt;, in right-to-left environments, it means &lt;i&gt;to the right of&lt;/i&gt;.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ the id of another &lt;tt&gt;rulerColumns&lt;/tt&gt; contribution
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.cdt.debug.ui.disassemblyRulerColumns/column/@id"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="after">
+ <annotation>
+ <documentation>
+ Requests placement after another column. The meaning of &lt;i&gt;after&lt;/i&gt; is similar to the SWT.TRAIL flag: In left-to-right environments, &lt;i&gt;after&lt;/i&gt; means &lt;i&gt;to the right of&lt;/i&gt;, in right-to-left environments, it means &lt;i&gt;to the left of&lt;/i&gt;.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ the id of another &lt;tt&gt;rulerColumns&lt;/tt&gt; contribution
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.cdt.debug.ui.disassemblyRulerColumns/column/@id"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ 7.2
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ The extension point is supported by the &lt;tt&gt;org.eclipse.cdt.debug.ui.disassembly.rulers&lt;/tt&gt; package. &lt;code&gt;RulerColumnRegistry&lt;/code&gt; gives access to all contributions, which in turn are described by &lt;code&gt;RulerColumnDescriptor&lt;/code&gt; instances.
+ </documentation>
+ </annotation>
+
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ All ruler column contributions must implement &lt;code&gt;org.eclipse.cdt.debug.ui.disassembly.rulers.IContributedRulerColumn&lt;/code&gt;. Many contributors will find the supplied &lt;code&gt;org.eclipse.cdt.debug.ui.disassembly.rulers.AbstractContributedRulerColumn&lt;/code&gt; useful which serves as super class for contributed ruler columns. Others might start off &lt;code&gt;org.eclipse.jface.text.source.AbstractRulerColumn&lt;/code&gt; which takes over most painting and scrolling aspects of a line based column and can be extended at various granularity levels. Those subclassing the latter class will have to implement &lt;code&gt;org.eclipse.cdt.debug.ui.disassembly.rulers.IContributedRulerColumn&lt;/code&gt; on their own by using &lt;code&gt;org.eclipse.cdt.debug.ui.disassembly.rulers.AbstractContributedRulerColumn&lt;/code&gt; as template.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ Copyright (c) 2006, 20011 IBM Corporation and others.&lt;br&gt;
+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 &lt;a href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/preferences/StringSetSerializer.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/preferences/StringSetSerializer.java
new file mode 100644
index 0000000000..68f71ebed2
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/preferences/StringSetSerializer.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2008 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 Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.debug.internal.ui.preferences;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.eclipse.core.runtime.Assert;
+
+public final class StringSetSerializer {
+ private static final String DELIM= "\0"; //$NON-NLS-1$
+ private StringSetSerializer() {
+ }
+
+ public static String serialize(Set<String> strings) {
+ Assert.isLegal(strings != null);
+ @SuppressWarnings("null")
+ StringBuffer buf= new StringBuffer(strings.size() * 20);
+ for (Iterator<String> it= strings.iterator(); it.hasNext();) {
+ buf.append(it.next());
+ if (it.hasNext())
+ buf.append(DELIM);
+ }
+ return buf.toString();
+ }
+
+ public static Set<String> deserialize(String serialized) {
+ Assert.isLegal(serialized != null);
+ Set<String> marked= new HashSet<String>();
+ StringTokenizer tok= new StringTokenizer(serialized, DELIM);
+ while (tok.hasMoreTokens())
+ marked.add(tok.nextToken());
+ return marked;
+ }
+
+ public static String[] getDifference(String oldValue, String newValue) {
+ Set<String> oldSet= deserialize(oldValue);
+ Set<String> newSet= deserialize(newValue);
+ Set<String> intersection= new HashSet<String>(oldSet);
+ intersection.retainAll(newSet);
+ oldSet.removeAll(intersection);
+ newSet.removeAll(intersection);
+ oldSet.addAll(newSet);
+ return oldSet.toArray(new String[oldSet.size()]);
+ }
+}
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/disassembly/rulers/AbstractContributedRulerColumn.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/disassembly/rulers/AbstractContributedRulerColumn.java
new file mode 100644
index 0000000000..a46aaf45a4
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/disassembly/rulers/AbstractContributedRulerColumn.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2011 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 Corporation - initial API and implementation
+ * Wind River Systems, Inc. - adapted for for disassembly parts
+ *******************************************************************************/
+package org.eclipse.cdt.debug.ui.disassembly.rulers;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IConfigurationElement;
+
+import org.eclipse.ui.IWorkbenchPart;
+
+
+/**
+ * Helper class for contributions to the
+ * <code>org.eclipse.cdt.debug.ui.disassemblyRulerColumns</code> extension point.
+ * <p>
+ * Subclasses must have a zero-argument constructor so that they can be created by
+ * {@link IConfigurationElement#createExecutableExtension(String)}.</p>
+ *
+ * @since 7.2
+ */
+public abstract class AbstractContributedRulerColumn implements IContributedRulerColumn {
+ /** The contribution descriptor. */
+ private RulerColumnDescriptor fDescriptor;
+ /** The target disassembly part. */
+ private IWorkbenchPart fDisassembly;
+
+ @Override
+ public final RulerColumnDescriptor getDescriptor() {
+ return fDescriptor;
+ }
+
+ @Override
+ public final void setDescriptor(RulerColumnDescriptor descriptor) {
+ Assert.isLegal(descriptor != null);
+ Assert.isTrue(fDescriptor == null);
+ fDescriptor= descriptor;
+ }
+
+ @Override
+ public final void setDisassemblyPart(IWorkbenchPart disassembly) {
+ Assert.isLegal(disassembly != null);
+ Assert.isTrue(fDisassembly == null);
+ fDisassembly= disassembly;
+ }
+
+ @Override
+ public final IWorkbenchPart getDisassemblyPart() {
+ return fDisassembly;
+ }
+
+ @Override
+ public void columnCreated() {
+ }
+
+ @Override
+ public void columnRemoved() {
+ }
+}
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/disassembly/rulers/IColumnSupport.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/disassembly/rulers/IColumnSupport.java
new file mode 100644
index 0000000000..ea21e15a4b
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/disassembly/rulers/IColumnSupport.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2011 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 Corporation - initial API and implementation
+ * Wind River Systems, Inc. - adapted for for disassembly parts
+ *******************************************************************************/
+package org.eclipse.cdt.debug.ui.disassembly.rulers;
+
+
+/**
+ * Provides support to modify and query the visibility of
+ * ruler columns and test whether a ruler column is supported.
+ * <p>
+ * This interface must not be implemented by clients.
+ * </p>
+ *
+ * @since 7.2
+ * @noimplement This interface is not intended to be implemented by clients.
+ * @noextend This interface is not intended to be extended by clients.
+ */
+public interface IColumnSupport {
+
+ /**
+ * Returns <code>true</code> if the column described by <code>descriptor</code> is
+ * currently showing, <code>false</code> if not.
+ *
+ * @param descriptor the column descriptor
+ * @return <code>true</code> if the specified column is currently visible
+ */
+ boolean isColumnVisible(RulerColumnDescriptor descriptor);
+
+ /**
+ * Attempts to set the visibility of the column described by <code>descriptor</code>. Nothing
+ * happens if the visibility is already as requested, or if the column is not supported by the
+ * editor.
+ *
+ * @param descriptor the column descriptor
+ * @param visible <code>true</code> to show the column, <code>false</code> to hide it
+ */
+ void setColumnVisible(RulerColumnDescriptor descriptor, boolean visible);
+
+ /**
+ * Returns <code>true</code> if the column described by <code>descriptor</code> is
+ * supported by the receiver's editor, <code>false</code> if <code>id</code> is not the
+ * identifier of a known column contribution, if the column does not target the editor, or if
+ * the editor does not support contributed columns.
+ *
+ * @param descriptor the column descriptor
+ * @return <code>true</code> if the specified column is supported
+ */
+ boolean isColumnSupported(RulerColumnDescriptor descriptor);
+
+ /**
+ * Removes and disposes all currently visible ruler columns.
+ */
+ void dispose();
+} \ No newline at end of file
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/disassembly/rulers/IContributedRulerColumn.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/disassembly/rulers/IContributedRulerColumn.java
new file mode 100644
index 0000000000..4c2e7c616b
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/disassembly/rulers/IContributedRulerColumn.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2011 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 Corporation - initial API and implementation
+ * Wind River Systems, Inc. - adapted for for disassembly parts
+ *******************************************************************************/
+package org.eclipse.cdt.debug.ui.disassembly.rulers;
+
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.jface.text.source.IVerticalRulerColumn;
+import org.eclipse.ui.IWorkbenchPart;
+
+
+/**
+ * Interface that has to be implemented by contributions to the
+ * <code>org.eclipse.cdt.debug.ui.disassembly.rulerColumns</code> extension point.
+ * <p>
+ * Implementors must have a zero-argument constructor so that they can be created
+ * by {@link IConfigurationElement#createExecutableExtension(String)}.</p>
+ *
+ * @since 7.2
+ */
+public interface IContributedRulerColumn extends IVerticalRulerColumn {
+
+ /**
+ * Returns the extension point descriptor of this ruler.
+ *
+ * @return descriptor the extension point descriptor of this ruler or <code>null</code> if called before {@link #columnCreated()}
+ */
+ RulerColumnDescriptor getDescriptor();
+
+ /**
+ * Sets the extension point descriptor of this ruler.
+ * <p>
+ * <em>This method will be called by the framework and must not
+ * be called by clients.</em></p>
+ *
+ * @param descriptor the extension point descriptor
+ */
+ void setDescriptor(RulerColumnDescriptor descriptor);
+
+ /**
+ * Sets the disassembly part (called right after the extension was instantiated).
+ * <p>
+ * <em>This method will be called by the framework and must not
+ * be called by clients.</em></p>
+ *
+ * @param disassembly the disassembly part targeted by this ruler instance
+ */
+ void setDisassemblyPart(IWorkbenchPart disassembly);
+
+ /**
+ * Returns the disassembly part targeted by this ruler instance.
+ *
+ * @return the disassembly part targeted by this ruler instance or <code>null</code> if called before {@link #columnCreated()}
+ */
+ IWorkbenchPart getDisassemblyPart();
+
+ /**
+ * Hook method called after a column has been instantiated, but before it is
+ * added to a {@link org.eclipse.jface.text.source.CompositeRuler} and before
+ * {@linkplain org.eclipse.jface.text.source.IVerticalRulerColumn#createControl(org.eclipse.jface.text.source.CompositeRuler, org.eclipse.swt.widgets.Composite) createControl}
+ * is called.
+ * <p>
+ * This happens when
+ * <ul>
+ * <li>the column is set visible by the user or programmatically</li>
+ * <li>the disassembly part is created, if this ruler targets the disassembly part and is enabled by default</li>
+ * <li>the disassembly part input changes and the column now targets the new disassembly part contents.</li>
+ * </ul></p>
+ */
+ void columnCreated();
+
+ /**
+ * Hook method called after a column has been removed from the {@link org.eclipse.jface.text.source.CompositeRuler}.
+ * <p>
+ * This happens when
+ * <ul>
+ * <li>the column is hidden by the user or programmatically</li>
+ * <li>the disassembly part is closed</li>
+ * <li>the disassembly part input changes and the column no longer targets the disassembly part
+ * contents.</li>
+ * </ul>
+ * </p>
+ * <p>
+ * The column will not be used after this method has been called. A new
+ * column will be instantiated if the same column type should be shown for
+ * the same disassembly part.
+ * </p>
+ */
+ void columnRemoved();
+
+}
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/disassembly/rulers/RulerColumnDescriptor.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/disassembly/rulers/RulerColumnDescriptor.java
new file mode 100644
index 0000000000..48dfaef455
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/disassembly/rulers/RulerColumnDescriptor.java
@@ -0,0 +1,309 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2011 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 Corporation - initial API and implementation
+ * Wind River Systems, Inc. - adapted for for disassembly parts
+ *******************************************************************************/
+package org.eclipse.cdt.debug.ui.disassembly.rulers;
+
+import java.net.URL;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.InvalidRegistryObjectException;
+import org.eclipse.core.runtime.content.IContentType;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.internal.texteditor.rulers.ExtensionPointHelper;
+import org.eclipse.ui.internal.texteditor.rulers.RulerColumnMessages;
+import org.eclipse.ui.internal.texteditor.rulers.RulerColumnPlacement;
+import org.eclipse.ui.internal.texteditor.rulers.RulerColumnTarget;
+
+
+/**
+ * The description of an extension to the
+ * <code>org.eclipse.ui.workbench.texteditor.rulerColumns</code> extension point. Instances are
+ * immutable. Instances can be obtained from a {@link RulerColumnRegistry}.
+ *
+ * @since 7.2
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class RulerColumnDescriptor {
+ /** The extension schema name of the class attribute. */
+ private static final String CLASS= "class"; //$NON-NLS-1$
+ /** The extension schema name of the id attribute. */
+ private static final String ID= "id"; //$NON-NLS-1$
+ /** The extension schema name of the optional name attribute. */
+ private static final String NAME= "name"; //$NON-NLS-1$
+ /** The extension schema name of the optional enabled attribute. */
+ private static final String ENABLED= "enabled"; //$NON-NLS-1$
+ /** The extension schema name of the optional icon attribute. */
+ private static final String ICON= "icon"; //$NON-NLS-1$
+ /** The extension schema name of the optional global attribute. */
+ private static final String GLOBAL= "global"; //$NON-NLS-1$
+ /** The extension schema name of the optional menu inclusion attribute. */
+ private static final String INCLUDE_IN_MENU= "includeInMenu"; //$NON-NLS-1$
+ /** The extension schema name of the targetEditor element. */
+ private static final String TARGET_ID= "targetId"; //$NON-NLS-1$
+ /** The extension schema name of the targetClass element. */
+ private static final String TARGET_CLASS= "targetClass"; //$NON-NLS-1$
+ /** The extension schema name of the placement element. */
+ private static final String PLACEMENT= "placement"; //$NON-NLS-1$
+
+ /** The identifier of the extension. */
+ private final String fId;
+ /** The name of the extension, equal to the id if no name is given. */
+ private final String fName;
+ /** The icon descriptor. */
+ private final ImageDescriptor fIcon;
+ /** The configuration element of this extension. */
+ private final IConfigurationElement fElement;
+ /** The target specification of the ruler column contribution. */
+ private final RulerColumnTarget fTarget;
+ /** The placement specification of the ruler column contribution. */
+ private final RulerColumnPlacement fRulerColumnPlacement;
+ /** The default enablement setting of the ruler column contribution. */
+ private final boolean fDefaultEnablement;
+ /** The global setting of the ruler column contribution. */
+ private final boolean fIsGlobal;
+ /** The menu inclusion setting of the ruler column contribution. */
+ private final boolean fIncludeInMenu;
+
+ /**
+ * Creates a new descriptor.
+ *
+ * @param element the configuration element to read
+ * @param registry the computer registry creating this descriptor
+ * @throws InvalidRegistryObjectException if the configuration element is no longer valid
+ * @throws CoreException if the configuration element does not conform to the extension point spec
+ */
+ RulerColumnDescriptor(IConfigurationElement element, RulerColumnRegistry registry) throws InvalidRegistryObjectException, CoreException {
+ Assert.isLegal(registry != null);
+ Assert.isLegal(element != null);
+ fElement= element;
+
+ ExtensionPointHelper helper= new ExtensionPointHelper(element);
+
+ fId= helper.getNonNullAttribute(ID);
+ fName= helper.getDefaultAttribute(NAME, fId);
+ helper.getNonNullAttribute(CLASS); // just check validity
+ URL iconURL= helper.getDefaultResourceURL(ICON, null);
+ fIcon= iconURL == null ? null : ImageDescriptor.createFromURL(iconURL);
+ fDefaultEnablement= helper.getDefaultAttribute(ENABLED, true);
+ fIsGlobal= helper.getDefaultAttribute(GLOBAL, true);
+ fIncludeInMenu= helper.getDefaultAttribute(INCLUDE_IN_MENU, true);
+
+ @SuppressWarnings("null")
+ IConfigurationElement[] targetEditors= element.getChildren(TARGET_ID);
+ IConfigurationElement[] targetClasses= element.getChildren(TARGET_CLASS);
+
+ RulerColumnTarget combined= null;
+ for (int i= 0; i < targetEditors.length; i++) {
+ IConfigurationElement targetEditor= targetEditors[i];
+ RulerColumnTarget target= RulerColumnTarget.createEditorIdTarget(new ExtensionPointHelper(targetEditor).getNonNullAttribute(ID));
+ combined= RulerColumnTarget.createOrTarget(combined, target);
+ }
+ for (int i= 0; i < targetClasses.length; i++) {
+ IConfigurationElement targetClass= targetClasses[i];
+ RulerColumnTarget target= RulerColumnTarget.createClassTarget(new ExtensionPointHelper(targetClass).getNonNullAttribute(CLASS));
+ combined= RulerColumnTarget.createOrTarget(combined, target);
+ }
+ fTarget= combined;
+
+ IConfigurationElement[] placements= element.getChildren(PLACEMENT);
+ switch (placements.length) {
+ case 0:
+ fRulerColumnPlacement= new RulerColumnPlacement();
+ break;
+ case 1:
+ fRulerColumnPlacement= new RulerColumnPlacement(placements[0]);
+ break;
+ default:
+ helper.fail(RulerColumnMessages.RulerColumnDescriptor_invalid_placement_msg);
+ fRulerColumnPlacement= null; // dummy
+ break;
+ }
+
+ Assert.isTrue(fTarget != null);
+ Assert.isTrue(fRulerColumnPlacement != null);
+ }
+
+ /**
+ * Returns the identifier of the described extension.
+ *
+ * @return the identifier of the described extension
+ */
+ public String getId() {
+ return fId;
+ }
+
+ /**
+ * Returns the name of the described extension.
+ *
+ * @return the name of the described extension
+ */
+ public String getName() {
+ return fName;
+ }
+
+ /**
+ * Returns the image descriptor of the described extension, <code>null</code> if it does not
+ * have an image.
+ *
+ * @return the image descriptor of the described extension or <code>null</code> for no image
+ */
+ public ImageDescriptor getIcon() {
+ return fIcon;
+ }
+
+ RulerColumnTarget getTarget() {
+ return fTarget;
+ }
+
+ RulerColumnPlacement getPlacement() {
+ return fRulerColumnPlacement;
+ }
+
+ /**
+ * Returns the default enablement of the described extension. Editors that support this
+ * contribution should typically enable the column by default.
+ *
+ * @return the default enablement of the described extension
+ */
+ public boolean getDefaultEnablement() {
+ return fDefaultEnablement;
+ }
+
+ /**
+ * Returns the global property of the described extension. Changing the visibility of a column
+ * with the global property set to <code>true</code> should typically affect all matching
+ * editors. Changing the visibility of a column with the global property set to
+ * <code>false</code> should only affect the current disassembly part.
+ *
+ * @return the global property of the described extension
+ */
+ public boolean isGlobal() {
+ return fIsGlobal;
+ }
+
+ /**
+ * Returns the menu inclusion property of the described extension. A toggle menu entry should be
+ * inluded in the ruler context menu for columns with this property set to <code>true</code>.
+ *
+ * @return the menu inclusion property of the described extension
+ */
+ public boolean isIncludedInMenu() {
+ return fIncludeInMenu;
+ }
+
+ /**
+ * Returns <code>true</code> if this contribution matches the passed disassembly part , <code>false</code> if not.
+ *
+ * @param disassembly the disassembly part to check
+ * @return <code>true</code> if this contribution targets the passed disassembly part
+ */
+ public boolean matchesPart(IWorkbenchPart disassembly) {
+ Assert.isLegal(disassembly != null);
+ RulerColumnTarget target= getTarget();
+
+ @SuppressWarnings("null")
+ IWorkbenchPartSite site= disassembly.getSite();
+ if (site != null && target.matchesEditorId(site.getId()))
+ return true;
+
+ if (target.matchesClass(disassembly.getClass()))
+ return true;
+
+ IContentType contentType= getContentType(disassembly);
+ return contentType != null && target.matchesContentType(contentType);
+
+ }
+
+ /**
+ * Creates a {@link IContributedRulerColumn} instance as described by the receiver. This may load the contributing plug-in.
+ *
+ * @param disassembly the disassembly part that loads the contributed column
+ * @return the instantiated column
+ * @throws CoreException as thrown by {@link IConfigurationElement#createExecutableExtension(String)}
+ * @throws InvalidRegistryObjectException as thrown by {@link IConfigurationElement#createExecutableExtension(String)}
+ */
+ public IContributedRulerColumn createColumn(IWorkbenchPart disassembly) throws CoreException, InvalidRegistryObjectException {
+ Assert.isLegal(disassembly != null);
+ IContributedRulerColumn column= (IContributedRulerColumn)fElement.createExecutableExtension(CLASS);
+ column.setDescriptor(this);
+ column.setDisassemblyPart(disassembly);
+ column.columnCreated();
+ return column;
+ }
+
+ /*
+ * @see java.lang.Object#toString()
+ * @since 3.3
+ */
+ @Override
+ public String toString() {
+ return "RulerColumnDescriptor[name=" + getName() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ IConfigurationElement getConfigurationElement() {
+ return fElement;
+ }
+
+ /*
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime= 31;
+ int result= 1;
+ result= prime * result + ((fId == null) ? 0 : fId.hashCode());
+ return result;
+ }
+
+ /*
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final RulerColumnDescriptor other= (RulerColumnDescriptor) obj;
+ if (fId == null) {
+ if (other.fId != null)
+ return false;
+ } else if (!fId.equals(other.fId))
+ return false;
+ return true;
+ }
+
+ /**
+ * Returns the content type of the disassembly part's input, <code>null</code> if the disassembly part input or
+ * the document provider is <code>null</code> or the content type cannot be determined.
+ *
+ * @param disassembly part the disassembly part to get the content type from
+ * @return the content type of the disassembly part's input, <code>null</code> if it cannot be
+ * determined
+ */
+ private IContentType getContentType(IWorkbenchPart disassembly) {
+ return null;
+ }
+
+ String getContributor() {
+ try {
+ return fElement.getContributor().getName();
+ } catch (InvalidRegistryObjectException e) {
+ return "unknown"; //$NON-NLS-1$
+ }
+ }
+}
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/disassembly/rulers/RulerColumnPreferenceAdapter.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/disassembly/rulers/RulerColumnPreferenceAdapter.java
new file mode 100644
index 0000000000..b924ec4178
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/disassembly/rulers/RulerColumnPreferenceAdapter.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 201 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 Corporation - initial API and implementation
+ * Wind River Systems, Inc. - adapted for for disassembly parts
+ *******************************************************************************/
+package org.eclipse.cdt.debug.ui.disassembly.rulers;
+
+import java.util.Set;
+
+import org.eclipse.cdt.debug.internal.ui.preferences.StringSetSerializer;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.preference.IPreferenceStore;
+
+/**
+ * Manages the preferences for ruler contributions stored in a preference store.
+ *
+ * @since 7.2
+ */
+public final class RulerColumnPreferenceAdapter {
+ private final IPreferenceStore fStore;
+ private final String fKey;
+
+ /**
+ * Creates a new preference adapter that will read and write under the specified key in the
+ * given preference store.
+ *
+ * @param store the preference store
+ * @param key the key
+ */
+ public RulerColumnPreferenceAdapter(IPreferenceStore store, String key) {
+ Assert.isLegal(store != null);
+ Assert.isLegal(key != null);
+ fStore= store;
+ fKey= key;
+ }
+
+ /**
+ * Returns the enablement state of the given ruler contribution.
+ *
+ * @param descriptor a ruler contribution descriptor
+ * @return <code>true</code> if the ruler is enabled, <code>false</code> otherwise
+ */
+ @SuppressWarnings("null")
+ public boolean isEnabled(RulerColumnDescriptor descriptor) {
+ Assert.isLegal(descriptor != null);
+ String preference= fStore.getString(fKey);
+ return StringSetSerializer.deserialize(preference).contains(descriptor.getId()) ^ descriptor.getDefaultEnablement();
+ }
+
+ /**
+ * Sets the enablement state of the given ruler contribution.
+ *
+ * @param descriptor a ruler contribution descriptor
+ * @param enabled <code>true</code> to enable the contribution, <code>false</code> to
+ * disable it
+ */
+ public void setEnabled(RulerColumnDescriptor descriptor, boolean enabled) {
+ Assert.isLegal(descriptor != null);
+ @SuppressWarnings("null")
+ String id= descriptor.getId();
+ String preference= fStore.getString(fKey);
+ Set<String> marked= StringSetSerializer.deserialize(preference);
+ boolean shouldMark= enabled ^ descriptor.getDefaultEnablement();
+ boolean isMarked= marked.contains(id);
+ if (isMarked != shouldMark) {
+ if (shouldMark)
+ marked.add(id);
+ else
+ marked.remove(id);
+ fStore.setValue(fKey, StringSetSerializer.serialize(marked));
+ }
+ }
+
+ /**
+ * Toggles the enablement state of given the ruler contribution.
+ *
+ * @param descriptor a ruler contribution descriptor
+ */
+ public void toggle(RulerColumnDescriptor descriptor) {
+ Assert.isLegal(descriptor != null);
+ setEnabled(descriptor, !isEnabled(descriptor));
+ }
+}
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/disassembly/rulers/RulerColumnRegistry.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/disassembly/rulers/RulerColumnRegistry.java
new file mode 100644
index 0000000000..024d07e97b
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/disassembly/rulers/RulerColumnRegistry.java
@@ -0,0 +1,294 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 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 Corporation - initial API and implementation
+ * Wind River Systems, Inc. - adapted for for disassembly parts
+ *******************************************************************************/
+package org.eclipse.cdt.debug.ui.disassembly.rulers;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.InvalidRegistryObjectException;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.ui.internal.texteditor.TextEditorPlugin;
+import org.eclipse.ui.internal.texteditor.rulers.DAG;
+import org.eclipse.ui.internal.texteditor.rulers.ExtensionPointHelper;
+import org.eclipse.ui.internal.texteditor.rulers.RulerColumnMessages;
+import org.eclipse.ui.internal.texteditor.rulers.RulerColumnPlacementConstraint;
+import org.eclipse.ui.texteditor.ConfigurationElementSorter;
+
+import com.ibm.icu.text.MessageFormat;
+
+
+/**
+ * A registry for all extensions to the
+ * <code>rulerColumns</code> extension point.
+ *
+ * @since 7.2
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class RulerColumnRegistry {
+
+ private static final String EXTENSION_POINT= "disassemblyRulerColumns"; //$NON-NLS-1$
+ private static final String QUALIFIED_EXTENSION_POINT= CDebugUIPlugin.PLUGIN_ID + '.' + EXTENSION_POINT;
+
+ /** The singleton instance. */
+ private static RulerColumnRegistry fgSingleton= null;
+
+ /**
+ * Returns the default computer registry.
+ *
+ * @return the singleton instance
+ */
+ public static synchronized RulerColumnRegistry getDefault() {
+ if (fgSingleton == null) {
+ fgSingleton= new RulerColumnRegistry();
+ }
+
+ return fgSingleton;
+ }
+
+ /**
+ * All descriptors (element type:
+ * {@link RulerColumnDescriptor}).
+ */
+ private List<RulerColumnDescriptor> fDescriptors= null;
+ /**
+ * All descriptors by id (element type: {@link RulerColumnDescriptor}).
+ */
+ private Map<String, RulerColumnDescriptor> fDescriptorMap= null;
+
+ /**
+ * <code>true</code> if this registry has been loaded.
+ */
+ private boolean fLoaded= false;
+
+ /**
+ * Creates a new instance.
+ */
+ RulerColumnRegistry() {
+ }
+
+ /**
+ * Returns the list of {@link RulerColumnDescriptor}s describing all extensions to the
+ * <code>rulerColumns</code> extension point. The list's iterator traverses the descriptors in
+ * the ordering implied by the placement specifications of the contributions.
+ * <p>
+ * The returned list is unmodifiable and guaranteed to never change. Note that the set of
+ * descriptors may change over time due to dynamic plug-in removal or addition.
+ * </p>
+ *
+ * @return the sorted list of extensions to the <code>rulerColumns</code> extension point
+ * (element type: {@link RulerColumnDescriptor})
+ */
+ public List<RulerColumnDescriptor> getColumnDescriptors() {
+ ensureExtensionPointRead();
+ return fDescriptors;
+ }
+
+ /**
+ * Returns the {@link RulerColumnDescriptor} with the given identity, <code>null</code> if no
+ * such descriptor exists.
+ *
+ * @param id the identity of the ruler contribution as given in the extension point xml.
+ * @return the {@link RulerColumnDescriptor} with the given identity, <code>null</code> if no
+ * such descriptor exists
+ */
+ public RulerColumnDescriptor getColumnDescriptor(String id) {
+ Assert.isLegal(id != null);
+ ensureExtensionPointRead();
+ return fDescriptorMap.get(id);
+ }
+
+ /**
+ * Ensures that the extensions are read and stored in
+ * <code>fDescriptorsByPartition</code>.
+ */
+ private void ensureExtensionPointRead() {
+ boolean reload;
+ synchronized (this) {
+ reload= !fLoaded;
+ fLoaded= true;
+ }
+ if (reload)
+ reload();
+ }
+
+ /**
+ * Reloads the extensions to the extension point.
+ * <p>
+ * This method can be called more than once in order to reload from
+ * a changed extension registry.
+ * </p>
+ */
+ public void reload() {
+ IExtensionRegistry registry= Platform.getExtensionRegistry();
+ List<IConfigurationElement> elements= new ArrayList<IConfigurationElement>(Arrays.asList(registry.getConfigurationElementsFor(CDebugUIPlugin.PLUGIN_ID, EXTENSION_POINT)));
+
+ List<RulerColumnDescriptor> descriptors= new ArrayList<RulerColumnDescriptor>();
+ Map<String, RulerColumnDescriptor> descriptorMap= new HashMap<String, RulerColumnDescriptor>();
+
+ for (Iterator<IConfigurationElement> iter= elements.iterator(); iter.hasNext();) {
+ IConfigurationElement element= iter.next();
+ try {
+ RulerColumnDescriptor desc= new RulerColumnDescriptor(element, this);
+ String id= desc.getId();
+ if (descriptorMap.containsKey(id)) {
+ noteDuplicateId(desc);
+ continue;
+ }
+
+ descriptors.add(desc);
+ descriptorMap.put(id, desc);
+ } catch (InvalidRegistryObjectException x) {
+ /*
+ * Element is not valid any longer as the contributing plug-in was unloaded or for
+ * some other reason. Do not include the extension in the list and inform the user
+ * about it.
+ */
+ noteInvalidExtension(element, x);
+ } catch (CoreException x) {
+ warnUser(x.getStatus());
+ }
+ }
+
+ sort(descriptors);
+
+ synchronized (this) {
+ fDescriptors= Collections.unmodifiableList(descriptors);
+ fDescriptorMap= Collections.unmodifiableMap(descriptorMap);
+ }
+ }
+
+ /**
+ * Sorts the column contributions.
+ *
+ * @param descriptors the descriptors to sort
+ */
+ @SuppressWarnings("unchecked")
+ private void sort(List<RulerColumnDescriptor> descriptors) {
+ /*
+ * Topological sort of the DAG defined by the plug-in dependencies
+ * 1. TopoSort descriptors by plug-in dependency
+ * 2. Insert into Directed Acyclic Graph
+ * 3. TopoSort DAG: pick the source with the lowest gravity and remove from DAG
+ */
+ ConfigurationElementSorter sorter= new ConfigurationElementSorter() {
+ @Override
+ public IConfigurationElement getConfigurationElement(Object object) {
+ return ((RulerColumnDescriptor) object).getConfigurationElement();
+ }
+ };
+ RulerColumnDescriptor[] array= new RulerColumnDescriptor[descriptors.size()];
+ descriptors.toArray(array);
+ sorter.sort(array);
+
+ Map<String, RulerColumnDescriptor> descriptorsById= new HashMap<String, RulerColumnDescriptor>();
+ for (RulerColumnDescriptor desc : array) {
+ descriptorsById.put(desc.getId(), desc);
+ }
+
+ DAG dag= new DAG();
+ for (RulerColumnDescriptor desc : array) {
+ dag.addVertex(desc);
+
+ Set<?> before= desc.getPlacement().getConstraints();
+ for (Iterator<?> it= before.iterator(); it.hasNext();) {
+ RulerColumnPlacementConstraint constraint= (RulerColumnPlacementConstraint) it.next();
+ String id= constraint.getId();
+ RulerColumnDescriptor target= descriptorsById.get(id);
+ if (target == null) {
+ noteUnknownTarget(desc, id);
+ } else {
+ boolean success;
+ if (constraint.isBefore())
+ success= dag.addEdge(desc, target);
+ else
+ success= dag.addEdge(target, desc);
+ if (!success)
+ noteCycle(desc, target);
+ }
+ }
+ }
+
+ Comparator<RulerColumnDescriptor> gravityComp= new Comparator<RulerColumnDescriptor>() {
+ @Override
+ public int compare(RulerColumnDescriptor o1, RulerColumnDescriptor o2) {
+ float diff= o1.getPlacement().getGravity() - o2.getPlacement().getGravity();
+ if (diff == 0)
+ return 0;
+ if (diff < 0)
+ return -1;
+ return 1;
+ }
+ };
+
+ /* Topological sort - always select the source with the least gravity */
+ Set<RulerColumnDescriptor> toProcess= dag.getSources();
+ int index= 0;
+ while (!toProcess.isEmpty()) {
+ RulerColumnDescriptor next= Collections.min(toProcess, gravityComp);
+ array[index]= next;
+ index++;
+ dag.removeVertex(next);
+ toProcess= dag.getSources();
+ }
+ Assert.isTrue(index == array.length);
+
+ ListIterator<RulerColumnDescriptor> it= descriptors.listIterator();
+ for (int i= 0; i < index; i++) {
+ it.next();
+ it.set(array[i]);
+ }
+ }
+
+ private void noteInvalidExtension(IConfigurationElement element, InvalidRegistryObjectException x) {
+ String message= MessageFormat.format(RulerColumnMessages.RulerColumnRegistry_invalid_msg, new Object[] {ExtensionPointHelper.findId(element)});
+ warnUser(message, x);
+ }
+
+ private void noteUnknownTarget(RulerColumnDescriptor desc, String referencedId) {
+ String message= MessageFormat.format(RulerColumnMessages.RulerColumnRegistry_unresolved_placement_msg, new Object[] {QUALIFIED_EXTENSION_POINT, referencedId, desc.getName(), desc.getContributor()});
+ warnUser(message, null);
+ }
+
+ private void noteCycle(RulerColumnDescriptor desc, RulerColumnDescriptor target) {
+ String message= MessageFormat.format(RulerColumnMessages.RulerColumnRegistry_cyclic_placement_msg, new Object[] {QUALIFIED_EXTENSION_POINT, target.getName(), desc.getName(), desc.getContributor()});
+ warnUser(message, null);
+ }
+
+ private void noteDuplicateId(RulerColumnDescriptor desc) {
+ String message= MessageFormat.format(RulerColumnMessages.RulerColumnRegistry_duplicate_id_msg, new Object[] {QUALIFIED_EXTENSION_POINT, desc.getId(), desc.getContributor()});
+ warnUser(message, null);
+ }
+
+ private void warnUser(String message, Exception exception) {
+ IStatus status= new Status(IStatus.WARNING, TextEditorPlugin.PLUGIN_ID, IStatus.OK, message, exception);
+ warnUser(status);
+ }
+
+ private void warnUser(IStatus status) {
+ TextEditorPlugin.getDefault().getLog().log(status);
+ }
+}

Back to the top