Use antlr4 for FQN instead of regex. (#4066)

This commit is contained in:
Alberto Miorin 2022-04-12 20:40:00 +02:00 committed by GitHub
parent 1ecbe79958
commit 4a66d1c6f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 91 additions and 8 deletions

View File

@ -22,6 +22,10 @@
</properties>
<dependencies>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
</dependency>
<dependency>
<groupId>com.macasaet.fernet</groupId>
<artifactId>fernet-java8</artifactId>
@ -342,6 +346,18 @@
<build>
<plugins>
<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId>
<version>${antlr.version}</version>
<executions>
<execution>
<goals>
<goal>antlr4</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.theoryinpractise</groupId>
<artifactId>googleformatter-maven-plugin</artifactId>

View File

@ -0,0 +1,30 @@
grammar Fqn;
fqn
: name ('.' name)* EOF
;
name
: NAME # unquotedName
| NAME_WITH_RESERVED # quotedName
;
NAME
: NON_RESERVED+
;
NAME_WITH_RESERVED
: QUOTE NON_RESERVED* (RESERVED NON_RESERVED*)+ QUOTE
;
QUOTE
: '"'
;
NON_RESERVED
: ~[".]
;
RESERVED
: '.'
;

View File

@ -4,7 +4,17 @@ import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.antlr.v4.runtime.BailErrorStrategy;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import org.openmetadata.catalog.Entity;
import org.openmetadata.catalog.FqnBaseListener;
import org.openmetadata.catalog.FqnLexer;
import org.openmetadata.catalog.FqnParser;
import org.openmetadata.catalog.FqnParser.FqnContext;
import org.openmetadata.catalog.FqnParser.QuotedNameContext;
import org.openmetadata.catalog.FqnParser.UnquotedNameContext;
public class FullyQualifiedName {
// Match the sub parts of fqn string "sss". or sss. or sss$
@ -28,16 +38,37 @@ public class FullyQualifiedName {
}
public static String[] split(String string) {
SplitListener listener = new SplitListener();
walk(string, listener);
return listener.split();
}
private static <L extends FqnBaseListener> void walk(String string, L listener) {
FqnLexer fqnLexer = new FqnLexer(CharStreams.fromString(string));
CommonTokenStream tokens = new CommonTokenStream(fqnLexer);
FqnParser fqnParser = new FqnParser(tokens);
fqnParser.setErrorHandler(new BailErrorStrategy());
FqnContext fqn = fqnParser.fqn();
ParseTreeWalker walker = new ParseTreeWalker();
walker.walk(listener, fqn);
}
private static class SplitListener extends FqnBaseListener {
List<String> list = new ArrayList<>();
Matcher matcher = partsPattern.matcher(string);
while (matcher.find()) {
if (matcher.group(1) != null) {
list.add(matcher.group(3).contains(".") ? matcher.group(1) : matcher.group(3));
} else {
list.add(matcher.group(5));
}
public String[] split() {
return list.toArray(new String[list.size()]);
}
@Override
public void enterQuotedName(QuotedNameContext ctx) {
list.add(ctx.getText());
}
@Override
public void enterUnquotedName(UnquotedNameContext ctx) {
list.add(ctx.getText());
}
return list.toArray(new String[list.size()]);
}
/** Adds quotes to name as required */

View File

@ -79,6 +79,7 @@
<org.junit.jupiter.version>5.8.2</org.junit.jupiter.version>
<dropwizard-health.version>1.7.1</dropwizard-health.version>
<fernet.version>1.5.0</fernet.version>
<antlr.version>4.9.3</antlr.version>
<!-- sonar -Dsonar.login=XXX -->
<sonar.projectKey>open-metadata_OpenMetadata</sonar.projectKey>
@ -94,6 +95,11 @@
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>${antlr.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>