Skip to content

Commit 35966f3

Browse files
committed
[E4] Introduce EModelService.findMatchingElements() as Xpath replacement
1 parent 4e127ef commit 35966f3

File tree

6 files changed

+65
-11
lines changed

6 files changed

+65
-11
lines changed

bundles/org.eclipse.e4.ui.model.workbench/META-INF/MANIFEST.MF

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ Bundle-Version: 2.4.400.qualifier
66
Bundle-Vendor: %providerName
77
Bundle-Localization: plugin
88
Bundle-RequiredExecutionEnvironment: JavaSE-17
9-
Export-Package: org.eclipse.e4.ui.model;x-friends:="org.eclipse.e4.ui.workbench,org.eclipse.e4.ui.workbench.swt,org.eclipse.ui.workbench",
9+
Export-Package: org.eclipse.e4.ui.model;
10+
x-friends:="org.eclipse.e4.ui.workbench,
11+
org.eclipse.e4.ui.workbench.swt,
12+
org.eclipse.ui.workbench,
13+
org.eclipse.e4.tools.emf.ui",
1014
org.eclipse.e4.ui.model.application,
1115
org.eclipse.e4.ui.model.application.commands,
1216
org.eclipse.e4.ui.model.application.commands.impl;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Hannes Wellmann and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* Hannes Wellmann - initial API and implementation
13+
*******************************************************************************/
14+
package org.eclipse.e4.ui.model;
15+
16+
import java.util.stream.Stream;
17+
import org.eclipse.e4.emf.xpath.XPathContextFactory;
18+
import org.eclipse.e4.ui.model.application.MApplicationElement;
19+
20+
public class ModelXPathEvaluator {
21+
22+
public static <T> Stream<T> findMatchingElements(MApplicationElement searchRoot, String xPath, Class<T> clazz) {
23+
return XPathContextFactory.newInstance().newContext(searchRoot).stream(xPath, clazz);
24+
}
25+
26+
// Inline the then still used part of JavaXPathContextFactoryImpl here once the
27+
// e4.emf.xpath bundle is finally removed
28+
}

