Skip to content

Commit 627a21b

Browse files
committed
Load marker content generator details from extensions #2193
It was not possible to add new columns to MarkerSupportViews via marker content generator extensions. By loading marker fields, marker types, and groups from marker content generator extensions that will be possible. This way, the problems view and markers view can be extended with new columns like, for example, an issue ID and URL to a detailed problem description. Fixes #2193
1 parent 5c74619 commit 627a21b

File tree

4 files changed

+223
-43
lines changed

4 files changed

+223
-43
lines changed

bundles/org.eclipse.ui.ide/src/org/eclipse/ui/views/markers/internal/ContentGeneratorDescriptor.java

Lines changed: 80 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020
import java.util.HashMap;
2121
import java.util.HashSet;
2222
import java.util.Iterator;
23+
import java.util.List;
2324
import java.util.Map;
25+
import java.util.Set;
2426
import java.util.TreeSet;
2527
import java.util.stream.Stream;
2628

@@ -43,12 +45,9 @@ public class ContentGeneratorDescriptor {
4345
private static final String MARKER_FIELD_REFERENCE = "markerFieldReference"; //$NON-NLS-1$
4446

4547
private IConfigurationElement configurationElement;
46-
private MarkerField[] allFields;
47-
private Collection<MarkerType> markerTypes;
48-
private MarkerField[] initialVisible;
49-
private Collection<MarkerGroup> groups;
48+
private MarkerField[] allFieldsWithoutExtensions;
49+
private MarkerField[] initialVisibleWithoutExtensions;
5050
private Collection<IConfigurationElement> generatorExtensions = new ArrayList<>();
51-
private Map<String, MarkerType> allTypesTable;
5251

5352
/**
5453
* Create a new ContentGeneratorDescriptor
@@ -60,13 +59,13 @@ public ContentGeneratorDescriptor(IConfigurationElement element) {
6059
/**
6160
* Add the groups defined in the receiver to the collection of groups.
6261
*/
63-
private void addDefinedGroups(Collection<MarkerGroup> groupss) {
62+
private void addDefinedGroups(Collection<MarkerGroup> groups) {
6463
// Add the ones in the receiver.
65-
addGroupsFrom(configurationElement, groupss);
64+
addGroupsFrom(configurationElement, groups);
6665
// Add the extensions
6766
Iterator<IConfigurationElement> extensions = generatorExtensions.iterator();
6867
while (extensions.hasNext()) {
69-
addGroupsFrom(extensions.next(), groupss);
68+
addGroupsFrom(extensions.next(), groups);
7069
}
7170
}
7271

@@ -96,7 +95,7 @@ private void addGroupsFrom(IConfigurationElement element, Collection<MarkerGroup
9695
* @return boolean
9796
*/
9897
public boolean allTypesSelected(Collection<MarkerType> selectedTypes) {
99-
return selectedTypes.containsAll(markerTypes);
98+
return selectedTypes.containsAll(getMarkerTypes());
10099
}
101100

102101
/**
@@ -105,7 +104,26 @@ public boolean allTypesSelected(Collection<MarkerType> selectedTypes) {
105104
* @return {@link MarkerField}[]
106105
*/
107106
public MarkerField[] getAllFields() {
108-
return allFields;
107+
List<MarkerField> allFieldsList = new ArrayList<>(Arrays.asList(allFieldsWithoutExtensions));
108+
109+
getExtensionsDescriptorsStream().flatMap(descriptor -> Arrays.stream(descriptor.getAllFields()))
110+
.forEach(field -> allFieldsList.add(field));
111+
112+
return allFieldsList.toArray(new MarkerField[allFieldsList.size()]);
113+
}
114+
115+
private Stream<ContentGeneratorDescriptor> getExtensionsDescriptorsStream() {
116+
if (generatorExtensions != null) {
117+
final MarkerSupportRegistry registry = MarkerSupportRegistry.getInstance();
118+
119+
return generatorExtensions.stream()
120+
.map(extensionConfigElem -> extensionConfigElem
121+
.getAttribute(MarkerSupportInternalUtilities.ATTRIBUTE_ID))
122+
.filter(id -> id != null && !id.isBlank())
123+
.map(contentGeneratorId -> registry.getContentGenDescriptor(contentGeneratorId))
124+
.filter(generator -> generator != null);
125+
}
126+
return Stream.empty();
109127
}
110128

111129
/**
@@ -156,7 +174,12 @@ public String getId() {
156174
* @return {@link MarkerField}[]
157175
*/
158176
public MarkerField[] getInitialVisible() {
159-
return initialVisible;
177+
List<MarkerField> allVisibleFieldsList = new ArrayList<>(Arrays.asList(initialVisibleWithoutExtensions));
178+
179+
getExtensionsDescriptorsStream().flatMap(descriptor -> Arrays.stream(descriptor.getInitialVisible()))
180+
.forEach(field -> allVisibleFieldsList.add(field));
181+
182+
return allVisibleFieldsList.toArray(new MarkerField[allVisibleFieldsList.size()]);
160183
}
161184

162185
/**
@@ -165,16 +188,15 @@ public MarkerField[] getInitialVisible() {
165188
* @return Collection of {@link MarkerGroup}
166189
*/
167190
public Collection<MarkerGroup> getMarkerGroups() {
168-
if (groups == null) {
169-
groups = new TreeSet<>((mg1, mg2) -> mg1.getMarkerField().getName().compareTo(mg2.getMarkerField().getName()));
191+
Collection<MarkerGroup> groups = new TreeSet<>(
192+
(mg1, mg2) -> mg1.getMarkerField().getName().compareTo(mg2.getMarkerField().getName()));
170193

171-
// Add the groups defined in the receiver
172-
addDefinedGroups(groups);
194+
// Add the groups defined in the receiver
195+
addDefinedGroups(groups);
173196

174-
if (getId().equals(MarkerSupportRegistry.PROBLEMS_GENERATOR)) {
175-
// Add the groups that reference the receiver.
176-
groups.addAll(MarkerSupportRegistry.getInstance().getMarkerGroups());
177-
}
197+
if (getId().equals(MarkerSupportRegistry.PROBLEMS_GENERATOR)) {
198+
// Add the groups that reference the receiver.
199+
groups.addAll(MarkerSupportRegistry.getInstance().getMarkerGroups());
178200
}
179201
return groups;
180202
}
@@ -185,23 +207,41 @@ public Collection<MarkerGroup> getMarkerGroups() {
185207
* @return Collection of {@link MarkerType}
186208
*/
187209
public Collection<MarkerType> getMarkerTypes() {
188-
if (markerTypes == null) {
189-
markerTypes = new HashSet<>();
190-
IConfigurationElement[] markerTypeElements = configurationElement.getChildren(MarkerSupportRegistry.MARKER_TYPE_REFERENCE);
191-
for (IConfigurationElement configElement : markerTypeElements) {
192-
String elementName = configElement.getAttribute(MarkerSupportInternalUtilities.ATTRIBUTE_ID);
193-
MarkerType[] types = MarkerTypesModel.getInstance().getType(elementName).getAllSubTypes();
194-
markerTypes.addAll(Arrays.asList(types));
195-
markerTypes.add(MarkerTypesModel.getInstance().getType(elementName));
196-
}
197-
if (markerTypes.isEmpty()) {
198-
MarkerType[] types = MarkerTypesModel.getInstance().getType(IMarker.PROBLEM).getAllSubTypes();
199-
markerTypes.addAll(Arrays.asList(types));
210+
Set<MarkerType> markerTypes = new HashSet<>();
211+
addMarkerTypesFrom(configurationElement, markerTypes);
212+
213+
Iterator<IConfigurationElement> extensions = generatorExtensions.iterator();
214+
while (extensions.hasNext()) {
215+
IConfigurationElement extensionElement = extensions.next();
216+
String extendingMarkerContentGeneratorId = extensionElement
217+
.getAttribute(MarkerSupportInternalUtilities.ATTRIBUTE_ID);
218+
if (extendingMarkerContentGeneratorId != null && !extendingMarkerContentGeneratorId.isBlank()) {
219+
ContentGeneratorDescriptor descriptor = MarkerSupportRegistry.getInstance()
220+
.getContentGenDescriptor(extendingMarkerContentGeneratorId);
221+
if (descriptor != null) {
222+
markerTypes.addAll(descriptor.getMarkerTypes());
223+
}
200224
}
201225
}
202226
return markerTypes;
203227
}
204228

229+
private void addMarkerTypesFrom(IConfigurationElement markerContentGeneratorConfigElement,
230+
Collection<MarkerType> markerTypes) {
231+
IConfigurationElement[] markerTypeElements = markerContentGeneratorConfigElement
232+
.getChildren(MarkerSupportRegistry.MARKER_TYPE_REFERENCE);
233+
for (IConfigurationElement configElement : markerTypeElements) {
234+
String elementName = configElement.getAttribute(MarkerSupportInternalUtilities.ATTRIBUTE_ID);
235+
MarkerType[] types = MarkerTypesModel.getInstance().getType(elementName).getAllSubTypes();
236+
markerTypes.addAll(Arrays.asList(types));
237+
markerTypes.add(MarkerTypesModel.getInstance().getType(elementName));
238+
}
239+
if (markerTypes.isEmpty()) {
240+
MarkerType[] types = MarkerTypesModel.getInstance().getType(IMarker.PROBLEM).getAllSubTypes();
241+
markerTypes.addAll(Arrays.asList(types));
242+
}
243+
}
244+
205245
/**
206246
* Return the name for the receiver.
207247
*
@@ -227,14 +267,12 @@ public MarkerType getType(String typeId) {
227267
* @return Map of {@link String} to {@link MarkerType}
228268
*/
229269
public Map<String, MarkerType> getTypesTable() {
230-
if (allTypesTable == null) {
231-
allTypesTable = new HashMap<>();
270+
Map<String, MarkerType> allTypesTable = new HashMap<>();
232271

233-
Iterator<MarkerType> allIterator = markerTypes.iterator();
234-
while (allIterator.hasNext()) {
235-
MarkerType next = allIterator.next();
236-
allTypesTable.put(next.getId(), next);
237-
}
272+
Iterator<MarkerType> allIterator = getMarkerTypes().iterator();
273+
while (allIterator.hasNext()) {
274+
MarkerType next = allIterator.next();
275+
allTypesTable.put(next.getId(), next);
238276
}
239277
return allTypesTable;
240278
}
@@ -264,11 +302,11 @@ public void initializeFromConfigurationElement(
264302
}
265303
}
266304

267-
allFields = new MarkerField[allFieldList.size()];
268-
allFieldList.toArray(allFields);
305+
allFieldsWithoutExtensions = new MarkerField[allFieldList.size()];
306+
allFieldList.toArray(allFieldsWithoutExtensions);
269307

270-
initialVisible = new MarkerField[initialVisibleList.size()];
271-
initialVisibleList.toArray(initialVisible);
308+
initialVisibleWithoutExtensions = new MarkerField[initialVisibleList.size()];
309+
initialVisibleList.toArray(initialVisibleWithoutExtensions);
272310

273311
}
274312

tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/markers/MarkerSupportViewTest.java

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,13 @@
2525
import org.eclipse.ui.internal.views.markers.FiltersConfigurationDialog;
2626
import org.eclipse.ui.internal.views.markers.MarkerContentGenerator;
2727
import org.eclipse.ui.tests.harness.util.UITestCase;
28+
import org.eclipse.ui.views.markers.MarkerField;
2829
import org.eclipse.ui.views.markers.MarkerSupportView;
30+
import org.eclipse.ui.views.markers.internal.ContentGeneratorDescriptor;
31+
import org.eclipse.ui.views.markers.internal.MarkerGroup;
2932
import org.eclipse.ui.views.markers.internal.MarkerMessages;
33+
import org.eclipse.ui.views.markers.internal.MarkerSupportRegistry;
34+
import org.eclipse.ui.views.markers.internal.MarkerType;
3035
import org.junit.Test;
3136
import org.junit.runner.RunWith;
3237
import org.junit.runners.JUnit4;
@@ -125,6 +130,59 @@ public void limitDisabled() throws Exception {
125130
assertFalse(isLimitEnabled);
126131
}
127132

133+
@Test
134+
public void markerContentGeneratorExtensionLoaded() throws Exception {
135+
MarkerSupportView view = (MarkerSupportView) PlatformUI.getWorkbench().getActiveWorkbenchWindow()
136+
.getActivePage().showView(PROBLEM_VIEW_ID);
137+
138+
MarkerContentGenerator generator = getMarkerContentGenerator(view);
139+
ContentGeneratorDescriptor descriptor = MarkerSupportRegistry.getInstance()
140+
.getContentGenDescriptor(generator.getId());
141+
assertNotNull(descriptor);
142+
143+
MarkerField[] allFields = descriptor.getAllFields();
144+
boolean foundAdditionalField1 = false;
145+
boolean foundRecursivelyAddedField2 = false;
146+
for (MarkerField field : allFields) {
147+
if (ProblemKeyMarkerField.class.equals(field.getClass())) {
148+
if ("Problem Key".equals(field.getName())) {
149+
foundAdditionalField1 = true;
150+
}
151+
152+
if ("Problem Key V2".equals(field.getName())) {
153+
foundRecursivelyAddedField2 = true;
154+
}
155+
}
156+
}
157+
assertTrue("MarkerFields from marker content generator extensions not loaded.",
158+
foundAdditionalField1);
159+
assertTrue("MarkerField not loaded from recursive marker content generator extension.",
160+
foundRecursivelyAddedField2);
161+
162+
MarkerField[] initiallyVisibleFields = descriptor.getInitialVisible();
163+
boolean foundAdditionalVisbileField = false;
164+
for (MarkerField field : initiallyVisibleFields) {
165+
if ("Problem Key".equals(field.getName())) {
166+
foundAdditionalVisbileField = true;
167+
}
168+
}
169+
assertTrue("Visible attribute from marker fields from marker content generator extensions not loaded.",
170+
foundAdditionalVisbileField);
171+
172+
MarkerType markerTypeFromExtension = descriptor.getType("org.eclipse.ui.tests.markers.artificial.problem");
173+
assertNotNull("Marker type from marker content generator extensions not loaded.", markerTypeFromExtension);
174+
assertTrue(descriptor.getMarkerTypes().contains(markerTypeFromExtension));
175+
176+
Collection<MarkerGroup> groups = descriptor.getMarkerGroups();
177+
boolean foundAdditionalMarkerGroup = false;
178+
for (MarkerGroup group : groups) {
179+
if ("org.eclipse.ui.tests.test.extended".equals(group.getId())) {
180+
foundAdditionalMarkerGroup = true;
181+
}
182+
}
183+
assertTrue("Marker groups from marker content generator extensions not loaded.", foundAdditionalMarkerGroup);
184+
}
185+
128186
public static MarkerContentGenerator getMarkerContentGenerator(MarkerSupportView view) {
129187
MarkerContentGenerator generator = null;
130188
try {
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package org.eclipse.ui.tests.markers;
2+
3+
import org.eclipse.ui.views.markers.MarkerField;
4+
import org.eclipse.ui.views.markers.MarkerItem;
5+
6+
public class ProblemKeyMarkerField extends MarkerField {
7+
8+
@Override
9+
public String getValue(MarkerItem item) {
10+
if (item == null) {
11+
return "";
12+
}
13+
return item.getAttributeValue("problemKey", "");
14+
}
15+
16+
}

tests/org.eclipse.ui.tests/plugin.xml

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3411,7 +3411,56 @@
34113411
</markerContentGenerator>
34123412
<markerContentGenerator
34133413
id="org.eclipse.ui.tests.customScopeContentGenerator">
3414-
</markerContentGenerator>
3414+
</markerContentGenerator>
3415+
<markerField
3416+
class="org.eclipse.ui.tests.markers.ProblemKeyMarkerField"
3417+
id="org.eclipse.ui.tests.markerField.problemKey"
3418+
name="Problem Key">
3419+
</markerField>
3420+
<markerField
3421+
class="org.eclipse.ui.tests.markers.ProblemKeyMarkerField"
3422+
id="org.eclipse.ui.tests.markerField.problemKeyV2"
3423+
name="Problem Key V2">
3424+
</markerField>
3425+
<markerContentGenerator
3426+
id="org.eclipse.ui.tests.additionalProblemMarkerContentGenerator"
3427+
name="Additional Problem Marker Content Generator">
3428+
<markerFieldReference
3429+
id="org.eclipse.ui.tests.markerField.problemKey">
3430+
</markerFieldReference>
3431+
<markerTypeReference
3432+
id="org.eclipse.ui.tests.markers.static.analysis.problem">
3433+
</markerTypeReference>
3434+
<markerTypeReference
3435+
id="org.eclipse.ui.tests.markers.artificial.problem">
3436+
</markerTypeReference>
3437+
</markerContentGenerator>
3438+
<markerContentGeneratorExtension
3439+
generatorId="org.eclipse.ui.ide.problemsGenerator"
3440+
id="org.eclipse.ui.tests.additionalProblemMarkerContentGenerator">
3441+
<markerGrouping
3442+
id="org.eclipse.ui.tests.test.extended"
3443+
label="Extended Problem Category">
3444+
</markerGrouping>
3445+
</markerContentGeneratorExtension>
3446+
<markerContentGeneratorExtension
3447+
generatorId="org.eclipse.ui.ide.allMarkersGenerator"
3448+
id="org.eclipse.ui.tests.additionalProblemMarkerContentGenerator">
3449+
</markerContentGeneratorExtension>
3450+
<markerContentGenerator
3451+
id="org.eclipse.ui.tests.additionalProblemMarkerContentGenerator2"
3452+
name="Additional Problem Marker Content Generator 2">
3453+
<markerFieldReference
3454+
id="org.eclipse.ui.tests.markerField.problemKeyV2">
3455+
</markerFieldReference>
3456+
<markerTypeReference
3457+
id="org.eclipse.ui.tests.markers.static.analysis.problem">
3458+
</markerTypeReference>
3459+
</markerContentGenerator>
3460+
<markerContentGeneratorExtension
3461+
generatorId="org.eclipse.ui.tests.additionalProblemMarkerContentGenerator"
3462+
id="org.eclipse.ui.tests.additionalProblemMarkerContentGenerator2">
3463+
</markerContentGeneratorExtension>
34153464
</extension>
34163465
<extension
34173466
id="categoryTestMarker"
@@ -4838,5 +4887,24 @@
48384887
categoryId="org.eclipse.ui.tests.issue1832">
48394888
</categoryActivityBinding>
48404889
</extension>
4890+
<extension
4891+
id="markers.static.analysis.problem"
4892+
name="Static Analysis Test Problem"
4893+
point="org.eclipse.core.resources.markers">
4894+
<super
4895+
type="org.eclipse.core.resources.problemmarker">
4896+
</super>
4897+
<persistent
4898+
value="true">
4899+
</persistent>
4900+
<attribute
4901+
name="problemKey">
4902+
</attribute>
4903+
</extension>
4904+
<extension
4905+
id="markers.artificial.problem"
4906+
name="Artificial Test Problem"
4907+
point="org.eclipse.core.resources.markers">
4908+
</extension>
48414909

48424910
</plugin>

0 commit comments

Comments
 (0)