Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
hadrienk committed Aug 29, 2024
1 parent 34fa7ce commit 2c37fb8
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 117 deletions.
42 changes: 21 additions & 21 deletions vtl-prov/src/main/java/fr/insee/vtl/prov/ProvenanceUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,25 @@

public class ProvenanceUtils {

public static List<Object> toBusinessModel(ProvenanceListener listener) {
// TODO: @nico te graph needs to be refactored. I'll try to fix it before monday.
ArrayList<Object> model = new ArrayList<>();
LinkedHashMap<String, ProvenanceListener.Node> variables = listener.variables;
variables.values().forEach(node -> {
String name = node.name;
Map<String, ProvenanceListener.Node> parents = node.parents;
VTLDataset vtlDataset = new VTLDataset(name);
model.add(vtlDataset);
});
return model;
}

public static void toJSON(ProvenanceListener.Node node) {

}

public static void toRDF(ProvenanceListener.Node node) {

}
//public static List<Object> toBusinessModel(ProvenanceListener listener) {
// // TODO: @nico te graph needs to be refactored. I'll try to fix it before monday.
//
// ArrayList<Object> model = new ArrayList<>();
// LinkedHashMap<String, ProvenanceListener.Node> variables = listener.variables;
// variables.values().forEach(node -> {
// String name = node.name;
// Map<String, ProvenanceListener.Node> parents = node.parents;
// VTLDataset vtlDataset = new VTLDataset(name);
// model.add(vtlDataset);
// });
// return model;
//}
//
//public static void toJSON(ProvenanceListener.Node node) {
//
//}
//
//public static void toRDF(ProvenanceListener.Node node) {
//
//}
}
88 changes: 88 additions & 0 deletions vtl-prov/src/main/java/fr/insee/vtl/prov/Variable.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package fr.insee.vtl.prov;

import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.misc.Interval;

import java.util.Optional;

public class Variable {

/**
* Returns the text of a context with empty space (aka. all channels).
*/
private static String getText(ParserRuleContext ctx) {
Token start = ctx.getStart();
Token stop = ctx.getStop();
return start.getInputStream().getText(new Interval(start.getStartIndex(), stop.getStopIndex()));
}

// Identifier of the variable.
private final ParserRuleContext nameCtx;

// Expression of the variable, if any.
private final ParserRuleContext exprCtx;

// Version of the variable.
private Integer version = 0;

// Previous version.
private Variable previous;

Variable(ParserRuleContext name, ParserRuleContext expression) {
this.nameCtx = name;
this.exprCtx = expression;
}

public Variable(ParserRuleContext name) {
this.nameCtx = name;
this.exprCtx = null;
}

public String getName() {
return getText(this.nameCtx);
}

public String getVersion() {
return getName() + "_" + this.version;
}

public Optional<String> getExpression() {
return Optional.ofNullable(exprCtx)
.map(Variable::getText);
}

public Optional<Variable> getPrevious() {
return Optional.ofNullable(previous);
}

public Variable newVersion() {
Variable copy = new Variable(this.nameCtx, this.exprCtx);
copy.version = this.version + 1;
copy.previous = this;
return copy;
}

@Override
public String toString() {
return getVersion();
}

public final boolean isSame(Variable other) {
return nameCtx.equals(other.nameCtx);
}

@Override
public final boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Variable)) return false;

Variable variable = (Variable) o;
return getVersion().equals(variable.getVersion());
}

@Override
public int hashCode() {
return nameCtx.hashCode();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,11 @@
import fr.insee.vtl.parser.VtlBaseListener;
import fr.insee.vtl.parser.VtlParser;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.misc.Interval;
import org.jgrapht.graph.DefaultDirectedGraph;
import org.jgrapht.graph.DefaultEdge;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

Expand All @@ -19,82 +16,15 @@
*/
public class VariableGraphListener extends VtlBaseListener {

/**
* Returns the text of a context with empty space (aka. all channels).
*/
private static String getText(ParserRuleContext ctx) {
Token start = ctx.getStart();
Token stop = ctx.getStop();
return start.getInputStream().getText(new Interval(start.getStartIndex(), stop.getStopIndex()));
}

private static class Variable {
private final ParserRuleContext name;
private final ParserRuleContext expression;
private Integer version = 0;

private Variable(ParserRuleContext name, ParserRuleContext expression) {
this.name = name;
this.expression = expression;
}

public Variable(ParserRuleContext name) {
this.name = name;
this.expression = null;
}

public String getName() {
return getText(this.name);
}

public String getVersion() {
return getName() + "_" + this.version;
}

public Optional<String> getExpression() {
return Optional.ofNullable(expression)
.map(VariableGraphListener::getText);
}

public Variable newVersion() {
Variable copy = new Variable(this.name, this.expression);
copy.version = this.version + 1;
return copy;
}

@Override
public String toString() {
return "Variable{" +
"name=" + getName() +
"(_" + version + ")" +
", expression=" + getExpression() +
'}';
}

@Override
public final boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Variable)) return false;

Variable variable = (Variable) o;
return name.equals(variable.name);
}