bundles/org.eclipse.e4.ui.model.workbench/src/org/eclipse/e4/ui/model/fragment/impl/StringModelFragmentImpl.java

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,8 @@
1818
import java.util.ArrayList;
1919
import java.util.List;
2020
import java.util.regex.Pattern;
21-
import org.eclipse.e4.emf.xpath.EcoreXPathContextFactory;
22-
import org.eclipse.e4.emf.xpath.XPathContext;
23-
import org.eclipse.e4.emf.xpath.XPathContextFactory;
21+
import org.eclipse.core.runtime.ILog;
22+
import org.eclipse.e4.ui.model.ModelXPathEvaluator;
2423
import org.eclipse.e4.ui.model.application.MApplication;
2524
import org.eclipse.e4.ui.model.application.MApplicationElement;
2625
import org.eclipse.e4.ui.model.fragment.MStringModelFragment;
@@ -282,10 +281,10 @@ public boolean eIsSet(int featureID) {
282281
return FEATURENAME_EDEFAULT == null ? featurename != null : !FEATURENAME_EDEFAULT.equals(featurename);
283282
case FragmentPackageImpl.STRING_MODEL_FRAGMENT__PARENT_ELEMENT_ID:
284283
return PARENT_ELEMENT_ID_EDEFAULT == null ? parentElementId != null
285-
: !PARENT_ELEMENT_ID_EDEFAULT.equals(parentElementId);
284+
: !PARENT_ELEMENT_ID_EDEFAULT.equals(parentElementId);
286285
case FragmentPackageImpl.STRING_MODEL_FRAGMENT__POSITION_IN_LIST:
287286
return POSITION_IN_LIST_EDEFAULT == null ? positionInList != null
288-
: !POSITION_IN_LIST_EDEFAULT.equals(positionInList);
287+
: !POSITION_IN_LIST_EDEFAULT.equals(positionInList);
289288
default:
290289
return super.eIsSet(featureID);
291290
}
@@ -355,14 +354,13 @@ private void mergeXPath(MApplication application, List<MApplicationElement> ret,
355354
if ("/".equals(xPath)) {
356355
targetElements = List.of(application);
357356
} else {
358-
XPathContextFactory<EObject> f = EcoreXPathContextFactory.newInstance();
359-
XPathContext xpathContext = f.newContext((EObject) application);
360357
try {
361-
targetElements = xpathContext.stream(xPath, MApplicationElement.class).toList();
358+
targetElements = ModelXPathEvaluator.findMatchingElements(application, xPath, MApplicationElement.class)
359+
.toList();
362360
} catch (Exception ex) {
363361
targetElements = List.of();
364362
// custom xpath functions will throw exceptions
365-
ex.printStackTrace();
363+
ILog.get().error("Failed to evaluate xpath: " + xPath, ex); //$NON-NLS-1$
366364
}
367365
}
368366
for (MApplicationElement targetElement : targetElements) {

bundles/org.eclipse.e4.ui.workbench/META-INF/MANIFEST.MF

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Manifest-Version: 1.0
22
Bundle-ManifestVersion: 2
33
Bundle-SymbolicName: org.eclipse.e4.ui.workbench;singleton:=true
4-
Bundle-Version: 1.16.100.qualifier
4+
Bundle-Version: 1.17.0.qualifier
55
Bundle-Name: %pluginName
66
Bundle-Vendor: %providerName
77
Bundle-Localization: plugin

bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/ModelServiceImpl.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,14 @@
2727
import java.util.LinkedHashSet;
2828
import java.util.List;
2929
import java.util.Objects;
30+
import java.util.stream.Stream;
3031
import org.eclipse.core.runtime.Assert;
3132
import org.eclipse.core.runtime.IExtensionRegistry;
3233
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
3334
import org.eclipse.e4.core.contexts.IEclipseContext;
3435
import org.eclipse.e4.core.services.events.IEventBroker;
3536
import org.eclipse.e4.core.services.log.Logger;
37+
import org.eclipse.e4.ui.model.ModelXPathEvaluator;
3638
import org.eclipse.e4.ui.model.application.MAddon;
3739
import org.eclipse.e4.ui.model.application.MApplication;
3840
import org.eclipse.e4.ui.model.application.MApplicationElement;
@@ -434,6 +436,11 @@ public <T> List<T> findElements(MApplicationElement searchRoot, Class<T> clazz,
434436
return new ArrayList<>(elements);
435437
}
436438

439+
@Override
440+
public <T> Stream<T> findMatchingElements(MApplicationElement searchRoot, String xPath, Class<T> clazz) {
441+
return ModelXPathEvaluator.findMatchingElements(searchRoot, xPath, clazz);
442+
}
443+
437444
private <T> Iterable<T> findPerspectiveElements(MUIElement searchRoot, String id,
438445
Class<T> clazz,
439446
List<String> tagsToMatch) {

bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/workbench/modeling/EModelService.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package org.eclipse.e4.ui.workbench.modeling;
1818

1919
import java.util.List;
20+
import java.util.stream.Stream;
2021
import org.eclipse.e4.core.contexts.IEclipseContext;
2122
import org.eclipse.e4.ui.model.application.MApplicationElement;
2223
import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptor;
@@ -279,6 +280,22 @@ <T> List<T> findElements(MUIElement searchRoot, String id, Class<T> clazz,
279280
<T> List<T> findElements(MApplicationElement searchRoot, Class<T> clazz,
280281
int searchFlags, Selector matcher);
281282

283+
/**
284+
* Returns a stream of any elements that are matched by the specified
285+
* {@code XPath} expression relative to the given {@code searchRoot}.
286+
*
287+
* @param <T> The generic type of the returned stream
288+
* @param searchRoot The element relative to which the {@code XPath} expression
289+
* is evaluated. This element must be non-null.
290+
* @param xPath the {@code XPath (XML Path Language)} expression matched
291+
* against the root
292+
* @param clazz The type of element to be searched for.
293+
* @return The stream of matching elements.
294+
*
295+
* @since 1.17
296+
*/
297+
<T> Stream<T> findMatchingElements(MApplicationElement searchRoot, String xPath, Class<T> clazz);
298+
282299
/**
283300
* Returns the first element, recursively searching under the specified search
284301
* root (inclusive)

0 commit comments

Comments
 (0)