From e1239f8480fdcdfedd0929288f8be56b5afdaedd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Pablo=20Santos=20Rodr=C3=ADguez?= Date: Wed, 12 Jul 2017 09:08:10 +0200 Subject: [PATCH] fixes #7: JSONPath params are always converted to String --- .../plugins/gwt/VariablesResolver.java | 90 +++++++++++-- .../plugins/gwt/VariablesResolverTest.java | 118 ++++++++++++++++++ 2 files changed, 200 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/jenkinsci/plugins/gwt/VariablesResolver.java b/src/main/java/org/jenkinsci/plugins/gwt/VariablesResolver.java index e9c2199..bd3d7a5 100644 --- a/src/main/java/org/jenkinsci/plugins/gwt/VariablesResolver.java +++ b/src/main/java/org/jenkinsci/plugins/gwt/VariablesResolver.java @@ -10,15 +10,19 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.logging.Logger; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathFactory; import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import com.google.common.base.Optional; @@ -55,20 +59,90 @@ private void addPostContentParameters(Map map) { if (genericVariables != null) { for (GenericVariable gv : genericVariables) { Object resolved = resolve(gv); - - if (resolved instanceof List) { - int i = 0; - for (Object o : (List) resolved) { - map.put(gv.getKey() + "_" + i, filter(o.toString(), gv.getRegexpFilter())); - i++; + if (resolved instanceof NodeList) { + NodeList nodeList = (NodeList) resolved; + if (nodeList.getLength() > 0) { + for (int i = 0; i < nodeList.getLength(); i++) { + flattenNode( + map, + gv.getKey(), + gv.getRegexpFilter(), + nodeList.item(i), + i, + nodeList.getLength() == 1 ? true : false); + } + } else { + map.put(gv.getKey(), ""); } } else { - map.put(gv.getKey(), filter(resolved.toString(), gv.getRegexpFilter())); + flatten(map, gv.getKey(), gv.getRegexpFilter(), resolved); } } } } + void flatten(Map map, String key, String regexFilter, Object resolved) { + if (resolved instanceof List) { + int i = 0; + for (Object o : (List) resolved) { + flatten(map, key + "_" + i, regexFilter, o); + i++; + } + } else if (resolved instanceof Map) { + for (Entry entry : ((Map) resolved).entrySet()) { + flatten(map, key + "_" + entry.getKey(), regexFilter, entry.getValue()); + } + } else if (resolved != null) { + map.put(key, filter(resolved.toString(), regexFilter)); + } + } + + void flattenNode( + Map map, + String key, + String regexFilter, + Node node, + int level, + boolean fromRootLevel) { + if (isLeafNode(node)) { + flatten(map, key, regexFilter, node.getTextContent()); + } else { + for (int i = 0; i < node.getChildNodes().getLength(); i++) { + Node childNode = node.getChildNodes().item(i); + if (isLeafNode(childNode)) { + flatten( + map, + expandKey(key, level, fromRootLevel) + "_" + childNode.getNodeName(), + regexFilter, + childNode.getTextContent()); + } else { + flattenNode( + map, + expandKey(key, level, fromRootLevel) + "_" + childNode.getNodeName(), + regexFilter, + childNode, + i / 2, //leafnode and text inside leafnode are 2 nodes, so /2 to keep counter in line + false); + } + } + } + } + + private String expandKey(String key, int level, boolean fromRootLevel) { + if (fromRootLevel) { + return key; + } else { + return key + "_" + level; + } + } + + private boolean isLeafNode(Node node) { + return node != null + && node.getNodeType() == Node.ELEMENT_NODE + && node.getChildNodes().getLength() == 1 + && node.getFirstChild().getNodeType() == Node.TEXT_NODE; + } + private void addRequestParameters(Map map) { if (parameterMap != null) { for (String requestParamName : parameterMap.keySet()) { @@ -136,7 +210,7 @@ private Object resolve(GenericVariable gv) { XPathFactory xPathfactory = XPathFactory.newInstance(); XPath xpath = xPathfactory.newXPath(); XPathExpression expr = xpath.compile(gv.getValue()); - return expr.evaluate(doc); + return expr.evaluate(doc, XPathConstants.NODESET); } else { throw new IllegalStateException("Not recognizing " + gv.getExpressionType()); } diff --git a/src/test/java/org/jenkinsci/plugins/gwt/VariablesResolverTest.java b/src/test/java/org/jenkinsci/plugins/gwt/VariablesResolverTest.java index 52c04ff..362439b 100644 --- a/src/test/java/org/jenkinsci/plugins/gwt/VariablesResolverTest.java +++ b/src/test/java/org/jenkinsci/plugins/gwt/VariablesResolverTest.java @@ -143,6 +143,44 @@ public void testJSONPathGetTwoVariables() throws Exception { .containsEntry("project_id", "1"); } + @Test + public void testJSONPathGetNodeVariable() throws Exception { + String resourceName = "gital-mergerequest-comment.json"; + String postContent = getContent(resourceName); + + String regexpFilter = ""; + List genericVariables = + newArrayList( // + new GenericVariable("user", "$.user", JSONPath, regexpFilter)); + Map parameterMap = new HashMap<>(); + List genericRequestVariables = new ArrayList<>(); + Map variables = + new VariablesResolver(parameterMap, postContent, genericVariables, genericRequestVariables) + .getVariables(); + + assertThat(variables) // + .containsEntry("user_name", "Administrator"); + } + + @Test + public void testJSONPathGetPayloadVariable() throws Exception { + String resourceName = "gital-mergerequest-comment.json"; + String postContent = getContent(resourceName); + + String regexpFilter = ""; + List genericVariables = + newArrayList( // + new GenericVariable("payload", "$", JSONPath, regexpFilter)); + Map parameterMap = new HashMap<>(); + List genericRequestVariables = new ArrayList<>(); + Map variables = + new VariablesResolver(parameterMap, postContent, genericVariables, genericRequestVariables) + .getVariables(); + + assertThat(variables) // + .containsEntry("payload_user_name", "Administrator"); + } + @Test public void testXPathGetOneVariable() throws Exception { String resourceName = "example.xml"; @@ -162,6 +200,86 @@ public void testXPathGetOneVariable() throws Exception { .containsEntry("book", "Harry Potter"); } + @Test + public void testXPathGetOneNode() throws Exception { + String resourceName = "example.xml"; + String postContent = getContent(resourceName); + + String regexpFilter = ""; + List genericVariables = + newArrayList( // + new GenericVariable("book", "/bookstore/book[1]", XPath, regexpFilter)); + Map parameterMap = new HashMap<>(); + List genericRequestVariables = new ArrayList<>(); + Map variables = + new VariablesResolver(parameterMap, postContent, genericVariables, genericRequestVariables) + .getVariables(); + + assertThat(variables) // + .containsEntry("book_title", "Harry Potter"); + } + + @Test + public void testXPathGetNodes() throws Exception { + String resourceName = "example.xml"; + String postContent = getContent(resourceName); + + String regexpFilter = ""; + List genericVariables = + newArrayList( // + new GenericVariable("book", "/bookstore/book[*]", XPath, regexpFilter)); + Map parameterMap = new HashMap<>(); + List genericRequestVariables = new ArrayList<>(); + Map variables = + new VariablesResolver(parameterMap, postContent, genericVariables, genericRequestVariables) + .getVariables(); + + assertThat(variables) // + .containsEntry("book_0_title", "Harry Potter") + .containsEntry("book_1_title", "Learning XML"); + } + + @Test + public void testXPathGetPayload() throws Exception { + String resourceName = "example.xml"; + String postContent = getContent(resourceName); + + String regexpFilter = ""; + List genericVariables = + newArrayList( // + new GenericVariable("payload", "/*", XPath, regexpFilter)); + Map parameterMap = new HashMap<>(); + List genericRequestVariables = new ArrayList<>(); + Map variables = + new VariablesResolver(parameterMap, postContent, genericVariables, genericRequestVariables) + .getVariables(); + + assertThat(variables) // + .containsEntry("payload_book_0_price", "29.99") + .containsEntry("payload_book_0_title", "Harry Potter") + .containsEntry("payload_book_1_title", "Learning XML"); + } + + @Test + public void testXPathGetNodeVariable() throws Exception { + String resourceName = "example.xml"; + String postContent = getContent(resourceName); + + String regexpFilter = ""; + List genericVariables = + newArrayList( // + new GenericVariable("book", "/bookstore/book[1]", XPath, regexpFilter)); + Map parameterMap = new HashMap<>(); + List genericRequestVariables = new ArrayList<>(); + Map variables = + new VariablesResolver(parameterMap, postContent, genericVariables, genericRequestVariables) + .getVariables(); + + assertThat(variables) // + .containsEntry("book_price", "29.99") + .containsEntry("book_title", "Harry Potter"); + } + @Test public void testHPathGetTwoVariable() throws Exception { String resourceName = "example.xml";