@Override
public int hashCode() {
return name.hashCode();
}
}

private Variable current;
private final Map<String, Variable> seen = new LinkedHashMap<>();
private final DefaultDirectedGraph<String, DefaultEdge> graph = new DefaultDirectedGraph<>(DefaultEdge.class);
private final DefaultDirectedGraph<Variable, DefaultEdge> graph = new DefaultDirectedGraph<>(DefaultEdge.class);

private void setCurrent(ParserRuleContext id, ParserRuleContext expression) {
assert current == null;
current = new Variable(id, expression);
if (seen.containsKey(current.getName())) {
current = seen.get(current.getName()).newVersion();
current = seen.get(current.getName()).newVersion();
}
}

Expand Down Expand Up @@ -126,12 +56,12 @@ public void exitPersistAssignment(VtlParser.PersistAssignmentContext ctx) {

@Override
public void enterVarID(VtlParser.VarIDContext ctx) {

assert current != null;

Variable newVariable = new Variable(ctx);

// Ignore if token is the same.
if (newVariable.equals(current)) {
if (newVariable.isSame(current)) {
return;
}

Expand All @@ -142,13 +72,13 @@ public void enterVarID(VtlParser.VarIDContext ctx) {
seen.put(newVariable.getName(), newVariable);
}

graph.addVertex(newVariable.getVersion());
graph.addVertex(current.getVersion());
graph.addEdge(newVariable.getVersion(), current.getVersion());
graph.addVertex(newVariable);
graph.addVertex(current);
graph.addEdge(newVariable, current);

}

public DefaultDirectedGraph<String, DefaultEdge> getGraph() {
public DefaultDirectedGraph<Variable, DefaultEdge> getGraph() {
Set<DefaultEdge> selfLoops = graph.edgeSet().stream()
.filter(e -> graph.getEdgeSource(e).equals(graph.getEdgeTarget(e)))
.collect(Collectors.toSet());
Expand All @@ -159,7 +89,7 @@ public DefaultDirectedGraph<String, DefaultEdge> getGraph() {
/**
* Returns the last variables (sink vertex) of the graph.
*/
public Set<String> getVariables() {
public Set<Variable> getVariables() {
return graph.vertexSet().stream()
.filter(v -> graph.outgoingEdgesOf(v).isEmpty())
.collect(Collectors.toSet());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ void testComplexGraph() {

VariableGraphListener provenanceListener = parseAndListen(expr);

assertThat(provenanceListener.getVariables()).containsExactly(
assertThat(provenanceListener.getVariables()).map(Variable::toString).containsExactlyInAnyOrder(
"ds8"
);
DefaultDirectedGraph<String, DefaultEdge> graph = provenanceListener.getGraph();
DefaultDirectedGraph<Variable, DefaultEdge> graph = provenanceListener.getGraph();
assertThat(graph.edgeSet()).map(DefaultEdge::toString).containsExactly(
"(ds1_0 : ds2_0)", "(ds2_0 : ds3_0)", "(ds3_0 : ds4_0)", "(ds4_0 : ds5_0)"
);
Expand All @@ -52,10 +52,10 @@ void testSimpleGraph() {

VariableGraphListener provenanceListener = parseAndListen(expr);

assertThat(provenanceListener.getVariables()).containsExactly(
assertThat(provenanceListener.getVariables()).map(Variable::toString).containsExactlyInAnyOrder(
"ds5_0"
);
DefaultDirectedGraph<String, DefaultEdge> graph = provenanceListener.getGraph();
DefaultDirectedGraph<Variable, DefaultEdge> graph = provenanceListener.getGraph();
assertThat(graph.edgeSet()).map(DefaultEdge::toString).containsExactly(
"(ds1_0 : ds2_0)", "(ds2_0 : ds3_0)", "(ds3_0 : ds4_0)", "(ds4_0 : ds5_0)"
);
Expand All @@ -68,10 +68,10 @@ void testComposition() {

VariableGraphListener provenanceListener = parseAndListen(expr);

assertThat(provenanceListener.getVariables()).containsExactly(
assertThat(provenanceListener.getVariables()).map(Variable::toString).containsExactlyInAnyOrder(
"ds3_0"
);
DefaultDirectedGraph<String, DefaultEdge> graph = provenanceListener.getGraph();
DefaultDirectedGraph<Variable, DefaultEdge> graph = provenanceListener.getGraph();
assertThat(graph.edgeSet()).map(DefaultEdge::toString).containsExactly(
"(ds1_0 : ds2_0)", "(ds2_0 : ds3_0)"
);
Expand All @@ -84,10 +84,10 @@ void testArithmeticGraph() {

VariableGraphListener provenanceListener = parseAndListen(expr);

assertThat(provenanceListener.getVariables()).containsExactly(
assertThat(provenanceListener.getVariables()).map(Variable::toString).containsExactlyInAnyOrder(
"ds3_0"
);
DefaultDirectedGraph<String, DefaultEdge> graph = provenanceListener.getGraph();
DefaultDirectedGraph<Variable, DefaultEdge> graph = provenanceListener.getGraph();
assertThat(graph.edgeSet()).map(DefaultEdge::toString).containsExactly(
"(ds1_0 : ds2_0)", "(ds2_0 : ds3_0)", "(ds1_0 : ds3_0)"
);
Expand All @@ -100,10 +100,10 @@ void testTwoGraphs() {

VariableGraphListener provenanceListener = parseAndListen(expr);

assertThat(provenanceListener.getVariables()).containsExactly(
assertThat(provenanceListener.getVariables()).map(Variable::toString).containsExactlyInAnyOrder(
"ds3_0", "ds6_0"
);
DefaultDirectedGraph<String, DefaultEdge> graph = provenanceListener.getGraph();
DefaultDirectedGraph<Variable, DefaultEdge> graph = provenanceListener.getGraph();
assertThat(graph.edgeSet()).map(DefaultEdge::toString).containsExactly(
"(ds2_0 : ds3_0)", "(ds1_0 : ds3_0)", "(ds5_0 : ds6_0)", "(ds4_0 : ds6_0)"
);
Expand All @@ -116,10 +116,10 @@ void testTwoConnectedGraphs() {

VariableGraphListener provenanceListener = parseAndListen(expr);

assertThat(provenanceListener.getVariables()).containsExactly(
assertThat(provenanceListener.getVariables()).map(Variable::toString).containsExactlyInAnyOrder(
"ds5_0", "ds3_0"
);
DefaultDirectedGraph<String, DefaultEdge> graph = provenanceListener.getGraph();
DefaultDirectedGraph<Variable, DefaultEdge> graph = provenanceListener.getGraph();
assertThat(graph.edgeSet()).map(DefaultEdge::toString).containsExactly(
"(ds2_0 : ds3_0)", "(ds1_0 : ds3_0)", "(ds4_0 : ds5_0)", "(ds1_0 : ds5_0)"
);
Expand All @@ -135,16 +135,16 @@ void testCyclicGraphs() {
"ds1 := ds2 * ds1;";

VariableGraphListener provenanceListener = parseAndListen(expr);
assertThat(provenanceListener.getVariables()).containsExactly(
assertThat(provenanceListener.getVariables()).map(Variable::toString).containsExactlyInAnyOrder(
"ds1_2"
);
DefaultDirectedGraph<String, DefaultEdge> graph = provenanceListener.getGraph();
DefaultDirectedGraph<Variable, DefaultEdge> graph = provenanceListener.getGraph();
assertThat(graph.edgeSet()).map(DefaultEdge::toString).containsExactly(
"(ds0_0 : ds1_0)", "(ds1_0 : ds1_1)", "(ds1_1 : ds1_2)", "(ds2_0 : ds1_2)"
);
}

public static void printTree(Graph<String, DefaultEdge> graph, String currentNode, String prefix, boolean isLast) {
public static void printTree(Graph<Variable, DefaultEdge> graph, Variable currentNode, String prefix, boolean isLast) {
if (currentNode == null || !graph.containsVertex(currentNode)) {
return;
}
Expand All @@ -159,13 +159,13 @@ public static void printTree(Graph<String, DefaultEdge> graph, String currentNod

// Recursively print each child node
for (DefaultEdge edge : outgoingEdges) {
String targetNode = graph.getEdgeSource(edge);
Variable targetNode = graph.getEdgeSource(edge);
printTree(graph, targetNode, prefix + (isLast ? " " : "│ "), ++index == count);
}
}

private static void printTrees(VariableGraphListener provenanceListener) {
for (String variable : provenanceListener.getVariables()) {
for (Variable variable : provenanceListener.getVariables()) {
printTree(provenanceListener.getGraph(), variable, "", false);
}
}
Expand Down

0 comments on commit 2c37fb8

Please sign in to comment.