From ceb8d5a7c84358b46f622ffac8c20d3f11b57781 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Sat, 14 Aug 2021 12:40:21 +0200 Subject: [PATCH] validate that tokens are known --- .../pdb/datastore/lang/ErrorListener.java | 2 +- .../lang/ExpressionValidationVisitor.java | 39 +++++++++++ .../pdb/datastore/lang/ExpressionVisitor.java | 32 ++++++--- .../datastore/lang/ParserSyntaxException.java | 67 +++++++++++++++++++ .../pdb/datastore/lang/QueryLanguage.java | 4 +- .../datastore/lang/QueryLanguageParser.java | 1 + .../pdb/datastore/lang/SyntaxException.java | 60 +---------------- .../lang/UnkownTokenSyntaxException.java | 16 +++++ 8 files changed, 149 insertions(+), 72 deletions(-) create mode 100644 data-store/src/main/java/org/lucares/pdb/datastore/lang/ExpressionValidationVisitor.java create mode 100644 data-store/src/main/java/org/lucares/pdb/datastore/lang/ParserSyntaxException.java create mode 100644 data-store/src/main/java/org/lucares/pdb/datastore/lang/UnkownTokenSyntaxException.java diff --git a/data-store/src/main/java/org/lucares/pdb/datastore/lang/ErrorListener.java b/data-store/src/main/java/org/lucares/pdb/datastore/lang/ErrorListener.java index 571d50e..3177456 100644 --- a/data-store/src/main/java/org/lucares/pdb/datastore/lang/ErrorListener.java +++ b/data-store/src/main/java/org/lucares/pdb/datastore/lang/ErrorListener.java @@ -14,6 +14,6 @@ public class ErrorListener extends BaseErrorListener { final int startIndex = charPositionInLine; final int lineStop = line; final int stopIndex = charPositionInLine; - throw new SyntaxException(msg, lineStart, startIndex, lineStop, stopIndex); + throw new ParserSyntaxException(msg, lineStart, startIndex, lineStop, stopIndex); } } diff --git a/data-store/src/main/java/org/lucares/pdb/datastore/lang/ExpressionValidationVisitor.java b/data-store/src/main/java/org/lucares/pdb/datastore/lang/ExpressionValidationVisitor.java new file mode 100644 index 0000000..6b7a5ad --- /dev/null +++ b/data-store/src/main/java/org/lucares/pdb/datastore/lang/ExpressionValidationVisitor.java @@ -0,0 +1,39 @@ +package org.lucares.pdb.datastore.lang; + +import org.lucares.pdb.api.Tags; +import org.lucares.pdb.datastore.lang.Expression.InExpression; +import org.lucares.pdb.datastore.lang.Expression.Property; + +public class ExpressionValidationVisitor extends IdentityExpressionVisitor { + + @Override + public Expression visit(final Property expression) { + + final String field = expression.getField(); + assertValueExists(field); + + final String value = expression.getValueAsString(); + assertValueExists(value); + + return null; + } + + @Override + public Expression visit(final InExpression expression) { + + assertValueExists(expression.getProperty()); + + return null; + } + + private void assertValueExists(final String value) { + if (Tags.STRING_COMPRESSOR.getIfPresent(value) < 0) { + throw new UnkownTokenSyntaxException(value); + } + } + + public static void validate(final Expression expression) { + expression.visit(new ExpressionValidationVisitor()); + } + +} diff --git a/data-store/src/main/java/org/lucares/pdb/datastore/lang/ExpressionVisitor.java b/data-store/src/main/java/org/lucares/pdb/datastore/lang/ExpressionVisitor.java index 828318c..e535047 100644 --- a/data-store/src/main/java/org/lucares/pdb/datastore/lang/ExpressionVisitor.java +++ b/data-store/src/main/java/org/lucares/pdb/datastore/lang/ExpressionVisitor.java @@ -1,47 +1,57 @@ package org.lucares.pdb.datastore.lang; public abstract class ExpressionVisitor { - public T visit(final Expression.And expression) { + + /** + * Can be overridden to change the default operation. + * + * @return T + */ + protected T doDefault() { throw new UnsupportedOperationException(); } + public T visit(final Expression.And expression) { + return doDefault(); + } + public T visit(final Expression.Or expression) { - throw new UnsupportedOperationException(); + return doDefault(); } public T visit(final Expression.Not expression) { - throw new UnsupportedOperationException(); + return doDefault(); } public T visit(final Expression.Property expression) { - throw new UnsupportedOperationException(); + return doDefault(); } public T visit(final Expression.Terminal expression) { - throw new UnsupportedOperationException(); + return doDefault(); } public T visit(final Expression.MatchAll expression) { - throw new UnsupportedOperationException(); + return doDefault(); } public T visit(final Expression.InExpression expression) { - throw new UnsupportedOperationException(); + return doDefault(); } public T visit(final Expression.Parentheses parentheses) { - throw new UnsupportedOperationException(); + return doDefault(); } public T visit(final Expression.AndCaretExpression expression) { - throw new UnsupportedOperationException(); + return doDefault(); } public T visit(final Expression.AndNotCaretExpression expression) { - throw new UnsupportedOperationException(); + return doDefault(); } public T visit(final Expression.CaretAndExpression expression) { - throw new UnsupportedOperationException(); + return doDefault(); } } diff --git a/data-store/src/main/java/org/lucares/pdb/datastore/lang/ParserSyntaxException.java b/data-store/src/main/java/org/lucares/pdb/datastore/lang/ParserSyntaxException.java new file mode 100644 index 0000000..c8ad53b --- /dev/null +++ b/data-store/src/main/java/org/lucares/pdb/datastore/lang/ParserSyntaxException.java @@ -0,0 +1,67 @@ +package org.lucares.pdb.datastore.lang; + +import java.util.Locale; + +import org.antlr.v4.runtime.ParserRuleContext; + +public class ParserSyntaxException extends SyntaxException { + + private static final long serialVersionUID = 1L; + private int lineStart; + private int startIndex; + private int lineStop; + private int stopIndex; + + public ParserSyntaxException(final ParserRuleContext context, final String message) { + this(message, context.getStart().getLine(), context.getStart().getStartIndex(), context.getStop().getLine(), + context.getStop().getStopIndex()); + } + + public ParserSyntaxException(final String message, final int lineStart, final int startIndex, final int lineStop, + final int stopIndex) { + super(message + ": " + generateMessage(lineStart, startIndex, lineStop, stopIndex)); + this.lineStart = lineStart; + this.startIndex = startIndex; + this.lineStop = lineStop; + this.stopIndex = stopIndex; + } + + private static String generateMessage(final int lineStart, final int startIndex, final int lineStop, + final int stopIndex) { + + return String.format(Locale.US, "line=%d, start=%d, to line=%d stop=%d", lineStart, startIndex, lineStop, + stopIndex); + } + + public int getLineStart() { + return lineStart; + } + + public void setLineStart(final int lineStart) { + this.lineStart = lineStart; + } + + public int getStartIndex() { + return startIndex; + } + + public void setStartIndex(final int startIndex) { + this.startIndex = startIndex; + } + + public int getLineStop() { + return lineStop; + } + + public void setLineStop(final int lineStop) { + this.lineStop = lineStop; + } + + public int getStopIndex() { + return stopIndex; + } + + public void setStopIndex(final int stopIndex) { + this.stopIndex = stopIndex; + } +} diff --git a/data-store/src/main/java/org/lucares/pdb/datastore/lang/QueryLanguage.java b/data-store/src/main/java/org/lucares/pdb/datastore/lang/QueryLanguage.java index 27a866f..230d334 100644 --- a/data-store/src/main/java/org/lucares/pdb/datastore/lang/QueryLanguage.java +++ b/data-store/src/main/java/org/lucares/pdb/datastore/lang/QueryLanguage.java @@ -49,7 +49,7 @@ public class QueryLanguage { @Override public void exitIdentifierExpression(final IdentifierExpressionContext ctx) { if (ctx.getText().length() > 255) { - throw new SyntaxException(ctx, "token too long"); + throw new ParserSyntaxException(ctx, "token too long"); } stack.push(new Terminal(ctx.getText())); @@ -58,7 +58,7 @@ public class QueryLanguage { @Override public void exitPropertyTerminalExpression(final PropertyTerminalExpressionContext ctx) { if (ctx.getText().length() > 255) { - throw new SyntaxException(ctx, "token too long"); + throw new ParserSyntaxException(ctx, "token too long"); } stack.push(new Terminal(ctx.getText())); diff --git a/data-store/src/main/java/org/lucares/pdb/datastore/lang/QueryLanguageParser.java b/data-store/src/main/java/org/lucares/pdb/datastore/lang/QueryLanguageParser.java index 0d341e8..1815537 100644 --- a/data-store/src/main/java/org/lucares/pdb/datastore/lang/QueryLanguageParser.java +++ b/data-store/src/main/java/org/lucares/pdb/datastore/lang/QueryLanguageParser.java @@ -12,6 +12,7 @@ public class QueryLanguageParser { final QueryLanguage lang = new QueryLanguage(); result = lang.parse(query); } + ExpressionValidationVisitor.validate(result); return result; } } diff --git a/data-store/src/main/java/org/lucares/pdb/datastore/lang/SyntaxException.java b/data-store/src/main/java/org/lucares/pdb/datastore/lang/SyntaxException.java index c14b724..952d7cb 100644 --- a/data-store/src/main/java/org/lucares/pdb/datastore/lang/SyntaxException.java +++ b/data-store/src/main/java/org/lucares/pdb/datastore/lang/SyntaxException.java @@ -1,67 +1,11 @@ package org.lucares.pdb.datastore.lang; -import java.util.Locale; - -import org.antlr.v4.runtime.ParserRuleContext; - public class SyntaxException extends RuntimeException { private static final long serialVersionUID = 1L; - private int lineStart; - private int startIndex; - private int lineStop; - private int stopIndex; - public SyntaxException(final ParserRuleContext context, final String message) { - this(message, context.getStart().getLine(), context.getStart().getStartIndex(), context.getStop().getLine(), - context.getStop().getStopIndex()); + public SyntaxException(final String message) { + super(message); } - public SyntaxException(final String message, final int lineStart, final int startIndex, final int lineStop, - final int stopIndex) { - super(message + ": " + generateMessage(lineStart, startIndex, lineStop, stopIndex)); - this.lineStart = lineStart; - this.startIndex = startIndex; - this.lineStop = lineStop; - this.stopIndex = stopIndex; - } - - private static String generateMessage(final int lineStart, final int startIndex, final int lineStop, - final int stopIndex) { - - return String.format(Locale.US, "line=%d, start=%d, to line=%d stop=%d", lineStart, startIndex, lineStop, - stopIndex); - } - - public int getLineStart() { - return lineStart; - } - - public void setLineStart(final int lineStart) { - this.lineStart = lineStart; - } - - public int getStartIndex() { - return startIndex; - } - - public void setStartIndex(final int startIndex) { - this.startIndex = startIndex; - } - - public int getLineStop() { - return lineStop; - } - - public void setLineStop(final int lineStop) { - this.lineStop = lineStop; - } - - public int getStopIndex() { - return stopIndex; - } - - public void setStopIndex(final int stopIndex) { - this.stopIndex = stopIndex; - } } diff --git a/data-store/src/main/java/org/lucares/pdb/datastore/lang/UnkownTokenSyntaxException.java b/data-store/src/main/java/org/lucares/pdb/datastore/lang/UnkownTokenSyntaxException.java new file mode 100644 index 0000000..1839a1a --- /dev/null +++ b/data-store/src/main/java/org/lucares/pdb/datastore/lang/UnkownTokenSyntaxException.java @@ -0,0 +1,16 @@ +package org.lucares.pdb.datastore.lang; + +public class UnkownTokenSyntaxException extends SyntaxException { + + private static final long serialVersionUID = 898095294251557256L; + private final String token; + + public UnkownTokenSyntaxException(final String token) { + super("The token '" + token + "' is unknown"); + this.token = token; + } + + public String getToken() { + return token; + } +}