Skip to content

Commit

Permalink
Load marker content generator details from extensions eclipse-platfor…
Browse files Browse the repository at this point in the history
…m#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 eclipse-platform#2193
  • Loading branch information
travkin79 committed Sep 18, 2024
1 parent dad3444 commit 004743b
Show file tree
Hide file tree
Showing 4 changed files with 239 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Stream;

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

private IConfigurationElement configurationElement;
private MarkerField[] allFields;
private Collection<MarkerType> markerTypes;
private MarkerField[] initialVisible;
private Collection<MarkerGroup> groups;
private MarkerField[] allFieldsWithoutExtensions;
private MarkerField[] initialVisibleWithoutExtensions;
private Collection<IConfigurationElement> generatorExtensions = new ArrayList<>();
private Map<String, MarkerType> allTypesTable;

/**
* Create a new ContentGeneratorDescriptor
Expand All @@ -60,13 +59,13 @@ public ContentGeneratorDescriptor(IConfigurationElement element) {
/**
* Add the groups defined in the receiver to the collection of groups.
*/
private void addDefinedGroups(Collection<MarkerGroup> groupss) {
private void addDefinedGroups(Collection<MarkerGroup> groups) {
// Add the ones in the receiver.
addGroupsFrom(configurationElement, groupss);
addGroupsFrom(configurationElement, groups);
// Add the extensions
Iterator<IConfigurationElement> extensions = generatorExtensions.iterator();
while (extensions.hasNext()) {
addGroupsFrom(extensions.next(), groupss);
addGroupsFrom(extensions.next(), groups);
}
}

Expand Down Expand Up @@ -96,7 +95,7 @@ private void addGroupsFrom(IConfigurationElement element, Collection<MarkerGroup
* @return boolean
*/
public boolean allTypesSelected(Collection<MarkerType> selectedTypes) {
return selectedTypes.containsAll(markerTypes);
return selectedTypes.containsAll(getMarkerTypes());
}

/**
Expand All @@ -105,7 +104,26 @@ public boolean allTypesSelected(Collection<MarkerType> selectedTypes) {
* @return {@link MarkerField}[]
*/
public MarkerField[] getAllFields() {
return allFields;
List<MarkerField> allFieldsList = new ArrayList<>(Arrays.asList(allFieldsWithoutExtensions));

getExtensionsDescriptorsStream().flatMap(descriptor -> Arrays.stream(descriptor.getAllFields()))
.forEach(field -> allFieldsList.add(field));

return allFieldsList.toArray(new MarkerField[allFieldsList.size()]);
}

private Stream<ContentGeneratorDescriptor> getExtensionsDescriptorsStream() {
if (generatorExtensions != null) {
final MarkerSupportRegistry registry = MarkerSupportRegistry.getInstance();

return generatorExtensions.stream()
.map(extensionConfigElem -> extensionConfigElem
.getAttribute(MarkerSupportInternalUtilities.ATTRIBUTE_ID))
.filter(id -> id != null && !id.isBlank())
.map(contentGeneratorId -> registry.getContentGenDescriptor(contentGeneratorId))
.filter(generator -> generator != null);
}
return Stream.empty();
}

/**
Expand Down Expand Up @@ -156,7 +174,12 @@ public String getId() {
* @return {@link MarkerField}[]
*/
public MarkerField[] getInitialVisible() {
return initialVisible;
List<MarkerField> allVisibleFieldsList = new ArrayList<>(Arrays.asList(initialVisibleWithoutExtensions));

getExtensionsDescriptorsStream().flatMap(descriptor -> Arrays.stream(descriptor.getInitialVisible()))
.forEach(field -> allVisibleFieldsList.add(field));

return allVisibleFieldsList.toArray(new MarkerField[allVisibleFieldsList.size()]);
}

/**
Expand All @@ -165,16 +188,15 @@ public MarkerField[] getInitialVisible() {
* @return Collection of {@link MarkerGroup}
*/
public Collection<MarkerGroup> getMarkerGroups() {
if (groups == null) {
groups = new TreeSet<>((mg1, mg2) -> mg1.getMarkerField().getName().compareTo(mg2.getMarkerField().getName()));
Collection<MarkerGroup> groups = new TreeSet<>(
(mg1, mg2) -> mg1.getMarkerField().getName().compareTo(mg2.getMarkerField().getName()));

// Add the groups defined in the receiver
addDefinedGroups(groups);
// Add the groups defined in the receiver
addDefinedGroups(groups);

if (getId().equals(MarkerSupportRegistry.PROBLEMS_GENERATOR)) {
// Add the groups that reference the receiver.
groups.addAll(MarkerSupportRegistry.getInstance().getMarkerGroups());
}
if (getId().equals(MarkerSupportRegistry.PROBLEMS_GENERATOR)) {
// Add the groups that reference the receiver.
groups.addAll(MarkerSupportRegistry.getInstance().getMarkerGroups());
}
return groups;
}
Expand All @@ -185,23 +207,46 @@ public Collection<MarkerGroup> getMarkerGroups() {
* @return Collection of {@link MarkerType}
*/
public Collection<MarkerType> getMarkerTypes() {
if (markerTypes == null) {
markerTypes = new HashSet<>();
IConfigurationElement[] markerTypeElements = configurationElement.getChildren(MarkerSupportRegistry.MARKER_TYPE_REFERENCE);
for (IConfigurationElement configElement : markerTypeElements) {
String elementName = configElement.getAttribute(MarkerSupportInternalUtilities.ATTRIBUTE_ID);
MarkerType[] types = MarkerTypesModel.getInstance().getType(elementName).getAllSubTypes();
markerTypes.addAll(Arrays.asList(types));
markerTypes.add(MarkerTypesModel.getInstance().getType(elementName));
}
if (markerTypes.isEmpty()) {
MarkerType[] types = MarkerTypesModel.getInstance().getType(IMarker.PROBLEM).getAllSubTypes();
markerTypes.addAll(Arrays.asList(types));
}
Set<MarkerType> markerTypes = collectMarkerTypesWithoutExtensions();
addMarkerTypesFromExtensions(markerTypes);
return markerTypes;
}

private Set<MarkerType> collectMarkerTypesWithoutExtensions() {
Set<MarkerType> markerTypes = new HashSet<>();

IConfigurationElement[] markerTypeElements = configurationElement
.getChildren(MarkerSupportRegistry.MARKER_TYPE_REFERENCE);
for (IConfigurationElement configElement : markerTypeElements) {
String elementName = configElement.getAttribute(MarkerSupportInternalUtilities.ATTRIBUTE_ID);
MarkerType[] types = MarkerTypesModel.getInstance().getType(elementName).getAllSubTypes();
markerTypes.addAll(Arrays.asList(types));
markerTypes.add(MarkerTypesModel.getInstance().getType(elementName));
}
if (markerTypes.isEmpty()) {
MarkerType[] types = MarkerTypesModel.getInstance().getType(IMarker.PROBLEM).getAllSubTypes();
markerTypes.addAll(Arrays.asList(types));
}

return markerTypes;
}

private void addMarkerTypesFromExtensions(Collection<MarkerType> markerTypes) {
Iterator<IConfigurationElement> extensions = generatorExtensions.iterator();
while (extensions.hasNext()) {
IConfigurationElement extensionElement = extensions.next();
String extendingMarkerContentGeneratorId = extensionElement
.getAttribute(MarkerSupportInternalUtilities.ATTRIBUTE_ID);
if (extendingMarkerContentGeneratorId != null && !extendingMarkerContentGeneratorId.isBlank()) {
ContentGeneratorDescriptor descriptor = MarkerSupportRegistry.getInstance()
.getContentGenDescriptor(extendingMarkerContentGeneratorId);
if (descriptor != null) {
markerTypes.addAll(descriptor.getMarkerTypes());
}
}
}
}

/**
* Return the name for the receiver.
*
Expand All @@ -227,14 +272,12 @@ public MarkerType getType(String typeId) {
* @return Map of {@link String} to {@link MarkerType}
*/
public Map<String, MarkerType> getTypesTable() {
if (allTypesTable == null) {
allTypesTable = new HashMap<>();
Map<String, MarkerType> allTypesTable = new HashMap<>();

Iterator<MarkerType> allIterator = markerTypes.iterator();
while (allIterator.hasNext()) {
MarkerType next = allIterator.next();
allTypesTable.put(next.getId(), next);
}
Iterator<MarkerType> allIterator = getMarkerTypes().iterator();
while (allIterator.hasNext()) {
MarkerType next = allIterator.next();
allTypesTable.put(next.getId(), next);
}
return allTypesTable;
}
Expand Down Expand Up @@ -264,11 +307,11 @@ public void initializeFromConfigurationElement(
}
}

allFields = new MarkerField[allFieldList.size()];
allFieldList.toArray(allFields);
allFieldsWithoutExtensions = new MarkerField[allFieldList.size()];
allFieldList.toArray(allFieldsWithoutExtensions);

initialVisible = new MarkerField[initialVisibleList.size()];
initialVisibleList.toArray(initialVisible);
initialVisibleWithoutExtensions = new MarkerField[initialVisibleList.size()];
initialVisibleList.toArray(initialVisibleWithoutExtensions);

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.swt.widgets.Button;
Expand All @@ -25,8 +29,13 @@
import org.eclipse.ui.internal.views.markers.FiltersConfigurationDialog;
import org.eclipse.ui.internal.views.markers.MarkerContentGenerator;
import org.eclipse.ui.tests.harness.util.UITestCase;
import org.eclipse.ui.views.markers.MarkerField;
import org.eclipse.ui.views.markers.MarkerSupportView;
import org.eclipse.ui.views.markers.internal.ContentGeneratorDescriptor;
import org.eclipse.ui.views.markers.internal.MarkerGroup;
import org.eclipse.ui.views.markers.internal.MarkerMessages;
import org.eclipse.ui.views.markers.internal.MarkerSupportRegistry;
import org.eclipse.ui.views.markers.internal.MarkerType;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
Expand Down Expand Up @@ -125,6 +134,65 @@ public void limitDisabled() throws Exception {
assertFalse(isLimitEnabled);
}

@Test
public void markerContentGeneratorExtensionLoaded() throws Exception {
MarkerSupportView view = (MarkerSupportView) PlatformUI.getWorkbench().getActiveWorkbenchWindow()
.getActivePage().showView(PROBLEM_VIEW_ID);

MarkerContentGenerator generator = getMarkerContentGenerator(view);
ContentGeneratorDescriptor descriptor = MarkerSupportRegistry.getInstance()
.getContentGenDescriptor(generator.getId());

assertNotNull(descriptor);

MarkerField[] allFields = descriptor.getAllFields();
List<String> allFieldNames = mapToNames(allFields);
String fieldName1 = "Problem Key", fieldName2 = "Problem Key V2";

assertTrue(
"Expected loading marker field '" + fieldName1
+ "' from marker content generator extensions, but got only " + allFieldNames,
allFieldNames.contains(fieldName1));
assertTrue(
"Expected recursively loading marker field '" + fieldName2
+ "' from marker content generator extensions, but got only " + allFieldNames,
allFieldNames.contains(fieldName2));

MarkerField[] initiallyVisibleFields = descriptor.getInitialVisible();
List<String> initiallyVisibleFieldNames = mapToNames(initiallyVisibleFields);

assertTrue("Expected marker field '" + fieldName1
+ "' from marker content generator extension being visible according to 'visible' attribute in the extension,"
+ " but only the following marker fields are visible " + initiallyVisibleFieldNames,
initiallyVisibleFieldNames.contains(fieldName1));

String markerTypeId = "org.eclipse.ui.tests.markers.artificial.problem";
MarkerType markerTypeFromExtension = descriptor.getType(markerTypeId);
List<String> markerTypeIds = descriptor.getMarkerTypes().stream().map(mt -> mt.getId())
.collect(Collectors.toList());

assertNotNull("Marker type with id '" + markerTypeId + "' not loaded from marker content generator extension.",
markerTypeFromExtension);
assertTrue("Expected marker type id '" + markerTypeId + "' being in marker types list, but we have only "
+ markerTypeIds, markerTypeIds.contains(markerTypeId));

Collection<MarkerGroup> groups = descriptor.getMarkerGroups();
List<String> groupIds = groups.stream().map(g -> g.getId()).collect(Collectors.toList());
String groupId = "org.eclipse.ui.tests.test.extended";

assertTrue("Expected loading group id '" + groupId
+ "' from marker content generator extension, but got only the following group ids: " + groupIds,
groupIds.contains(groupId));
}

private List<String> mapToNames(MarkerField[] markerFields) {
if (markerFields == null || markerFields.length == 0) {
return Collections.emptyList();
}

return Arrays.stream(markerFields).map(mf -> mf.getName()).collect(Collectors.toList());
}

public static MarkerContentGenerator getMarkerContentGenerator(MarkerSupportView view) {
MarkerContentGenerator generator = null;
try {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.eclipse.ui.tests.markers;

import org.eclipse.ui.views.markers.MarkerField;
import org.eclipse.ui.views.markers.MarkerItem;

public class ProblemKeyMarkerField extends MarkerField {

@Override
public String getValue(MarkerItem item) {
if (item == null) {
return "";
}
return item.getAttributeValue("problemKey", "");
}

}
Loading

0 comments on commit 004743b

Please sign in to comment.