aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordanielhanrahan <daniel.hanrahan@est.tech>2024-11-27 15:38:41 +0000
committerdanielhanrahan <daniel.hanrahan@est.tech>2024-12-02 13:30:15 +0000
commitd262e1c3f4671673a02ea402366a8c9b93fe4e53 (patch)
tree8805f57e86733f5766e02eed6bb218f54f000282
parent7cd33c3f6784b5df58cb242847719c4faec7eca3 (diff)
[Cps Path Parser] Introduce Attribute axis
Add grammar and tests for attribute-axis to match cps paths like: //books/@title which should return the titles of all books (a subsequent patch will implement the logic). The syntax is compatible with XPath standard. Issue-ID: CPS-2416 Signed-off-by: danielhanrahan <daniel.hanrahan@est.tech> Change-Id: I25164b23670147c504f0f0f6c0cc8ff15997f2a3
-rw-r--r--cps-path-parser/src/main/antlr4/org/onap/cps/cpspath/parser/antlr4/CpsPath.g44
-rw-r--r--cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathBuilder.java7
-rw-r--r--cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathQuery.java10
-rw-r--r--cps-path-parser/src/test/groovy/org/onap/cps/cpspath/parser/CpsPathQuerySpec.groovy18
4 files changed, 38 insertions, 1 deletions
diff --git a/cps-path-parser/src/main/antlr4/org/onap/cps/cpspath/parser/antlr4/CpsPath.g4 b/cps-path-parser/src/main/antlr4/org/onap/cps/cpspath/parser/antlr4/CpsPath.g4
index 74b99feb33..bb6bfc3942 100644
--- a/cps-path-parser/src/main/antlr4/org/onap/cps/cpspath/parser/antlr4/CpsPath.g4
+++ b/cps-path-parser/src/main/antlr4/org/onap/cps/cpspath/parser/antlr4/CpsPath.g4
@@ -27,10 +27,12 @@
grammar CpsPath ;
-cpsPath : ( prefix | descendant ) multipleLeafConditions? textFunctionCondition? containsFunctionCondition? ancestorAxis? EOF ;
+cpsPath : ( prefix | descendant ) multipleLeafConditions? textFunctionCondition? containsFunctionCondition? ancestorAxis? attributeAxis? EOF ;
slash : SLASH ;
+attributeAxis : SLASH AT leafName ;
+
ancestorAxis : KW_ANCESTOR_AXIS_PREFIX ancestorPath ;
ancestorPath : yangElement ( slash yangElement)* ;
diff --git a/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathBuilder.java b/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathBuilder.java
index b67d70847c..d0deb7defc 100644
--- a/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathBuilder.java
+++ b/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathBuilder.java
@@ -131,6 +131,13 @@ public class CpsPathBuilder extends CpsPathBaseListener {
}
@Override
+ public void exitAttributeAxis(final CpsPathParser.AttributeAxisContext ctx) {
+ final String attributeName = ctx.leafName().getText();
+ normalizedXpathBuilder.append("/@").append(attributeName);
+ cpsPathQuery.setAttributeAxisAttributeName(attributeName);
+ }
+
+ @Override
public void exitTextFunctionCondition(final TextFunctionConditionContext ctx) {
cpsPathQuery.setTextFunctionConditionLeafName(ctx.leafName().getText());
cpsPathQuery.setTextFunctionConditionValue(unwrapQuotedString(ctx.StringLiteral().getText()));
diff --git a/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathQuery.java b/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathQuery.java
index 03602b64f6..3612ec57fb 100644
--- a/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathQuery.java
+++ b/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathQuery.java
@@ -40,6 +40,7 @@ public class CpsPathQuery {
private String descendantName;
private List<LeafCondition> leafConditions;
private String ancestorSchemaNodeIdentifier = "";
+ private String attributeAxisAttributeName = "";
private String textFunctionConditionLeafName;
private String textFunctionConditionValue;
private List<String> booleanOperators;
@@ -66,6 +67,15 @@ public class CpsPathQuery {
}
/**
+ * Has attribute axis been included in cpsPath.
+ *
+ * @return boolean value.
+ */
+ public boolean hasAttributeAxis() {
+ return !(attributeAxisAttributeName.isEmpty());
+ }
+
+ /**
* Have leaf value conditions been included in cpsPath.
*
* @return boolean value.
diff --git a/cps-path-parser/src/test/groovy/org/onap/cps/cpspath/parser/CpsPathQuerySpec.groovy b/cps-path-parser/src/test/groovy/org/onap/cps/cpspath/parser/CpsPathQuerySpec.groovy
index a1bf28977a..b551080b40 100644
--- a/cps-path-parser/src/test/groovy/org/onap/cps/cpspath/parser/CpsPathQuerySpec.groovy
+++ b/cps-path-parser/src/test/groovy/org/onap/cps/cpspath/parser/CpsPathQuerySpec.groovy
@@ -34,6 +34,7 @@ class CpsPathQuerySpec extends Specification {
then: 'the query has the correct default properties'
assert result.cpsPathPrefixType == ABSOLUTE
assert result.hasAncestorAxis() == false
+ assert result.hasAttributeAxis() == false
assert result.hasLeafConditions() == false
assert result.hasTextFunctionCondition() == false
assert result.hasContainsFunctionCondition() == false
@@ -107,6 +108,7 @@ class CpsPathQuerySpec extends Specification {
'parent & child with multiple OR operators' | '/parent/child[@key1=1 or @key2="abc" or @key="xyz"]/child2' || "/parent/child[@key1='1' or @key2='abc' or @key='xyz']/child2"
'parent & child with multiple AND/OR combination' | '/parent/child[@key1=1 and @key2="abc" or @key="xyz"]/child2' || "/parent/child[@key1='1' and @key2='abc' or @key='xyz']/child2"
'parent & child with multiple OR/AND combination' | '/parent/child[@key1=1 or @key2="abc" and @key="xyz"]/child2' || "/parent/child[@key1='1' or @key2='abc' and @key='xyz']/child2"
+ 'attribute axis' | '/parent/child/@key' || '/parent/child/@key'
}
def 'Parse xpath to form the Normalized xpath containing #scenario.'() {
@@ -254,4 +256,20 @@ class CpsPathQuerySpec extends Specification {
'/test[@name2="value2" and @name1="value1"]' || 'name2' | 'name1'
}
+ def 'Cps Path using attribute axis.'() {
+ when: 'the cps path is parsed'
+ def result = CpsPathQuery.createFrom(cpsPath)
+ then: 'the query has the correct properties for attribute axis'
+ assert result.hasAttributeAxis() == expectAttributeAxis
+ assert result.attributeAxisAttributeName == expectedAttributeName
+ where: 'the following data is used'
+ cpsPath || expectAttributeAxis | expectedAttributeName
+ '/test' || false | ''
+ '/test/@id' || true | 'id'
+ '/test[@id="id"]' || false | ''
+ '/test[@id="id"]/@id' || true | 'id'
+ '//test/ancestor::root' || false | ''
+ '//test/ancestor::root/@xyz' || true | 'xyz'
+ }
+
}