summaryrefslogtreecommitdiffstats
path: root/cps-path-parser/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'cps-path-parser/src/main')
-rw-r--r--cps-path-parser/src/main/antlr4/org/onap/cps/cpspath/parser/antlr4/CpsPath.g46
-rw-r--r--cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathBuilder.java81
-rw-r--r--cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathQuery.java25
-rw-r--r--cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathUtil.java81
-rwxr-xr-xcps-path-parser/src/main/java/org/onap/cps/cpspath/parser/PathParsingException.java55
5 files changed, 218 insertions, 30 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 cefeac4387..40ad410a0d 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
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021 Nordix Foundation
+ * Copyright (C) 2021-2022 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +20,7 @@
grammar CpsPath ;
-cpsPath : ( prefix | descendant | incorrectPrefix ) multipleLeafConditions? textFunctionCondition? ancestorAxis? ;
+cpsPath : ( prefix | descendant | incorrectPrefix ) multipleLeafConditions? textFunctionCondition? ancestorAxis? invalidPostFix?;
ancestorAxis : SLASH KW_ANCESTOR COLONCOLON ancestorPath ;
@@ -46,6 +46,8 @@ leafCondition : AT leafName EQ ( IntegerLiteral | StringLiteral) ;
leafName : QName ;
+invalidPostFix : (AT | CB | COLONCOLON | EQ ).+ ;
+
/*
* Lexer Rules
* Most of the lexer rules below are inspired by
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 ebf6fd3c91..21f5173a98 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
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021 Nordix Foundation
+ * Copyright (C) 2021-2022 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@ import static org.onap.cps.cpspath.parser.CpsPathPrefixType.DESCENDANT;
import java.util.HashMap;
import java.util.Map;
import org.onap.cps.cpspath.parser.antlr4.CpsPathBaseListener;
+import org.onap.cps.cpspath.parser.antlr4.CpsPathParser;
import org.onap.cps.cpspath.parser.antlr4.CpsPathParser.AncestorAxisContext;
import org.onap.cps.cpspath.parser.antlr4.CpsPathParser.DescendantContext;
import org.onap.cps.cpspath.parser.antlr4.CpsPathParser.IncorrectPrefixContext;
@@ -35,18 +36,33 @@ import org.onap.cps.cpspath.parser.antlr4.CpsPathParser.TextFunctionConditionCon
public class CpsPathBuilder extends CpsPathBaseListener {
+ private static final String OPEN_BRACKET = "[";
+
+ private static final String CLOSE_BRACKET = "]";
+
final CpsPathQuery cpsPathQuery = new CpsPathQuery();
final Map<String, Object> leavesData = new HashMap<>();
+ final StringBuilder normalizedXpathBuilder = new StringBuilder();
+
+ final StringBuilder normalizedAncestorPathBuilder = new StringBuilder();
+
+ boolean processingAncestorAxis = false;
+
+ @Override
+ public void exitInvalidPostFix(final CpsPathParser.InvalidPostFixContext ctx) {
+ throw new PathParsingException(ctx.getText());
+ }
+
@Override
public void exitPrefix(final PrefixContext ctx) {
- cpsPathQuery.setXpathPrefix(ctx.getText());
+ cpsPathQuery.setXpathPrefix(normalizedXpathBuilder.toString());
}
@Override
public void exitIncorrectPrefix(final IncorrectPrefixContext ctx) {
- throw new IllegalStateException("CPS path can only start with one or two slashes (/)");
+ throw new PathParsingException("CPS path can only start with one or two slashes (/)");
}
@Override
@@ -56,32 +72,49 @@ public class CpsPathBuilder extends CpsPathBaseListener {
comparisonValue = Integer.valueOf(ctx.IntegerLiteral().getText());
}
if (ctx.StringLiteral() != null) {
+ final boolean wasWrappedInDoubleQuote = ctx.StringLiteral().getText().startsWith("\"");
comparisonValue = stripFirstAndLastCharacter(ctx.StringLiteral().getText());
+ if (wasWrappedInDoubleQuote) {
+ comparisonValue = String.valueOf(comparisonValue).replace("'", "\\'");
+ }
} else if (comparisonValue == null) {
- throw new IllegalStateException("Unsupported comparison value encountered in expression" + ctx.getText());
+ throw new PathParsingException("Unsupported comparison value encountered in expression" + ctx.getText());
}
leavesData.put(ctx.leafName().getText(), comparisonValue);
+ appendCondition(normalizedXpathBuilder, ctx.leafName().getText(), comparisonValue);
+ if (processingAncestorAxis) {
+ appendCondition(normalizedAncestorPathBuilder, ctx.leafName().getText(), comparisonValue);
+ }
}
@Override
public void exitDescendant(final DescendantContext ctx) {
cpsPathQuery.setCpsPathPrefixType(DESCENDANT);
- cpsPathQuery.setDescendantName(ctx.getText().substring(2));
+ cpsPathQuery.setDescendantName(normalizedXpathBuilder.substring(1));
+ normalizedXpathBuilder.insert(0, "/");
}
@Override
public void enterMultipleLeafConditions(final MultipleLeafConditionsContext ctx) {
+ normalizedXpathBuilder.append(OPEN_BRACKET);
leavesData.clear();
}
@Override
public void exitMultipleLeafConditions(final MultipleLeafConditionsContext ctx) {
+ normalizedXpathBuilder.append(CLOSE_BRACKET);
cpsPathQuery.setLeavesData(leavesData);
}
@Override
+ public void enterAncestorAxis(final AncestorAxisContext ctx) {
+ processingAncestorAxis = true;
+ }
+
+ @Override
public void exitAncestorAxis(final AncestorAxisContext ctx) {
- cpsPathQuery.setAncestorSchemaNodeIdentifier(ctx.ancestorPath().getText());
+ cpsPathQuery.setAncestorSchemaNodeIdentifier(normalizedAncestorPathBuilder.substring(1));
+ processingAncestorAxis = false;
}
@Override
@@ -90,7 +123,24 @@ public class CpsPathBuilder extends CpsPathBaseListener {
cpsPathQuery.setTextFunctionConditionValue(stripFirstAndLastCharacter(ctx.StringLiteral().getText()));
}
+ @Override
+ public void enterListElementRef(final CpsPathParser.ListElementRefContext ctx) {
+ normalizedXpathBuilder.append(OPEN_BRACKET);
+ if (processingAncestorAxis) {
+ normalizedAncestorPathBuilder.append(OPEN_BRACKET);
+ }
+ }
+
+ @Override
+ public void exitListElementRef(final CpsPathParser.ListElementRefContext ctx) {
+ normalizedXpathBuilder.append(CLOSE_BRACKET);
+ if (processingAncestorAxis) {
+ normalizedAncestorPathBuilder.append(CLOSE_BRACKET);
+ }
+ }
+
CpsPathQuery build() {
+ cpsPathQuery.setNormalizedXpath(normalizedXpathBuilder.toString());
return cpsPathQuery;
}
@@ -98,4 +148,23 @@ public class CpsPathBuilder extends CpsPathBaseListener {
return wrappedString.substring(1, wrappedString.length() - 1);
}
+ @Override
+ public void exitContainerName(final CpsPathParser.ContainerNameContext ctx) {
+ normalizedXpathBuilder.append("/")
+ .append(ctx.getText());
+ if (processingAncestorAxis) {
+ normalizedAncestorPathBuilder.append("/").append(ctx.getText());
+ }
+ }
+
+ private void appendCondition(final StringBuilder currentNormalizedPathBuilder, final String name,
+ final Object value) {
+ final char lastCharacter = currentNormalizedPathBuilder.charAt(currentNormalizedPathBuilder.length() - 1);
+ currentNormalizedPathBuilder.append(lastCharacter == '[' ? "" : " and ")
+ .append("@")
+ .append(name)
+ .append("='")
+ .append(value)
+ .append("'");
+ }
}
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 de7adf2b71..53490f3a2d 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
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021 Nordix Foundation
+ * Copyright (C) 2021-2022 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,19 +26,13 @@ import java.util.Map;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
-import org.antlr.v4.runtime.BaseErrorListener;
-import org.antlr.v4.runtime.CharStreams;
-import org.antlr.v4.runtime.CommonTokenStream;
-import org.antlr.v4.runtime.RecognitionException;
-import org.antlr.v4.runtime.Recognizer;
-import org.onap.cps.cpspath.parser.antlr4.CpsPathLexer;
-import org.onap.cps.cpspath.parser.antlr4.CpsPathParser;
@Getter
@Setter(AccessLevel.PACKAGE)
public class CpsPathQuery {
private String xpathPrefix;
+ private String normalizedXpath;
private CpsPathPrefixType cpsPathPrefixType = ABSOLUTE;
private String descendantName;
private Map<String, Object> leavesData;
@@ -53,20 +47,7 @@ public class CpsPathQuery {
* @return a CpsPathQuery object.
*/
public static CpsPathQuery createFrom(final String cpsPathSource) {
- final var inputStream = CharStreams.fromString(cpsPathSource);
- final var cpsPathLexer = new CpsPathLexer(inputStream);
- final var cpsPathParser = new CpsPathParser(new CommonTokenStream(cpsPathLexer));
- cpsPathParser.addErrorListener(new BaseErrorListener() {
- @Override
- public void syntaxError(final Recognizer<?, ?> recognizer, final Object offendingSymbol, final int line,
- final int charPositionInLine, final String msg, final RecognitionException e) {
- throw new IllegalStateException("failed to parse at line " + line + " due to " + msg, e);
- }
- });
- final var cpsPathBuilder = new CpsPathBuilder();
- cpsPathParser.addParseListener(cpsPathBuilder);
- cpsPathParser.cpsPath();
- return cpsPathBuilder.build();
+ return CpsPathUtil.getCpsPathQuery(cpsPathSource);
}
/**
diff --git a/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathUtil.java b/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathUtil.java
new file mode 100644
index 0000000000..97d7d1d760
--- /dev/null
+++ b/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathUtil.java
@@ -0,0 +1,81 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.cpspath.parser;
+
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import org.antlr.v4.runtime.BaseErrorListener;
+import org.antlr.v4.runtime.CharStream;
+import org.antlr.v4.runtime.CharStreams;
+import org.antlr.v4.runtime.CommonTokenStream;
+import org.antlr.v4.runtime.RecognitionException;
+import org.antlr.v4.runtime.Recognizer;
+import org.onap.cps.cpspath.parser.antlr4.CpsPathLexer;
+import org.onap.cps.cpspath.parser.antlr4.CpsPathParser;
+
+@Getter
+@Setter
+@NoArgsConstructor(access = AccessLevel.PACKAGE)
+public class CpsPathUtil {
+
+ /**
+ * Returns a normalized xpath path query.
+ *
+ * @param xpathSource xpath
+ * @return a normalized xpath String.
+ */
+ public static String getNormalizedXpath(final String xpathSource) {
+ final CpsPathBuilder cpsPathBuilder = getCpsPathBuilder(xpathSource);
+ return cpsPathBuilder.build().getNormalizedXpath();
+ }
+
+ /**
+ * Returns a cps path query.
+ *
+ * @param cpsPathSource cps path
+ * @return a CpsPathQuery object.
+ */
+
+ public static CpsPathQuery getCpsPathQuery(final String cpsPathSource) {
+ final CpsPathBuilder cpsPathBuilder = getCpsPathBuilder(cpsPathSource);
+ return cpsPathBuilder.build();
+ }
+
+ private static CpsPathBuilder getCpsPathBuilder(final String cpsPathSource) {
+ final CharStream inputStream = CharStreams.fromString(cpsPathSource);
+ final CpsPathLexer cpsPathLexer = new CpsPathLexer(inputStream);
+ final CpsPathParser cpsPathParser = new CpsPathParser(new CommonTokenStream(cpsPathLexer));
+ cpsPathParser.addErrorListener(new BaseErrorListener() {
+ @Override
+ public void syntaxError(final Recognizer<?, ?> recognizer, final Object offendingSymbol, final int line,
+ final int charPositionInLine, final String msg, final RecognitionException e) {
+ throw new PathParsingException("failed to parse at line " + line + " due to " + msg,
+ e == null ? "" : e.getMessage());
+ }
+ });
+ final CpsPathBuilder cpsPathBuilder = new CpsPathBuilder();
+ cpsPathParser.addParseListener(cpsPathBuilder);
+ cpsPathParser.cpsPath();
+ return cpsPathBuilder;
+ }
+}
diff --git a/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/PathParsingException.java b/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/PathParsingException.java
new file mode 100755
index 0000000000..4a67167c96
--- /dev/null
+++ b/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/PathParsingException.java
@@ -0,0 +1,55 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.cpspath.parser;
+
+import lombok.Getter;
+
+/**
+ * XPath Parsing Exception.
+ */
+public class PathParsingException extends RuntimeException {
+
+ private static final long serialVersionUID = 7072864354925271894L;
+
+ @Getter
+ final String details;
+
+ /**
+ * Constructor.
+ *
+ * @param details the error details
+ */
+ public PathParsingException(final String details) {
+ super("Error while parsing xpath expression");
+ this.details = details;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param message the error message
+ * @param details the error details
+ */
+ public PathParsingException(final String message, final String details) {
+ super(message);
+ this.details = details;
+ }
+}