Skip to content

Commit 004743b

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 dad3444 commit 004743b

File tree

4 files changed

+239
-44
lines changed

4 files changed

+239
-44
lines changed

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

Lines changed: 86 additions & 43 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,46 @@ 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));
200-
}
210+
Set<MarkerType> markerTypes = collectMarkerTypesWithoutExtensions();
211+
addMarkerTypesFromExtensions(markerTypes);
212+
return markerTypes;
213+
}
214+
215+
private Set<MarkerType> collectMarkerTypesWithoutExtensions() {
216+
Set<MarkerType> markerTypes = new HashSet<>();
217+
218+
IConfigurationElement[] markerTypeElements = configurationElement
219+
.getChildren(MarkerSupportRegistry.MARKER_TYPE_REFERENCE);
220+
for (IConfigurationElement configElement : markerTypeElements) {
221+
String elementName = configElement.getAttribute(MarkerSupportInternalUtilities.ATTRIBUTE_ID);
222+
MarkerType[] types = MarkerTypesModel.getInstance().getType(elementName).getAllSubTypes();
223+
markerTypes.addAll(Arrays.asList(types));
224+
markerTypes.add(MarkerTypesModel.getInstance().getType(elementName));
201225
}
226+
if (markerTypes.isEmpty()) {
227+
MarkerType[] types = MarkerTypesModel.getInstance().getType(IMarker.PROBLEM).getAllSubTypes();
228+
markerTypes.addAll(Arrays.asList(types));
229+
}
230+
202231
return markerTypes;
203232
}
204233

234+
private void addMarkerTypesFromExtensions(Collection<MarkerType> markerTypes) {
235+
Iterator<IConfigurationElement> extensions = generatorExtensions.iterator();
236+
while (extensions.hasNext()) {
237+
IConfigurationElement extensionElement = extensions.next();
238+
String extendingMarkerContentGeneratorId = extensionElement
239+
.getAttribute(MarkerSupportInternalUtilities.ATTRIBUTE_ID);
240+
if (extendingMarkerContentGeneratorId != null && !extendingMarkerContentGeneratorId.isBlank()) {
241+
ContentGeneratorDescriptor descriptor = MarkerSupportRegistry.getInstance()
242+
.getContentGenDescriptor(extendingMarkerContentGeneratorId);
243+
if (descriptor != null) {
244+
markerTypes.addAll(descriptor.getMarkerTypes());
245+
}
246+
}
247+
}
248+
}
249+
205250
/**
206251
* Return the name for the receiver.
207252
*
@@ -227,14 +272,12 @@ public MarkerType getType(String typeId) {
227272
* @return Map of {@link String} to {@link MarkerType}
228273
*/
229274
public Map<String, MarkerType> getTypesTable() {
230-
if (allTypesTable == null) {
231-
allTypesTable = new HashMap<>();
275+
Map<String, MarkerType> allTypesTable = new HashMap<>();
232276

233-
Iterator<MarkerType> allIterator = markerTypes.iterator();
234-
while (allIterator.hasNext()) {
235-
MarkerType next = allIterator.next();
236-
allTypesTable.put(next.getId(), next);
237-
}
277+
Iterator<MarkerType> allIterator = getMarkerTypes().iterator();
278+
while (allIterator.hasNext()) {
279+
MarkerType next = allIterator.next();
280+
allTypesTable.put(next.getId(), next);
238281
}
239282
return allTypesTable;
240283
}
@@ -264,11 +307,11 @@ public void initializeFromConfigurationElement(
264307
}
265308
}
266309

267-
allFields = new MarkerField[allFieldList.size()];
268-
allFieldList.toArray(allFields);
310+
allFieldsWithoutExtensions = new MarkerField[allFieldList.size()];
311+
allFieldList.toArray(allFieldsWithoutExtensions);
269312

270-
initialVisible = new MarkerField[initialVisibleList.size()];
271-
initialVisibleList.toArray(initialVisible);
313+
initialVisibleWithoutExtensions = new MarkerField[initialVisibleList.size()];
314+
initialVisibleList.toArray(initialVisibleWithoutExtensions);
272315

273316
}
274317

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

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@
1414

1515
import java.lang.reflect.Field;
1616
import java.lang.reflect.Method;
17+
import java.util.Arrays;
1718
import java.util.Collection;
19+
import java.util.Collections;
20+
import java.util.List;
21+
import java.util.stream.Collectors;
1822

