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 74cc46b7049..1fd6ad3841b 100644 --- a/bundles/org.eclipse.e4.emf.xpath/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.e4.emf.xpath/META-INF/MANIFEST.MF @@ -5,6 +5,7 @@ Bundle-SymbolicName: org.eclipse.e4.emf.xpath Bundle-Version: 0.5.0.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-17 Require-Bundle: org.eclipse.emf.ecore;bundle-version="2.35.0", + org.eclipse.emf.ecore.xmi;bundle-version="2.35.0", org.eclipse.core.runtime;bundle-version="3.29.0" Export-Package: org.eclipse.e4.emf.internal.xpath;x-internal:=true, org.eclipse.e4.emf.internal.xpath.helper;x-friends:="org.eclipse.e4.emf.xpath.test,org.eclipse.e4.ui.model.workbench,org.eclipse.e4.ui.workbench", diff --git a/bundles/org.eclipse.e4.emf.xpath/src/org/eclipse/e4/emf/xpath/JavaXPathFactory.java b/bundles/org.eclipse.e4.emf.xpath/src/org/eclipse/e4/emf/xpath/JavaXPathFactory.java new file mode 100644 index 00000000000..60464da530f --- /dev/null +++ b/bundles/org.eclipse.e4.emf.xpath/src/org/eclipse/e4/emf/xpath/JavaXPathFactory.java @@ -0,0 +1,39 @@ +package org.eclipse.e4.emf.xpath; + +import org.eclipse.e4.emf.xpath.internal.java.JavaXPathFactoryImpl; +import org.eclipse.emf.ecore.EObject; + +/** + * @since 0.5 + */ +public abstract class JavaXPathFactory { + /** + * Creates a new XPathContext with the specified object as the root node. + * + * @param contextBean Object + * @return XPathContext + */ + public abstract XPathContext newContext(T contextBean); + + /** + * Creates a new XPathContext with the specified bean as the root node and the + * specified parent context. Variables defined in a parent context can be + * referenced in XPaths passed to the child context. + * + * @param parentContext parent context + * @param contextBean Object + * @return XPathContext + */ + public abstract XPathContext newContext(XPathContext parentContext, T contextBean); + + /** + * @param the object type the xpath is created for + * @return Create a new XPath-Factory + */ + public static XPathContextFactory newInstance() { + return new JavaXPathFactoryImpl<>(); + } + + + +} diff --git a/bundles/org.eclipse.e4.emf.xpath/src/org/eclipse/e4/emf/xpath/internal/java/EObjectContext.java b/bundles/org.eclipse.e4.emf.xpath/src/org/eclipse/e4/emf/xpath/internal/java/EObjectContext.java new file mode 100644 index 00000000000..40fd3754956 --- /dev/null +++ b/bundles/org.eclipse.e4.emf.xpath/src/org/eclipse/e4/emf/xpath/internal/java/EObjectContext.java @@ -0,0 +1,177 @@ +package org.eclipse.e4.emf.xpath.internal.java; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Spliterators; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathEvaluationResult; +import javax.xml.xpath.XPathEvaluationResult.XPathResultType; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathFactory; +import javax.xml.xpath.XPathNodes; + +import org.eclipse.e4.emf.xpath.XPathContext; +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.ecore.xmi.XMLHelper; +import org.eclipse.emf.ecore.xmi.XMLResource; +import org.eclipse.emf.ecore.xmi.impl.XMLHelperImpl; +import org.w3c.dom.DOMImplementation; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.ls.DOMImplementationLS; +import org.w3c.dom.ls.LSSerializer; + +public class EObjectContext implements XPathContext { + private final String PROXY_KEY = "EObjectContext.Proxy"; + private final Map proxy2node; + private final EObjectContext parentContext; + private final Document root; + private XMLHelper xml; + + public EObjectContext() throws ParserConfigurationException { + this(null); + } + + public EObjectContext(EObjectContext parentContext) throws ParserConfigurationException { + this.proxy2node = new HashMap<>(); + this.parentContext = parentContext; + if (parentContext == null) { + this.root = DocumentBuilderFactory.newDefaultInstance().newDocumentBuilder().newDocument(); + } else { + this.root = parentContext.root; + } + } + + @Override + public Object getValue(String xpath) { + Iterator iterate = iterate(xpath); + return iterate.hasNext() ? iterate.next() : null; + } + + @Override + public T getValue(String xpath, Class requiredType) { + return requiredType.cast(getValue(xpath)); + } + + @Override + @SuppressWarnings("unchecked") + public Iterator iterate(String xpath) { + return (Iterator) stream(xpath, Object.class).iterator(); + } + + @Override + public Stream stream(String path, Class type) { + try { + XPathFactory factory = XPathFactory.newInstance(); +// factory.setXPathFunctionResolver((functionName, arity) -> null); +// factory.setXPathVariableResolver(e -> null); + XPath xpath = factory.newXPath(); + /* + EObjectNodePointer item = new EObjectNodePointer(contextObject); + XPathEvaluationResult evaluateExpression = xpath.evaluateExpression(path, item); + XPathNodes value1 = (XPathNodes) evaluateExpression.value(); + if (value1.size() > 0) { + Node node = value1.get(0); + System.out.println(node); + }*/ + +// path = "/Application/TrimmedWindow"; + XPathEvaluationResult result1 = xpath.evaluateExpression(path, root); + XPathNodes nodes2 = (XPathNodes) result1.value(); + if (nodes2.size() > 0) { + Node node = nodes2.get(0); + + System.out.println(node); + } + + prettyPrint(); + + XPathExpression expr = xpath.compile(path); + XPathEvaluationResult result = expr.evaluateExpression(root, XPathEvaluationResult.class); + XPathResultType type2 = result.type(); + Object value = result.value(); + + NodeList nodes1 = (NodeList) expr.evaluate(root, XPathConstants.NODESET); + XPathNodes nodes = expr.evaluateExpression(root, XPathNodes.class); + + System.out.println(nodes1.getLength()); + System.out.println(nodes.size()); + + Stream stream = StreamSupport.stream(Spliterators.spliterator(nodes.iterator(), nodes.size(), 0), + false); + return stream.map(this::getProxy).map(type::cast); + } catch (Exception e1) { + throw new IllegalStateException(e1); + } + } + + private void prettyPrint() { + final DOMImplementation implementation = root.getImplementation(); + final DOMImplementationLS domImplementation = (DOMImplementationLS) implementation; + final LSSerializer serial = domImplementation.createLSSerializer(); + serial.getDomConfig().setParameter("format-pretty-print", Boolean.TRUE); + + final String writeToString = serial.writeToString(root); + System.out.println(writeToString); + } + + protected Element getNode(EObject proxy) { + return (Element) proxy2node.get(proxy); + } + + protected EObject getProxy(Node element) { + return (EObject) element.getUserData(PROXY_KEY); + } + + protected Element addRoot(EObject eObject) { + // TODO What about other types of resources? + xml = new XMLHelperImpl((XMLResource) eObject.eResource()); + Element object = createElement(eObject); + if (parentContext == null) { + root.appendChild(object); + } else { + Element parentObject = getNode(eObject.eContainer()); + parentObject.appendChild(object); + } + return object; + } + + protected Element add(EObject eChildObject, EObject eParentObject) { + Element childObject = createElement(eChildObject); + Node parentObject = proxy2node.get(eParentObject); + parentObject.appendChild(childObject); + return childObject; + } + + private Element createElement(EObject eObject) { + // TODO: Better way to get the "root" QName + String qName = "application"; + if (eObject.eContainingFeature() != null) { + qName = xml.getQName(eObject.eContainingFeature()); + } + Element object = root.createElement(qName); + object.setUserData(PROXY_KEY, eObject, null); + proxy2node.put(eObject, object); + List eAttributes = eObject.eClass().getEAllAttributes(); + for (EAttribute eAttribute : eAttributes) { + if (eObject.eIsSet(eAttribute)) { + Object value = eObject.eGet(eAttribute); + String stringValue = EcoreUtil.convertToString(eAttribute.getEAttributeType(), value); + object.setAttribute(eAttribute.getName(), stringValue); + } + } + return object; + } +} diff --git a/bundles/org.eclipse.e4.emf.xpath/src/org/eclipse/e4/emf/xpath/internal/java/EObjectNodePointer.java b/bundles/org.eclipse.e4.emf.xpath/src/org/eclipse/e4/emf/xpath/internal/java/EObjectNodePointer.java new file mode 100644 index 00000000000..c5450daed1c --- /dev/null +++ b/bundles/org.eclipse.e4.emf.xpath/src/org/eclipse/e4/emf/xpath/internal/java/EObjectNodePointer.java @@ -0,0 +1,435 @@ +package org.eclipse.e4.emf.xpath.internal.java; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.w3c.dom.Attr; +import org.w3c.dom.DOMException; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.TypeInfo; +import org.w3c.dom.UserDataHandler; + +// TODO Is this still needed? +public class EObjectNodePointer implements Element { + + private final String name; + private final Document document; + private final EObject eObject; + private final EObjectNodePointer parent; +// private final Map obj2nodes; + + public EObjectNodePointer(EObject eObject) throws ParserConfigurationException { + this.name = eObject.eClass().getName(); + this.eObject = eObject; + this.parent = null; + // TODO: check if document is necessary + this.document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); + } + + public EObjectNodePointer(String name, EObject eObject, +// Map obj2nodes, + EObjectNodePointer parent, Document document) { + this.name = name; + this.eObject = eObject; +// this.obj2nodes = obj2nodes; + this.parent = parent; + this.document = document; + } + + // TODO: hashCode/equals? + + @Override + public String getNodeName() { + return name; + } + + @Override + public String getTagName() { + return name; + } + + @Override + public String getNodeValue() throws DOMException { + throw unsupportedOperation(); + } + + @Override + public void setNodeValue(String nodeValue) throws DOMException { + throw unsupportedOperation(); + } + + @Override + public short getNodeType() { + return ELEMENT_NODE; + } + + @Override + public Node getParentNode() { + return parent; + } + + @Override + public boolean hasChildNodes() { + EClass eClass = eObject.eClass(); + return availableAttributes(eClass.getEAllAttributes()).findAny().isPresent() + || availableReferences(eClass).findAny().isPresent(); + } + + @Override + public NodeList getChildNodes() { + EClass eClass = eObject.eClass(); + var attributeNodes = availableAttributes(eClass.getEAllAttributes()).map(this::createAttributeNode); + var referenceNodes = availableReferences(eClass).flatMap(this::createReferenceNodes); + List childNodes = Stream.concat(attributeNodes, referenceNodes).toList(); + return new NodeList() { + + @Override + public Node item(int index) { + return childNodes.get(index); + } + + @Override + public int getLength() { + return childNodes.size(); + } + }; + } + + private Stream availableReferences(EClass eClass) { + return eClass.getEAllReferences().stream().filter(r -> r.isContainment()).filter(eObject::eIsSet); + } + + private Stream createReferenceNodes(EReference ref) { + Object value = this.eObject.eGet(ref); + Stream stream = value instanceof List list ? list.stream() : Stream.of(value); + return stream.map(EObject.class::cast) + .map(e -> new EObjectNodePointer(ref.getName(), e, /* obj2nodes, */ this, document)); + } + + @Override + public Node getFirstChild() { + throw unsupportedOperation(); + } + + @Override + public Node getLastChild() { + throw unsupportedOperation(); + } + + @Override + public Node getPreviousSibling() { + throw unsupportedOperation(); + } + + @Override + public Node getNextSibling() { + throw unsupportedOperation(); + } + + @Override + public boolean hasAttributes() { + return availableAttributes(eObject.eClass().getEAllAttributes()).findAny().isPresent(); + } + + private Stream availableAttributes(List allAttributes) { + return allAttributes.stream().filter(eObject::eIsSet); + } + + private Node createAttributeNode(EAttribute attribute) { + Object value = eObject.eIsSet(attribute) ? eObject.eGet(attribute) : null; + Attr attributeNode = document.createAttribute(attribute.getName()); + String strValue = EcoreUtil.convertToString(attribute.getEAttributeType(), value); + attributeNode.setValue(strValue); + return attributeNode; + } + + @Override + public NamedNodeMap getAttributes() { + List allAttributes = eObject.eClass().getEAllAttributes(); + return new NamedNodeMap() { + + @Override + public Node setNamedItemNS(Node arg) throws DOMException { + throw unsupportedOperation(); + } + + @Override + public Node setNamedItem(Node arg) throws DOMException { + throw unsupportedOperation(); + } + + @Override + public Node removeNamedItemNS(String namespaceURI, String localName) throws DOMException { + throw unsupportedOperation(); + } + + @Override + public Node removeNamedItem(String name) throws DOMException { + throw unsupportedOperation(); + } + + @Override + public Node item(int index) { + var attribute = availableAttributes(allAttributes).skip(index).findFirst(); + return attribute.isPresent() ? createAttributeNode(attribute.get()) : null; + } + + @Override + public Node getNamedItemNS(String namespaceURI, String localName) throws DOMException { + throw unsupportedOperation(); + } + + @Override + public Node getNamedItem(String name) { + var attribute = allAttributes.stream().filter(a -> a.getName().equals(name)).findFirst(); + return attribute.isPresent() ? createAttributeNode(attribute.get()) : null; + } + + @Override + public int getLength() { + return (int) availableAttributes(allAttributes).count(); + } + }; + } + + @Override + public String getAttribute(String name) { + return getAttributes().getNamedItem(name).getNodeValue(); + } + + @Override + public Document getOwnerDocument() { + return document; + } + + @Override + public boolean isSameNode(Node other) { + return other instanceof EObjectNodePointer node // + && node.name == name && node.eObject == eObject; + } + + @Override + public boolean isEqualNode(Node arg) { + return arg instanceof EObjectNodePointer node && Objects.equals(node.eObject, eObject); + } + + @Override + public String toString() { + return "[" + getTagName() + availableAttributes(eObject.eClass().getEAllAttributes()) + .map(a -> a.getName() + "=" + eObject.eGet(a)).collect(Collectors.joining(" ", " ", "]")); + } + + private static UnsupportedOperationException unsupportedOperation() { + return new UnsupportedOperationException(); + } + + @Override + public Node insertBefore(Node newChild, Node refChild) throws DOMException { + throw unsupportedOperation(); + } + + @Override + public Node replaceChild(Node newChild, Node oldChild) throws DOMException { + throw unsupportedOperation(); + } + + @Override + public Node removeChild(Node oldChild) throws DOMException { + throw unsupportedOperation(); + } + + @Override + public Node appendChild(Node newChild) throws DOMException { + throw unsupportedOperation(); + } + + @Override + public Node cloneNode(boolean deep) { + throw unsupportedOperation(); + } + + @Override + public void normalize() { + throw unsupportedOperation(); + } + + @Override + public boolean isSupported(String feature, String version) { + throw unsupportedOperation(); + } + + @Override + public String getNamespaceURI() { + return null; + } + + @Override + public String getPrefix() { + throw unsupportedOperation(); + } + + @Override + public void setPrefix(String prefix) throws DOMException { + throw unsupportedOperation(); + } + + @Override + public String getLocalName() { + return null; + } + + @Override + public String getBaseURI() { + throw unsupportedOperation(); + } + + @Override + public short compareDocumentPosition(Node other) throws DOMException { + throw unsupportedOperation(); + } + + @Override + public String getTextContent() throws DOMException { + throw unsupportedOperation(); + } + + @Override + public void setTextContent(String textContent) throws DOMException { + throw unsupportedOperation(); + } + + @Override + public String lookupPrefix(String namespaceURI) { + throw unsupportedOperation(); + } + + @Override + public boolean isDefaultNamespace(String namespaceURI) { + throw unsupportedOperation(); + } + + @Override + public String lookupNamespaceURI(String prefix) { + throw unsupportedOperation(); + } + + @Override + public Object getFeature(String feature, String version) { + throw unsupportedOperation(); + } + + @Override + public Object setUserData(String key, Object data, UserDataHandler handler) { + throw unsupportedOperation(); + } + + @Override + public Object getUserData(String key) { + throw unsupportedOperation(); + } + + @Override + public void setAttribute(String name, String value) throws DOMException { + throw unsupportedOperation(); + } + + @Override + public void removeAttribute(String name) throws DOMException { + throw unsupportedOperation(); + } + + @Override + public Attr getAttributeNode(String name) { + return (Attr) getAttributes().getNamedItem(name); + } + + @Override + public Attr setAttributeNode(Attr newAttr) throws DOMException { + throw unsupportedOperation(); + } + + @Override + public Attr removeAttributeNode(Attr oldAttr) throws DOMException { + throw unsupportedOperation(); + } + + @Override + public NodeList getElementsByTagName(String name) { + throw unsupportedOperation(); + } + + @Override + public String getAttributeNS(String namespaceURI, String localName) throws DOMException { + throw unsupportedOperation(); + } + + @Override + public void setAttributeNS(String namespaceURI, String qualifiedName, String value) throws DOMException { + throw unsupportedOperation(); + } + + @Override + public void removeAttributeNS(String namespaceURI, String localName) throws DOMException { + throw unsupportedOperation(); + } + + @Override + public Attr getAttributeNodeNS(String namespaceURI, String localName) throws DOMException { + throw unsupportedOperation(); + } + + @Override + public Attr setAttributeNodeNS(Attr newAttr) throws DOMException { + throw unsupportedOperation(); + } + + @Override + public NodeList getElementsByTagNameNS(String namespaceURI, String localName) throws DOMException { + throw unsupportedOperation(); + } + + @Override + public boolean hasAttribute(String name) { + return getAttributes().getNamedItem(name) != null; + } + + @Override + public boolean hasAttributeNS(String namespaceURI, String localName) throws DOMException { + throw unsupportedOperation(); + } + + @Override + public TypeInfo getSchemaTypeInfo() { + throw unsupportedOperation(); + } + + @Override + public void setIdAttribute(String name, boolean isId) throws DOMException { + throw unsupportedOperation(); + } + + @Override + public void setIdAttributeNS(String namespaceURI, String localName, boolean isId) throws DOMException { + throw unsupportedOperation(); + } + + @Override + public void setIdAttributeNode(Attr idAttr, boolean isId) throws DOMException { + throw unsupportedOperation(); + } + + } \ No newline at end of file diff --git a/bundles/org.eclipse.e4.emf.xpath/src/org/eclipse/e4/emf/xpath/internal/java/JavaXPathFactoryImpl.java b/bundles/org.eclipse.e4.emf.xpath/src/org/eclipse/e4/emf/xpath/internal/java/JavaXPathFactoryImpl.java new file mode 100644 index 00000000000..95d44b5e51e --- /dev/null +++ b/bundles/org.eclipse.e4.emf.xpath/src/org/eclipse/e4/emf/xpath/internal/java/JavaXPathFactoryImpl.java @@ -0,0 +1,103 @@ +package org.eclipse.e4.emf.xpath.internal.java; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathFactory; + +import org.eclipse.e4.emf.xpath.XPathContext; +import org.eclipse.e4.emf.xpath.XPathContextFactory; +import org.eclipse.emf.ecore.EObject; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +public class JavaXPathFactoryImpl extends XPathContextFactory { + + public static void main(String[] args) throws Exception { + // parse the XML as a W3C Document + DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + Document document; +// FileInputStream inputStream = new FileInputStream(new File("widgets.xml")); + ByteArrayInputStream inputStream = new ByteArrayInputStream(""" + + + + + + """.getBytes(StandardCharsets.UTF_8)); + try (InputStream stream = inputStream) { + document = builder.parse(new File("widgets.xml")); + } + document = builder.newDocument(); + Element root = document.createElement("foo"); + root.appendChild(document.createElement("bar")); + root.appendChild(document.createElement("bar")); + root.appendChild(document.createElement("bar")); + document.appendChild(root); + + // Get an XPath object and evaluate the expression + XPath xpath = XPathFactory.newInstance().newXPath(); + String expression = "/foo/bar"; + Node evaluateExpression = xpath.evaluateExpression(expression, document, Node.class); + Node widgetNode = (Node) xpath.evaluate(expression, document, XPathConstants.NODE); + + // or using the evaluateExpression method + Node widgetNode2 = xpath.evaluateExpression(expression, document, Node.class); + } + + @Override + public XPathContext newContext(T contextBean) { + return newContext(null, contextBean); + } + + @Override + public XPathContext newContext(XPathContext parentContext, T contextBean) { + if (!(contextBean instanceof EObject contextObject)) { + throw new IllegalArgumentException(); + } + // TODO: consider parent-context (may be null) + + EObjectContext context; + + try { + // TODO: What about the compatibility with other contexts' + context = new EObjectContext((EObjectContext) parentContext); + } catch (ParserConfigurationException e) { + throw new IllegalStateException(e); + } + + context.addRoot(contextObject); + contextObject.eContents(); + contextObject.eAllContents().forEachRemaining(eObject -> { + EObject eParent = eObject.eContainer(); + if (context.getNode(eObject) == null) { + context.add(eObject, eParent); + } + }); + /* + DOMImplementation implementation = proxyDoc.getImplementation(); + final DOMImplementationLS domImplementation = (DOMImplementationLS) implementation; + LSSerializer serial = domImplementation.createLSSerializer(); + serial.getDomConfig().setParameter("format-pretty-print", Boolean.TRUE); + String writeToString = serial.writeToString(proxyDoc); + System.out.println(writeToString); + */ +// try { +// proxyDoc = documentBuilder.parse(new ByteArrayInputStream(writeToString.getBytes(StandardCharsets.UTF_16))); +// +// } catch (SAXException | IOException e) { +// throw new IllegalStateException(e); +// } + + return context; + } + +} \ No newline at end of file diff --git a/bundles/org.eclipse.e4.emf.xpath/widgets.xml b/bundles/org.eclipse.e4.emf.xpath/widgets.xml new file mode 100644 index 00000000000..aa762be0e4c --- /dev/null +++ b/bundles/org.eclipse.e4.emf.xpath/widgets.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/tests/org.eclipse.e4.emf.xpath.test/src/org/eclipse/e4/emf/xpath/test/ExampleQueriesApplicationTest.java b/tests/org.eclipse.e4.emf.xpath.test/src/org/eclipse/e4/emf/xpath/test/ExampleQueriesApplicationTest.java index 0fb975b0713..43959e48634 100644 --- a/tests/org.eclipse.e4.emf.xpath.test/src/org/eclipse/e4/emf/xpath/test/ExampleQueriesApplicationTest.java +++ b/tests/org.eclipse.e4.emf.xpath.test/src/org/eclipse/e4/emf/xpath/test/ExampleQueriesApplicationTest.java @@ -16,7 +16,11 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import java.util.Collection; +import java.util.List; + import org.eclipse.e4.emf.xpath.EcoreXPathContextFactory; +import org.eclipse.e4.emf.xpath.JavaXPathFactory; import org.eclipse.e4.emf.xpath.XPathContext; import org.eclipse.e4.emf.xpath.XPathContextFactory; import org.eclipse.e4.ui.internal.workbench.E4XMIResourceFactory; @@ -36,9 +40,22 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; +@RunWith(Parameterized.class) public class ExampleQueriesApplicationTest { + @Parameters + public static Collection data() { + return List.of(EcoreXPathContextFactory.newInstance(), JavaXPathFactory.newInstance()); + } + + @Parameter + public XPathContextFactory xpathContextFactory; + private ResourceSet resourceSet; private XPathContext xpathContext; private Resource resource; @@ -62,8 +79,7 @@ public void setUp() { URI uri = URI.createPlatformPluginURI("/org.eclipse.e4.emf.xpath.test/model/Application.e4xmi", true); resource = resourceSet.getResource(uri, true); - XPathContextFactory f = EcoreXPathContextFactory.newInstance(); - xpathContext = f.newContext(resource.getContents().get(0)); + xpathContext = xpathContextFactory.newContext(resource.getContents().get(0)); } @After