From 063ed05e28bb281d153716dcf7c91406b37fbd64 Mon Sep 17 00:00:00 2001 From: Patrick Ziegler Date: Fri, 11 Oct 2024 06:16:47 +0200 Subject: [PATCH] Initial support for parent context-handling --- .../java/JavaXPathContextFactoryImpl.java | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/bundles/org.eclipse.e4.emf.xpath/src/org/eclipse/e4/emf/xpath/internal/java/JavaXPathContextFactoryImpl.java b/bundles/org.eclipse.e4.emf.xpath/src/org/eclipse/e4/emf/xpath/internal/java/JavaXPathContextFactoryImpl.java index c0cea8520d5..3505ab16d00 100644 --- a/bundles/org.eclipse.e4.emf.xpath/src/org/eclipse/e4/emf/xpath/internal/java/JavaXPathContextFactoryImpl.java +++ b/bundles/org.eclipse.e4.emf.xpath/src/org/eclipse/e4/emf/xpath/internal/java/JavaXPathContextFactoryImpl.java @@ -59,9 +59,14 @@ public XPathContext newContext(XPathContext parentContext, T contextBean) { if (!(contextBean instanceof EObject rootObject)) { throw new IllegalArgumentException(); } - // TODO: consider parent-context (may be null). Require the context-bean to be - // from the same resource? Then we can also reuse all maps and the XPath object - + if (parentContext != null) { + EObjectContext parent = ((EObjectContext) parentContext); + Element rootElement = parent.object2domProxy.get(contextBean); + if (rootElement == null) { + throw new IllegalArgumentException("Context bean is not from the same tree its parent context"); + } + return new EObjectContext(rootElement, parent); + } DocumentBuilder documentBuilder; try { documentBuilder = DocumentBuilderFactory.newDefaultInstance().newDocumentBuilder(); @@ -86,7 +91,7 @@ public XPathContext newContext(XPathContext parentContext, T contextBean) { domProxy2object.put(proxy, eObject); }); - return new EObjectContext(rootElement, domProxy2object); + return new EObjectContext(rootElement, domProxy2object, object2domProxy); } private static class EObjectContext implements XPathContext { @@ -96,14 +101,24 @@ private static class EObjectContext implements XPathContext { private final XPath xpath; private final Element rootElement; private final Map domProxy2object; + private final Map object2domProxy; - private EObjectContext(Element rootElement, Map domProxy2object) { + private EObjectContext(Element rootElement, Map domProxy2object, + Map object2domProxy) { this.rootElement = rootElement; this.domProxy2object = Map.copyOf(domProxy2object); + this.object2domProxy = Map.copyOf(object2domProxy); this.xpath = XPATH_FACTORY.newXPath(); this.xpath.setXPathFunctionResolver(this::resolveEMFFunctions); } + private EObjectContext(Element rootElement, EObjectContext parentContext) { + this.rootElement = rootElement; + this.domProxy2object = Map.copyOf(parentContext.domProxy2object); + this.object2domProxy = Map.copyOf(parentContext.object2domProxy); + this.xpath = parentContext.xpath; + } + @Override public Stream stream(String path, Class resultType) { // See XPathResultType for generally supported result types