From ea3b85f26e6c9c47e4989bfdf16ee0c929fd1706 Mon Sep 17 00:00:00 2001 From: eishchuk Date: Mon, 27 May 2019 17:32:10 +0200 Subject: [PATCH] Initial commit --- .gitignore | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ pom.xml | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main/antlr4/com/ishchuk/antlr4/JSONgram.g4 | 20 ++++++++++++++++++++ src/main/antlr4/com/ishchuk/antlr4/Log.g4 | 16 ++++++++++++++++ src/main/java/com/ishchuk/antlr/json/JsonListener.java | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main/java/com/ishchuk/antlr/json/model/JsonArray.java | 21 +++++++++++++++++++++ src/main/java/com/ishchuk/antlr/json/model/JsonElement.java | 13 +++++++++++++ src/main/java/com/ishchuk/antlr/json/model/JsonModel.java | 22 ++++++++++++++++++++++ src/main/java/com/ishchuk/antlr/json/model/JsonObject.java | 20 ++++++++++++++++++++ src/main/java/com/ishchuk/antlr/json/model/JsonPrimitive.java | 15 +++++++++++++++ src/main/java/com/ishchuk/antlr/json/model/intermediate/Intermediate.java | 23 +++++++++++++++++++++++ src/main/java/com/ishchuk/antlr/log/LogListener.java | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/main/java/com/ishchuk/antlr/log/model/LogEntry.java | 35 +++++++++++++++++++++++++++++++++++ src/main/java/com/ishchuk/antlr/log/model/LogLevel.java | 5 +++++ src/test/java/com/ishchuk/antlr/JsonParserUnitTest.java | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ src/test/java/com/ishchuk/antlr/LogParserUnitTest.java | 38 ++++++++++++++++++++++++++++++++++++++ 16 files changed, 594 insertions(+), 0 deletions(-) create mode 100644 .gitignore create mode 100644 pom.xml create mode 100644 src/main/antlr4/com/ishchuk/antlr4/JSONgram.g4 create mode 100644 src/main/antlr4/com/ishchuk/antlr4/Log.g4 create mode 100644 src/main/java/com/ishchuk/antlr/json/JsonListener.java create mode 100644 src/main/java/com/ishchuk/antlr/json/model/JsonArray.java create mode 100644 src/main/java/com/ishchuk/antlr/json/model/JsonElement.java create mode 100644 src/main/java/com/ishchuk/antlr/json/model/JsonModel.java create mode 100644 src/main/java/com/ishchuk/antlr/json/model/JsonObject.java create mode 100644 src/main/java/com/ishchuk/antlr/json/model/JsonPrimitive.java create mode 100644 src/main/java/com/ishchuk/antlr/json/model/intermediate/Intermediate.java create mode 100644 src/main/java/com/ishchuk/antlr/log/LogListener.java create mode 100644 src/main/java/com/ishchuk/antlr/log/model/LogEntry.java create mode 100644 src/main/java/com/ishchuk/antlr/log/model/LogLevel.java create mode 100644 src/test/java/com/ishchuk/antlr/JsonParserUnitTest.java create mode 100644 src/test/java/com/ishchuk/antlr/LogParserUnitTest.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..03744fa --- /dev/null +++ b/.gitignore @@ -0,0 +1,73 @@ +.classpath +.project +.settings +.idea +.metadata +*.iml +*.ipr +kong-stack.retry +target +.factorypath + +# +# NodeJS +# + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Typescript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..02a2143 --- /dev/null +++ b/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.ishchuk + converter + 1.0-SNAPSHOT + + + + org.antlr + antlr4-runtime + 4.7.2 + + + + junit + junit + 4.12 + test + + + + + + + + org.antlr + antlr4-maven-plugin + 4.7.2 + + + + antlr4 + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 3.0.0 + + + generate-sources + + add-source + + + + ${basedir}/target/generated-sources/antlr4 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + + \ No newline at end of file diff --git a/src/main/antlr4/com/ishchuk/antlr4/JSONgram.g4 b/src/main/antlr4/com/ishchuk/antlr4/JSONgram.g4 new file mode 100644 index 0000000..9b2c452 --- /dev/null +++ b/src/main/antlr4/com/ishchuk/antlr4/JSONgram.g4 @@ -0,0 +1,20 @@ +grammar JSONgram; + +json : content; + +object : '{' keyValue (',' keyValue)* '}' | '{' '}'; +table : '[' content (',' content)* ']' | '[' ']'; +keyValue : CHAINE ':' content; + +content: CHAINE | NUMBER | object | table | 'true' | 'false' | 'null'; + + +fragment INT: '0' | [1-9] [0-9]*; +fragment EXP: [Ee] [+\-]? INT; + +CHAINE : '"' [a-zA-Z0-9_!@#$%^&*()\-+=/.,<>;':] [a-zA-Z0-9_!@#$%^&*()\-+=/.,<>;':]* '"' ; +NUMBER : '-'? INT ('.' [0-9] +)? EXP?; + +WS : [ \t\n\r] + -> skip; + + diff --git a/src/main/antlr4/com/ishchuk/antlr4/Log.g4 b/src/main/antlr4/com/ishchuk/antlr4/Log.g4 new file mode 100644 index 0000000..3ecb966 --- /dev/null +++ b/src/main/antlr4/com/ishchuk/antlr4/Log.g4 @@ -0,0 +1,16 @@ +grammar Log; + +log : entry+; +entry : timestamp ' ' level ' ' message CRLF; +timestamp : DATE ' ' TIME; +level : 'ERROR' | 'INFO' | 'DEBUG'; +message : (TEXT | ' ')+; + +fragment DIGIT : [0-9]; +fragment TWODIGIT : DIGIT DIGIT; +fragment LETTER : [A-Za-z]; + +DATE : TWODIGIT TWODIGIT '-' LETTER LETTER LETTER '-' TWODIGIT; +TIME : TWODIGIT ':' TWODIGIT ':' TWODIGIT; +TEXT : LETTER+; +CRLF : '\r'? '\n' | '\r'; \ No newline at end of file diff --git a/src/main/java/com/ishchuk/antlr/json/JsonListener.java b/src/main/java/com/ishchuk/antlr/json/JsonListener.java new file mode 100644 index 0000000..84e85fb --- /dev/null +++ b/src/main/java/com/ishchuk/antlr/json/JsonListener.java @@ -0,0 +1,123 @@ +package com.ishchuk.antlr.json; + +import com.ishchuk.antlr.json.model.*; +import com.ishchuk.antlr4.JSONgramBaseListener; +import com.ishchuk.antlr4.JSONgramParser; + +import java.util.*; + + +public class JsonListener extends JSONgramBaseListener { + + private JsonModel jsonFile; + private Map json; + private List var; + private boolean read; + + @Override + public void enterJson(JSONgramParser.JsonContext ctx) { + this.jsonFile = new JsonModel(); + this.json = new HashMap<>(); + this.var = new ArrayList<>(); + this.read = true; + + + } + + public JsonModel getJsonFile() { + return this.jsonFile; + } + + @Override + public void enterContent(JSONgramParser.ContentContext ctx) { + + if (read && Objects.nonNull(ctx.object())) { + ctx.object().keyValue().forEach(kv -> { + JsonElement elem = new JsonElement(); + elem.setContent(kv.content()); + json.put(kv.CHAINE().getSymbol().getText(), elem); + }); + read = false; + } else { + System.out.println("content: " + ctx.getText()); + String parent = getParent(ctx); + System.out.println("parent: " + parent); + + + if (json.containsKey(parent)) { + System.out.println("parent in json"); + searchMap(json, parent); + + } else { + System.out.println("NOT in json"); + + json.values().forEach(kv -> { + if (kv instanceof JsonObject) { + searchMap(((JsonObject) kv).getMap(), parent); + } else if (kv instanceof JsonArray) { + ((JsonArray) kv).getArray().forEach(obj -> { + searchMap(obj.getMap(), parent); + }); + } + }); + } + } + } + + private void searchMap(Map json, final String parent) { + if (json.containsKey(parent)) { + System.out.println("parent in json"); + if (json.get(parent).getContent() instanceof JSONgramParser.ContentContext) { + JSONgramParser.ContentContext content = + (JSONgramParser.ContentContext) json.get(parent).getContent(); + if (Objects.nonNull(content.object())) { + json.replace(parent, prepareJsonObject(content)); + } else if (Objects.nonNull(content.table())) { + JsonArray arr = new JsonArray(); + content.table().content().forEach(cont -> { + JsonObject obj = prepareJsonObject(cont); + arr.getArray().add(obj); + }); + arr.getArray().forEach(temp -> { + searchMap(temp.getMap(), parent); + }); + json.replace(parent, arr); + } else { + JsonPrimitive prim = new JsonPrimitive(); + prim.setValue(content.getText()); + json.replace(parent, prim); + } + } + } + } + + private JsonObject prepareJsonObject(JSONgramParser.ContentContext cont) { + JsonObject obj = new JsonObject(); + cont.object().keyValue().forEach(kv -> { + JsonElement elem = new JsonElement(); + elem.setContent(kv.content()); + obj.getMap().put(kv.CHAINE().getSymbol().getText(), elem); + }); + return obj; + } + + + private String getParent(JSONgramParser.ContentContext ctx) { + String parent; + if (Objects.nonNull(ctx.table()) || Objects.nonNull(ctx.object())) { + if (ctx.getParent().children.get(0).getText().equals("[")) { + parent = ctx.getParent().getParent().getParent().children.get(0).getText(); + } else { + parent = ctx.getParent().children.get(0).getText(); + } + } else { + parent = ctx.getParent().children.get(0).getText(); + } + return parent; + } + + + + + +} diff --git a/src/main/java/com/ishchuk/antlr/json/model/JsonArray.java b/src/main/java/com/ishchuk/antlr/json/model/JsonArray.java new file mode 100644 index 0000000..640cda4 --- /dev/null +++ b/src/main/java/com/ishchuk/antlr/json/model/JsonArray.java @@ -0,0 +1,21 @@ +package com.ishchuk.antlr.json.model; + +import java.util.ArrayList; +import java.util.List; + +public class JsonArray extends JsonElement { + + private List array; + + public List getArray() { + return array; + } + + public void setArray(List array) { + this.array = array; + } + + public JsonArray() { + this.array = new ArrayList<>(); + } +} diff --git a/src/main/java/com/ishchuk/antlr/json/model/JsonElement.java b/src/main/java/com/ishchuk/antlr/json/model/JsonElement.java new file mode 100644 index 0000000..e89703e --- /dev/null +++ b/src/main/java/com/ishchuk/antlr/json/model/JsonElement.java @@ -0,0 +1,13 @@ +package com.ishchuk.antlr.json.model; + +public class JsonElement { + private Object content; + + public Object getContent() { + return content; + } + + public void setContent(Object content) { + this.content = content; + } +} diff --git a/src/main/java/com/ishchuk/antlr/json/model/JsonModel.java b/src/main/java/com/ishchuk/antlr/json/model/JsonModel.java new file mode 100644 index 0000000..73de968 --- /dev/null +++ b/src/main/java/com/ishchuk/antlr/json/model/JsonModel.java @@ -0,0 +1,22 @@ +package com.ishchuk.antlr.json.model; + +import java.util.ArrayList; +import java.util.List; + +public class JsonModel { + + private List list; + + public List getList() { + return list; + } + + public void setList(List list) { + this.list = list; + } + + public JsonModel() { + this.list = new ArrayList<>(); + } + +} diff --git a/src/main/java/com/ishchuk/antlr/json/model/JsonObject.java b/src/main/java/com/ishchuk/antlr/json/model/JsonObject.java new file mode 100644 index 0000000..d2f6821 --- /dev/null +++ b/src/main/java/com/ishchuk/antlr/json/model/JsonObject.java @@ -0,0 +1,20 @@ +package com.ishchuk.antlr.json.model; + +import java.util.HashMap; +import java.util.Map; + +public class JsonObject extends JsonElement { + private Map map; + + public Map getMap() { + return map; + } + + public void setMap(Map map) { + this.map = map; + } + + public JsonObject() { + this.map = new HashMap<>(); + } +} diff --git a/src/main/java/com/ishchuk/antlr/json/model/JsonPrimitive.java b/src/main/java/com/ishchuk/antlr/json/model/JsonPrimitive.java new file mode 100644 index 0000000..3be56c8 --- /dev/null +++ b/src/main/java/com/ishchuk/antlr/json/model/JsonPrimitive.java @@ -0,0 +1,15 @@ +package com.ishchuk.antlr.json.model; + +public class JsonPrimitive extends JsonElement { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + +} diff --git a/src/main/java/com/ishchuk/antlr/json/model/intermediate/Intermediate.java b/src/main/java/com/ishchuk/antlr/json/model/intermediate/Intermediate.java new file mode 100644 index 0000000..2373865 --- /dev/null +++ b/src/main/java/com/ishchuk/antlr/json/model/intermediate/Intermediate.java @@ -0,0 +1,23 @@ +package com.ishchuk.antlr.json.model.intermediate; + +public class Intermediate { + private boolean wait; + private String name; + + public boolean isWait() { + return wait; + } + + public void setWait(boolean wait) { + this.wait = wait; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} + diff --git a/src/main/java/com/ishchuk/antlr/log/LogListener.java b/src/main/java/com/ishchuk/antlr/log/LogListener.java new file mode 100644 index 0000000..f21ff5f --- /dev/null +++ b/src/main/java/com/ishchuk/antlr/log/LogListener.java @@ -0,0 +1,51 @@ +package com.ishchuk.antlr.log; + +import com.ishchuk.antlr4.LogBaseListener; +import com.ishchuk.antlr4.LogParser; +import com.ishchuk.antlr.log.model.LogLevel; +import com.ishchuk.antlr.log.model.LogEntry; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Locale; + +public class LogListener extends LogBaseListener { + + private static final DateTimeFormatter DEFAULT_DATETIME_FORMATTER + = DateTimeFormatter.ofPattern("yyyy-MMM-dd HH:mm:ss", Locale.ENGLISH); + + private List entries = new ArrayList<>(); + private LogEntry currentLogEntry; + + @Override + public void enterEntry(LogParser.EntryContext ctx) { + this.currentLogEntry = new LogEntry(); + } + + @Override + public void exitEntry(LogParser.EntryContext ctx) { + entries.add(currentLogEntry); + } + + @Override + public void enterTimestamp(LogParser.TimestampContext ctx) { + currentLogEntry.setTimestamp(LocalDateTime.parse(ctx.getText(), DEFAULT_DATETIME_FORMATTER)); + } + + @Override + public void enterMessage(LogParser.MessageContext ctx) { + currentLogEntry.setMessage(ctx.getText()); + } + + @Override + public void enterLevel(LogParser.LevelContext ctx) { + currentLogEntry.setLevel(LogLevel.valueOf(ctx.getText())); + } + + public List getEntries() { + return Collections.unmodifiableList(entries); + } +} \ No newline at end of file diff --git a/src/main/java/com/ishchuk/antlr/log/model/LogEntry.java b/src/main/java/com/ishchuk/antlr/log/model/LogEntry.java new file mode 100644 index 0000000..11fb6d0 --- /dev/null +++ b/src/main/java/com/ishchuk/antlr/log/model/LogEntry.java @@ -0,0 +1,35 @@ +package com.ishchuk.antlr.log.model; + +import java.time.LocalDateTime; + + +public class LogEntry { + + private LogLevel level; + private String message; + private LocalDateTime timestamp; + + public LogLevel getLevel() { + return level; + } + + public void setLevel(LogLevel level) { + this.level = level; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public LocalDateTime getTimestamp() { + return timestamp; + } + + public void setTimestamp(LocalDateTime timestamp) { + this.timestamp = timestamp; + } +} diff --git a/src/main/java/com/ishchuk/antlr/log/model/LogLevel.java b/src/main/java/com/ishchuk/antlr/log/model/LogLevel.java new file mode 100644 index 0000000..50962f3 --- /dev/null +++ b/src/main/java/com/ishchuk/antlr/log/model/LogLevel.java @@ -0,0 +1,5 @@ +package com.ishchuk.antlr.log.model; + +public enum LogLevel { + DEBUG, INFO, ERROR +} diff --git a/src/test/java/com/ishchuk/antlr/JsonParserUnitTest.java b/src/test/java/com/ishchuk/antlr/JsonParserUnitTest.java new file mode 100644 index 0000000..512402d --- /dev/null +++ b/src/test/java/com/ishchuk/antlr/JsonParserUnitTest.java @@ -0,0 +1,49 @@ +package com.ishchuk.antlr; + + +import com.ishchuk.antlr.json.JsonListener; +import com.ishchuk.antlr4.JSONgramLexer; +import com.ishchuk.antlr4.JSONgramParser; + +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.tree.ParseTreeWalker; +import org.junit.Test; + + + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +public class JsonParserUnitTest { + + @Test + public void whenJsonObjectWithString_thenStringIsDetected() throws Exception { + // String line = "{\"menu\": \"light134-()%4praer---'$\"}"; + String line = "{\n" + "\"line\": \"contentLine\"," + + "\"table\":[{\"lineInTable\":\"contentLineIntTable\"},{}]," + + " \"menu\": {\n" + + " \"id\": \"file\",\n" + + " \"value\": \"File\",\n" + + " \"popup\": {\n" + + " \"menuitem\": [\n" + + " { \"value\": \"New\", \"onclick\": \"CreateNewDoc()\" },\n" + + " { \"value\": \"Open\", \"onclick\": \"OpenDoc()\" },\n" + + " { \"value\": \"Close\", \"onclick\": \"CloseDoc()\" }\n" + + " ]\n" + + " }\n" + + " }\n" + + "}"; + JSONgramLexer serverJSONgramLexer = new JSONgramLexer(CharStreams.fromString(line)); + CommonTokenStream tokens = new CommonTokenStream( serverJSONgramLexer ); + JSONgramParser JSONgramParser = new JSONgramParser(tokens); + ParseTreeWalker walker = new ParseTreeWalker(); + JsonListener jsonWalker = new JsonListener(); + walker.walk(jsonWalker, JSONgramParser.json()); + + System.out.println(jsonWalker.getJsonFile().getList().size()); + jsonWalker.getJsonFile().getList().forEach(System.out::println); + assertThat(jsonWalker.getJsonFile(), is(line)); + + } +} diff --git a/src/test/java/com/ishchuk/antlr/LogParserUnitTest.java b/src/test/java/com/ishchuk/antlr/LogParserUnitTest.java new file mode 100644 index 0000000..aba16b8 --- /dev/null +++ b/src/test/java/com/ishchuk/antlr/LogParserUnitTest.java @@ -0,0 +1,38 @@ +package com.ishchuk.antlr; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +import com.ishchuk.antlr.log.LogListener; +import com.ishchuk.antlr.log.model.LogLevel; +import com.ishchuk.antlr.log.model.LogEntry; +import com.ishchuk.antlr4.LogLexer; +import com.ishchuk.antlr4.LogParser; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.tree.ParseTreeWalker; +import org.junit.Test; + +import java.time.LocalDateTime; + + +public class LogParserUnitTest { + + @Test + public void whenLogContainsOneErrorLogEntry_thenOneErrorIsReturned() throws Exception { + String logLines = "2018-May-05 14:20:21 DEBUG entering awesome method\r\n" + + "2018-May-05 14:20:24 ERROR Bad thing happened\r\n"; + LogLexer serverLogLexer = new LogLexer(CharStreams.fromString(logLines)); + CommonTokenStream tokens = new CommonTokenStream( serverLogLexer ); + LogParser logParser = new LogParser(tokens); + ParseTreeWalker walker = new ParseTreeWalker(); + LogListener logWalker = new LogListener(); + walker.walk(logWalker, logParser.log()); + + assertThat(logWalker.getEntries().size(), is(2)); + LogEntry error = logWalker.getEntries().get(1); + assertThat(error.getLevel(), is(LogLevel.ERROR)); + assertThat(error.getMessage(), is("Bad thing happened")); + assertThat(error.getTimestamp(), is(LocalDateTime.of(2018,5,5,14,20,24))); + } +} -- libgit2 0.21.2