diff options
Diffstat (limited to 'cps-path-parser/src/main')
5 files changed, 55 insertions, 155 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 c88a822654..3aef120fed 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-2022 Nordix Foundation + * Copyright (C) 2021-2023 Nordix Foundation * Modifications Copyright (C) 2023 TechMahindra Ltd * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,6 +19,12 @@ * ============LICENSE_END========================================================= */ +/* + * Parser Rules + * Some of the parser rules below are inspired by + * https://github.com/antlr/grammars-v4/blob/master/xpath/xpath31/XPath31Parser.g4 + */ + grammar CpsPath ; cpsPath : ( prefix | descendant | incorrectPrefix ) multipleLeafConditions? textFunctionCondition? containsFunctionCondition? ancestorAxis? invalidPostFix?; @@ -60,7 +66,7 @@ invalidPostFix : (AT | CB | COLONCOLON | comparativeOperators ).+ ; /* * Lexer Rules * Most of the lexer rules below are inspired by - * https://raw.githubusercontent.com/antlr/grammars-v4/master/xpath/xpath31/XPath31.g4 + * https://github.com/antlr/grammars-v4/blob/master/xpath/xpath31/XPath31Lexer.g4 */ AT : '@' ; @@ -89,9 +95,9 @@ IntegerLiteral : FragDigits ; // Add below type definitions for leafvalue comparision in https://jira.onap.org/browse/CPS-440 DecimalLiteral : ('.' FragDigits) | (FragDigits '.' [0-9]*) ; DoubleLiteral : (('.' FragDigits) | (FragDigits ('.' [0-9]*)?)) [eE] [+-]? FragDigits ; -StringLiteral : ('"' (FragEscapeQuot | ~[^"])*? '"') | ('\'' (FragEscapeApos | ~['])*? '\'') ; +StringLiteral : '"' (~["] | FragEscapeQuot)* '"' | '\'' (~['] | FragEscapeApos)* '\'' ; fragment FragEscapeQuot : '""' ; -fragment FragEscapeApos : '\'' ; +fragment FragEscapeApos : '\'\''; fragment FragDigits : [0-9]+ ; QName : FragQName ; diff --git a/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathBooleanOperatorType.java b/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathBooleanOperatorType.java deleted file mode 100644 index b2f1dddb19..0000000000 --- a/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathBooleanOperatorType.java +++ /dev/null @@ -1,51 +0,0 @@ -/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 2023 TechMahindra Ltd
- * ================================================================================
- * 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;
-
-public enum CpsPathBooleanOperatorType {
- AND("and"),
- OR("or");
-
- private final String operatorValue;
-
- CpsPathBooleanOperatorType(final String operatorValue) {
- this.operatorValue = operatorValue;
- }
-
- public String getValues() {
- return this.operatorValue;
- }
-
- /**
- * Finds the value of the given enumeration.
- *
- * @param operatorValue value of the enum
- * @return a booleanOperatorType
- */
- public static CpsPathBooleanOperatorType fromString(final String operatorValue) {
- for (final CpsPathBooleanOperatorType booleanOperatorType : CpsPathBooleanOperatorType.values()) {
- if (booleanOperatorType.operatorValue.equalsIgnoreCase(operatorValue)) {
- return booleanOperatorType;
- }
- }
- return null;
- }
-}
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 5c47127375..de261e64b3 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-2022 Nordix Foundation + * Copyright (C) 2021-2023 Nordix Foundation * Modifications Copyright (C) 2023 TechMahindra Ltd * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,9 +24,7 @@ package org.onap.cps.cpspath.parser; import static org.onap.cps.cpspath.parser.CpsPathPrefixType.DESCENDANT; import java.util.ArrayList; -import java.util.LinkedHashMap; import java.util.List; -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; @@ -43,21 +41,21 @@ public class CpsPathBuilder extends CpsPathBaseListener { private static final String CLOSE_BRACKET = "]"; - final CpsPathQuery cpsPathQuery = new CpsPathQuery(); + private final CpsPathQuery cpsPathQuery = new CpsPathQuery(); - final Map<String, Object> leavesData = new LinkedHashMap<>(); + private final List<CpsPathQuery.DataLeaf> leavesData = new ArrayList<>(); - final StringBuilder normalizedXpathBuilder = new StringBuilder(); + private final StringBuilder normalizedXpathBuilder = new StringBuilder(); - final StringBuilder normalizedAncestorPathBuilder = new StringBuilder(); + private final StringBuilder normalizedAncestorPathBuilder = new StringBuilder(); - boolean processingAncestorAxis = false; + private boolean processingAncestorAxis = false; - private List<String> containerNames = new ArrayList<>(); + private final List<String> containerNames = new ArrayList<>(); - final List<String> booleanOperators = new ArrayList<>(); + private final List<String> booleanOperators = new ArrayList<>(); - final List<String> comparativeOperators = new ArrayList<>(); + private final List<String> comparativeOperators = new ArrayList<>(); @Override public void exitInvalidPostFix(final CpsPathParser.InvalidPostFixContext ctx) { @@ -81,34 +79,25 @@ public class CpsPathBuilder extends CpsPathBaseListener { @Override public void exitLeafCondition(final LeafConditionContext ctx) { - Object comparisonValue; + final Object comparisonValue; if (ctx.IntegerLiteral() != null) { comparisonValue = Integer.valueOf(ctx.IntegerLiteral().getText()); } else if (ctx.StringLiteral() != null) { - final boolean wasWrappedInDoubleQuote = ctx.StringLiteral().getText().startsWith("\""); - comparisonValue = stripFirstAndLastCharacter(ctx.StringLiteral().getText()); - if (wasWrappedInDoubleQuote) { - comparisonValue = String.valueOf(comparisonValue).replace("'", "\\'"); - } + comparisonValue = unwrapQuotedString(ctx.StringLiteral().getText()); } else { - throw new PathParsingException( - "Unsupported comparison value encountered in expression" + ctx.getText()); + throw new PathParsingException("Unsupported comparison value encountered in expression" + ctx.getText()); } leafContext(ctx.leafName(), comparisonValue); } @Override public void exitBooleanOperators(final CpsPathParser.BooleanOperatorsContext ctx) { - final CpsPathBooleanOperatorType cpsPathBooleanOperatorType = CpsPathBooleanOperatorType.fromString( - ctx.getText()); - booleanOperators.add(cpsPathBooleanOperatorType.getValues()); + booleanOperators.add(ctx.getText()); } @Override public void exitComparativeOperators(final CpsPathParser.ComparativeOperatorsContext ctx) { - final CpsPathComparativeOperator cpsPathComparativeOperator = CpsPathComparativeOperator.fromString( - ctx.getText()); - comparativeOperators.add(cpsPathComparativeOperator.getLabel()); + comparativeOperators.add(ctx.getText()); } @Override @@ -122,6 +111,8 @@ public class CpsPathBuilder extends CpsPathBaseListener { public void enterMultipleLeafConditions(final MultipleLeafConditionsContext ctx) { normalizedXpathBuilder.append(OPEN_BRACKET); leavesData.clear(); + booleanOperators.clear(); + comparativeOperators.clear(); } @Override @@ -144,13 +135,13 @@ public class CpsPathBuilder extends CpsPathBaseListener { @Override public void exitTextFunctionCondition(final TextFunctionConditionContext ctx) { cpsPathQuery.setTextFunctionConditionLeafName(ctx.leafName().getText()); - cpsPathQuery.setTextFunctionConditionValue(stripFirstAndLastCharacter(ctx.StringLiteral().getText())); + cpsPathQuery.setTextFunctionConditionValue(unwrapQuotedString(ctx.StringLiteral().getText())); } @Override public void exitContainsFunctionCondition(final CpsPathParser.ContainsFunctionConditionContext ctx) { cpsPathQuery.setContainsFunctionConditionLeafName(ctx.leafName().getText()); - cpsPathQuery.setContainsFunctionConditionValue(stripFirstAndLastCharacter(ctx.StringLiteral().getText())); + cpsPathQuery.setContainsFunctionConditionValue(unwrapQuotedString(ctx.StringLiteral().getText())); } @Override @@ -177,10 +168,6 @@ public class CpsPathBuilder extends CpsPathBaseListener { return cpsPathQuery; } - private static String stripFirstAndLastCharacter(final String wrappedString) { - return wrappedString.substring(1, wrappedString.length() - 1); - } - @Override public void exitContainerName(final CpsPathParser.ContainerNameContext ctx) { final String containerName = ctx.getText(); @@ -193,7 +180,7 @@ public class CpsPathBuilder extends CpsPathBaseListener { } private void leafContext(final CpsPathParser.LeafNameContext ctx, final Object comparisonValue) { - leavesData.put(ctx.getText(), comparisonValue); + leavesData.add(new CpsPathQuery.DataLeaf(ctx.getText(), comparisonValue)); appendCondition(normalizedXpathBuilder, ctx.getText(), comparisonValue); if (processingAncestorAxis) { appendCondition(normalizedAncestorPathBuilder, ctx.getText(), comparisonValue); @@ -211,11 +198,25 @@ public class CpsPathBuilder extends CpsPathBaseListener { .append(name) .append(getLastElement(comparativeOperators)) .append("'") - .append(value) + .append(value.toString().replace("'", "''")) .append("'"); } - private String getLastElement(final List<String> listOfStrings) { + private static String getLastElement(final List<String> listOfStrings) { return listOfStrings.get(listOfStrings.size() - 1); } + + private static String unwrapQuotedString(final String wrappedString) { + final boolean wasWrappedInSingleQuote = wrappedString.startsWith("'"); + final String value = stripFirstAndLastCharacter(wrappedString); + if (wasWrappedInSingleQuote) { + return value.replace("''", "'"); + } else { + return value.replace("\"\"", "\""); + } + } + + private static String stripFirstAndLastCharacter(final String wrappedString) { + return wrappedString.substring(1, wrappedString.length() - 1); + } } diff --git a/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathComparativeOperator.java b/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathComparativeOperator.java deleted file mode 100644 index c7ffd0d7ec..0000000000 --- a/cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathComparativeOperator.java +++ /dev/null @@ -1,64 +0,0 @@ -/*
- * ============LICENSE_START=======================================================
- * Copyright (C) 2023 Tech Mahindra Ltd
- * ================================================================================
- * 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 java.util.HashMap;
-import java.util.Map;
-
-public enum CpsPathComparativeOperator {
- EQ("="),
- GT(">"),
- LT("<"),
- GE(">="),
- LE("<=");
-
- private final String label;
-
- CpsPathComparativeOperator(final String label) {
- this.label = label;
- }
-
- public final String getLabel() {
- return this.label;
- }
-
- private static final Map<String, CpsPathComparativeOperator> cpsPathComparativeOperatorPerLabel = new HashMap<>();
-
- static {
- for (final CpsPathComparativeOperator cpsPathComparativeOperator : CpsPathComparativeOperator.values()) {
- cpsPathComparativeOperatorPerLabel.put(cpsPathComparativeOperator.label, cpsPathComparativeOperator);
- }
- }
-
- /**
- * Finds the value of the given enumeration.
- *
- * @param label value of the enum
- * @return a comparativeOperatorType
- */
- public static CpsPathComparativeOperator fromString(final String label) {
- if (!cpsPathComparativeOperatorPerLabel.containsKey(label)) {
- throw new PathParsingException("Incomplete leaf condition (no operator)");
- }
- return cpsPathComparativeOperatorPerLabel.get(label);
- }
-}
-
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 3c3cbccf7e..f98df05a28 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 @@ -24,8 +24,9 @@ package org.onap.cps.cpspath.parser; import static org.onap.cps.cpspath.parser.CpsPathPrefixType.ABSOLUTE; import java.util.List; -import java.util.Map; import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; @@ -39,7 +40,7 @@ public class CpsPathQuery { private List<String> containerNames; private CpsPathPrefixType cpsPathPrefixType = ABSOLUTE; private String descendantName; - private Map<String, Object> leavesData; + private List<DataLeaf> leavesData; private String ancestorSchemaNodeIdentifier = ""; private String textFunctionConditionLeafName; private String textFunctionConditionValue; @@ -103,4 +104,11 @@ public class CpsPathQuery { return cpsPathPrefixType == ABSOLUTE && hasLeafConditions(); } + @Getter + @EqualsAndHashCode + @AllArgsConstructor + public static class DataLeaf { + private final String name; + private final Object value; + } } |