diff --git a/bundles/org.eclipse.e4.emf.xpath/.settings/.api_filters b/bundles/org.eclipse.e4.emf.xpath/.settings/.api_filters
new file mode 100644
index 00000000000..8c85f39506c
--- /dev/null
+++ b/bundles/org.eclipse.e4.emf.xpath/.settings/.api_filters
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bundles/org.eclipse.e4.emf.xpath/META-INF/MANIFEST.MF b/bundles/org.eclipse.e4.emf.xpath/META-INF/MANIFEST.MF
index 1290213bb2e..74cc46b7049 100644
--- a/bundles/org.eclipse.e4.emf.xpath/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.e4.emf.xpath/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %Bundle-Name
Bundle-SymbolicName: org.eclipse.e4.emf.xpath
-Bundle-Version: 0.4.300.qualifier
+Bundle-Version: 0.5.0.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-17
Require-Bundle: org.eclipse.emf.ecore;bundle-version="2.35.0",
org.eclipse.core.runtime;bundle-version="3.29.0"
diff --git a/bundles/org.eclipse.e4.emf.xpath/src/org/eclipse/e4/emf/internal/xpath/JXPathContextImpl.java b/bundles/org.eclipse.e4.emf.xpath/src/org/eclipse/e4/emf/internal/xpath/JXPathContextImpl.java
index a5b6225d9bf..bb35950e263 100644
--- a/bundles/org.eclipse.e4.emf.xpath/src/org/eclipse/e4/emf/internal/xpath/JXPathContextImpl.java
+++ b/bundles/org.eclipse.e4.emf.xpath/src/org/eclipse/e4/emf/internal/xpath/JXPathContextImpl.java
@@ -21,6 +21,7 @@
import org.apache.commons.jxpath.JXPathContext;
import org.apache.commons.jxpath.NodeSet;
import org.apache.commons.jxpath.Pointer;
+import org.apache.commons.jxpath.util.TypeUtils;
import org.eclipse.e4.emf.xpath.XPathContext;
import org.eclipse.emf.ecore.EObject;
@@ -84,8 +85,11 @@ public Object getValue(String xpath) {
}
@Override
- public Object getValue(String xpath, Class> requiredType) {
- return context.getValue(xpath, requiredType);
+ public T getValue(String xpath, Class requiredType) {
+ Object value = context.getValue(xpath, requiredType);
+ @SuppressWarnings("unchecked")
+ T typedValue = (T) TypeUtils.convert(value, requiredType);
+ return typedValue;
}
@Override
diff --git a/bundles/org.eclipse.e4.emf.xpath/src/org/eclipse/e4/emf/xpath/XPathContext.java b/bundles/org.eclipse.e4.emf.xpath/src/org/eclipse/e4/emf/xpath/XPathContext.java
index a14160ed31c..41ead7162c3 100644
--- a/bundles/org.eclipse.e4.emf.xpath/src/org/eclipse/e4/emf/xpath/XPathContext.java
+++ b/bundles/org.eclipse.e4.emf.xpath/src/org/eclipse/e4/emf/xpath/XPathContext.java
@@ -14,6 +14,12 @@
package org.eclipse.e4.emf.xpath;
import java.util.Iterator;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+import org.apache.commons.jxpath.util.TypeUtils;
/**
* Context in which the xpath is executed
@@ -42,7 +48,7 @@ public interface XPathContext {
* required type
* @return Object found
*/
- Object getValue(String xpath, Class> requiredType);
+ T getValue(String xpath, Class requiredType);
/**
* Traverses the xpath and returns an Iterator of all results found for the
@@ -55,4 +61,22 @@ public interface XPathContext {
* @return Iterator<Object>
*/
Iterator iterate(String xpath);
+
+ /**
+ * Traverses the xpath and returns an {@link Stream} of all results found for
+ * the path. If the xpath matches no properties in the graph, the stream will be
+ * empty.
+ *
+ * @param the expected object type
+ * @param xpath the xpath expression to iterate
+ * @param type the type of elements in the returned stream
+ * @return a stream of elements matching the specified xpath and of the given
+ * type
+ * @since 0.5
+ */
+ default Stream stream(String xpath, Class type) {
+ Iterator> iterator = iterate(xpath);
+ return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.ORDERED), false)
+ .filter(e -> TypeUtils.canConvert(e, type)).map(e -> TypeUtils.convert(e, type)).map(type::cast);
+ }
}
diff --git a/bundles/org.eclipse.e4.ui.model.workbench/src/org/eclipse/e4/ui/model/fragment/impl/StringModelFragmentImpl.java b/bundles/org.eclipse.e4.ui.model.workbench/src/org/eclipse/e4/ui/model/fragment/impl/StringModelFragmentImpl.java
index 895d3b0663a..fe5007880e1 100644
--- a/bundles/org.eclipse.e4.ui.model.workbench/src/org/eclipse/e4/ui/model/fragment/impl/StringModelFragmentImpl.java
+++ b/bundles/org.eclipse.e4.ui.model.workbench/src/org/eclipse/e4/ui/model/fragment/impl/StringModelFragmentImpl.java
@@ -16,8 +16,6 @@
package org.eclipse.e4.ui.model.fragment.impl;
import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;
import org.eclipse.e4.emf.xpath.EcoreXPathContextFactory;
@@ -355,22 +353,14 @@ private void mergeIdList(MApplication application, List ret
private void mergeXPath(MApplication application, List ret, String xPath) {
List targetElements;
if ("/".equals(xPath)) {
- targetElements = Collections.singletonList(application);
+ targetElements = List.of(application);
} else {
XPathContextFactory f = EcoreXPathContextFactory.newInstance();
XPathContext xpathContext = f.newContext((EObject) application);
- Iterator