Skip to content

Commit

Permalink
model parser impl
Browse files Browse the repository at this point in the history
  • Loading branch information
rusakovichma committed Dec 16, 2021
1 parent 9f3cef6 commit 6d53b5f
Show file tree
Hide file tree
Showing 20 changed files with 539 additions and 11 deletions.
13 changes: 13 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Maven
target/

# Eclipse
.classpath
.project
.settings

.idea
*.iml

# Sonar
.sonar
25 changes: 25 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.example</groupId>
<artifactId>TicTaaC</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>

<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>

</project>
4 changes: 4 additions & 0 deletions src/main/java/com/github/rusakovichma/tictaac/Launcher.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.github.rusakovichma.tictaac;

public class Launcher {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.github.rusakovichma.tictaac.model;

import com.github.rusakovichma.tictaac.model.threatmodel.Asset;
import com.github.rusakovichma.tictaac.model.threatmodel.Boundary;
import com.github.rusakovichma.tictaac.model.threatmodel.DataFlow;
import com.github.rusakovichma.tictaac.model.threatmodel.Element;

import java.util.List;

public class ThreatModel {

private List<Asset> assets;
private List<Element> elements;
private List<Boundary> boundaries;
private List<DataFlow> dataFlows;

public List<Asset> getAssets() {
return assets;
}

public void setAssets(List<Asset> assets) {
this.assets = assets;
}

public List<Element> getElements() {
return elements;
}

public void setElements(List<Element> elements) {
this.elements = elements;
}

public List<Boundary> getBoundaries() {
return boundaries;
}

public void setBoundaries(List<Boundary> boundaries) {
this.boundaries = boundaries;
}

public List<DataFlow> getDataFlows() {
return dataFlows;
}

public void setDataFlows(List<DataFlow> dataFlows) {
this.dataFlows = dataFlows;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.github.rusakovichma.tictaac.model.threatmodel;

public class Asset {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.github.rusakovichma.tictaac.model.threatmodel;

public class Boundary {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.github.rusakovichma.tictaac.model.threatmodel;

public class DataFlow {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.github.rusakovichma.tictaac.model.threatmodel;

public class Element {
}
11 changes: 11 additions & 0 deletions src/main/java/com/github/rusakovichma/tictaac/parser/Parser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.github.rusakovichma.tictaac.parser;

import com.github.rusakovichma.tictaac.parser.model.NodeTree;

import java.io.IOException;

public interface Parser {

public NodeTree getNodeTree(String file) throws IOException;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package com.github.rusakovichma.tictaac.parser.impl;

import com.github.rusakovichma.tictaac.parser.Parser;
import com.github.rusakovichma.tictaac.parser.model.Node;
import com.github.rusakovichma.tictaac.parser.model.NodeTree;
import com.github.rusakovichma.tictaac.parser.model.NodeType;
import com.github.rusakovichma.tictaac.util.StringUtils;

import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.function.Consumer;

import static com.github.rusakovichma.tictaac.util.FileUtil.readLineByLine;

public class ParserImpl implements Parser {

private Node findClosestSibling(NodeTree tree, Node newNode) {
if (tree.isEmpty()) {
return null;
}

Iterator<Node> reversedIterator = tree.descendingIterator();

while (reversedIterator.hasNext()) {
Node sibling = reversedIterator.next();

//already parent or more mature node
if (newNode.getIndentLength() > sibling.getIndentLength()){
break;
}

if (sibling.getIndentLength() == newNode.getIndentLength() &&
sibling.getNodeType() == newNode.getNodeType()) {
return sibling;
}
}

return null;
}

private void addSibling(Node prevNode, Node newNode) {
newNode.setNodeLevel(prevNode.getNodeLevel());
prevNode.setNextSibling(newNode);

addDescendant(prevNode.getParent(), newNode);
}

private void addDescendant(Node parent, Node desc) {
if (parent != null) {
desc.setNodeLevel(parent.getNodeLevel() + 1);
if (parent.getDescendants() == null) {
parent.setDescendants(new LinkedList<>());
}
parent.getDescendants().add(desc);
}
desc.setParent(parent);
}

@Override
public NodeTree getNodeTree(String file) throws IOException {
final NodeTree tree = new NodeTree();

Consumer<String> fileLineConsumer = line -> {
if (line == null || line.isEmpty()) {
return;
}

int indentLength;
try {
indentLength = StringUtils.getStartingIndentLength(line);
} catch (IOException e) {
e.printStackTrace();
return;
}

NodeType nodeType = NodeType.getType(line);
if (nodeType == NodeType.unknown) {
return;
}

Node newNode = new Node();
newNode.setNodeType(nodeType);
newNode.setContent(line);
newNode.setIndentLength(indentLength);

if (indentLength == 0) {
newNode.setNodeLevel(0);

Node sibling = findClosestSibling(tree, newNode);
if (sibling != null) {
//sibling
addSibling(sibling, newNode);
}
} else {
if (tree.isEmpty()) {
newNode.setNodeLevel(0);
}

Node prevNode = tree.getLast();
if (prevNode.getIndentLength() == indentLength) {
//sibling
addSibling(prevNode, newNode);
} else if (indentLength > prevNode.getIndentLength()) {
//parent
addDescendant(prevNode, newNode);
} else if (indentLength < prevNode.getIndentLength()) {
Node closestSibling = findClosestSibling(tree, newNode);
if (closestSibling != null) {
addSibling(closestSibling, newNode);
}
}
}

tree.add(newNode);
};

readLineByLine(file, fileLineConsumer);

return tree;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.github.rusakovichma.tictaac.parser.model;

import java.util.LinkedList;

public class Node {

private int indentLength;
private int nodeLevel;
private Node parent;
private Node nextSibling;
private LinkedList<Node> descendants;
private String content;
private NodeType nodeType;

public int getIndentLength() {
return indentLength;
}

public void setIndentLength(int indentLength) {
this.indentLength = indentLength;
}

public Node getParent() {
return parent;
}

public void setParent(Node parent) {
this.parent = parent;
}

public Node getNextSibling() {
return nextSibling;
}

public void setNextSibling(Node nextSibling) {
this.nextSibling = nextSibling;
}

public String getContent() {
return content;
}

public void setContent(String content) {
this.content = content;
}

public int getNodeLevel() {
return nodeLevel;
}

public void setNodeLevel(int nodeLevel) {
this.nodeLevel = nodeLevel;
}

public LinkedList<Node> getDescendants() {
return descendants;
}

public void setDescendants(LinkedList<Node> descendants) {
this.descendants = descendants;
}

public NodeType getNodeType() {
return nodeType;
}

public void setNodeType(NodeType nodeType) {
this.nodeType = nodeType;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.github.rusakovichma.tictaac.parser.model;

import java.util.LinkedList;

public class NodeTree extends LinkedList<Node> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.github.rusakovichma.tictaac.parser.model;

import java.util.regex.Pattern;

public enum NodeType {
element,
property,
flow,
unknown;

private static final Pattern PROPERTY_PATTERN = Pattern.compile("^(\\t|\\s)*[a-zA-Z0-9_-]+:");
private static final Pattern FLOW_PATTERN = Pattern.compile("[a-zA-Z0-9_ -]+(->)[a-zA-Z0-9_ -]+");
private static final Pattern ELEMENT_PATTERN = Pattern.compile("-[a-zA-Z0-9_ -]+");

public static NodeType getType(String raw) {
if (raw == null) {
return unknown;
}
if (PROPERTY_PATTERN.matcher(raw).find()) {
return property;
}
if (FLOW_PATTERN.matcher(raw).find()) {
return flow;
}
if (ELEMENT_PATTERN.matcher(raw).find()) {
return element;
}
return unknown;
}
}
21 changes: 21 additions & 0 deletions src/main/java/com/github/rusakovichma/tictaac/util/FileUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.github.rusakovichma.tictaac.util;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.function.Consumer;
import java.util.stream.Stream;

public class FileUtil {

private FileUtil() {
}

public static void readLineByLine(String file, Consumer<String> lineStringConsumer)
throws IOException {
try (Stream<String> stream = Files.lines(Paths.get(file))) {
stream.forEach(lineStringConsumer);
}
}

}
Loading

0 comments on commit 6d53b5f

Please sign in to comment.