1923
import org.eclipse.jface.viewers.CheckboxTableViewer;
2024
import org.eclipse.swt.widgets.Button;
@@ -25,8 +29,13 @@
2529
import org.eclipse.ui.internal.views.markers.FiltersConfigurationDialog;
2630
import org.eclipse.ui.internal.views.markers.MarkerContentGenerator;
2731
import org.eclipse.ui.tests.harness.util.UITestCase;
32+
import org.eclipse.ui.views.markers.MarkerField;
2833
import org.eclipse.ui.views.markers.MarkerSupportView;
34+
import org.eclipse.ui.views.markers.internal.ContentGeneratorDescriptor;
35+
import org.eclipse.ui.views.markers.internal.MarkerGroup;
2936
import org.eclipse.ui.views.markers.internal.MarkerMessages;
37+
import org.eclipse.ui.views.markers.internal.MarkerSupportRegistry;
38+
import org.eclipse.ui.views.markers.internal.MarkerType;
3039
import org.junit.Test;
3140
import org.junit.runner.RunWith;
3241
import org.junit.runners.JUnit4;
@@ -125,6 +134,65 @@ public void limitDisabled() throws Exception {
125134
assertFalse(isLimitEnabled);
126135
}
127136

137+
@Test
138+
public void markerContentGeneratorExtensionLoaded() throws Exception {
139+
MarkerSupportView view = (MarkerSupportView) PlatformUI.getWorkbench().getActiveWorkbenchWindow()
140+
.getActivePage().showView(PROBLEM_VIEW_ID);
141+
142+
MarkerContentGenerator generator = getMarkerContentGenerator(view);
143+
ContentGeneratorDescriptor descriptor = MarkerSupportRegistry.getInstance()
144+
.getContentGenDescriptor(generator.getId());
145+
146+
assertNotNull(descriptor);
147+
148+
MarkerField[] allFields = descriptor.getAllFields();
149+
List<String> allFieldNames = mapToNames(allFields);
150+
String fieldName1 = "Problem Key", fieldName2 = "Problem Key V2";
151+
152+
assertTrue(
153+
"Expected loading marker field '" + fieldName1
154+
+ "' from marker content generator extensions, but got only " + allFieldNames,
155+
allFieldNames.contains(fieldName1));
156+
assertTrue(
157+
"Expected recursively loading marker field '" + fieldName2
158+
+ "' from marker content generator extensions, but got only " + allFieldNames,
159+
allFieldNames.contains(fieldName2));
160+
161+
MarkerField[] initiallyVisibleFields = descriptor.getInitialVisible();
162+
List<String> initiallyVisibleFieldNames = mapToNames(initiallyVisibleFields);
163+
164+
assertTrue("Expected marker field '" + fieldName1
165+
+ "' from marker content generator extension being visible according to 'visible' attribute in the extension,"
166+
+ " but only the following marker fields are visible " + initiallyVisibleFieldNames,
167+
initiallyVisibleFieldNames.contains(fieldName1));
168+
169+
String markerTypeId = "org.eclipse.ui.tests.markers.artificial.problem";
170+
MarkerType markerTypeFromExtension = descriptor.getType(markerTypeId);
171+
List<String> markerTypeIds = descriptor.getMarkerTypes().stream().map(mt -> mt.getId())
172+
.collect(Collectors.toList());
173+
174+
assertNotNull("Marker type with id '" + markerTypeId + "' not loaded from marker content generator extension.",
175+
markerTypeFromExtension);
176+
assertTrue("Expected marker type id '" + markerTypeId + "' being in marker types list, but we have only "
177+
+ markerTypeIds, markerTypeIds.contains(markerTypeId));
178+
179+
Collection<MarkerGroup> groups = descriptor.getMarkerGroups();
180+
List<String> groupIds = groups.stream().map(g -> g.getId()).collect(Collectors.toList());
181+
String groupId = "org.eclipse.ui.tests.test.extended";
182+
183+
assertTrue("Expected loading group id '" + groupId
184+
+ "' from marker content generator extension, but got only the following group ids: " + groupIds,
185+
groupIds.contains(groupId));
186+
}
187+
188+
private List<String> mapToNames(MarkerField[] markerFields) {
189+
if (markerFields == null || markerFields.length == 0) {
190+
return Collections.emptyList();
191+
}
192+
193+
return Arrays.stream(markerFields).map(mf -> mf.getName()).collect(Collectors.toList());
194+
}
195+
128196
public static MarkerContentGenerator getMarkerContentGenerator(MarkerSupportView view) {
129197
MarkerContentGenerator generator = null;
130198
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+
}

0 commit comments

Comments
 (0)