I have a class with a graph inside. I iterate the graph and create a string that builds the graph, and then I just write that string into a Java file.
Is there a better way of doing this, i read about JDT and CodeModel but I really am needing some hint of how to get used with it.
EDIT
I am doing a regular expression code generator, so far I have converted the Regular Expression into a DFA represented in a directedgraph (using grail library). When I have the DFA the next step is to generate a class that have three methods, 1st one builds the same graph (DFA), 2nd method moves from one node to another, and the third method matches if the input string is accepted one. Only first method is changing depending on the regularexpression input, the other two are static and same for each generated java class.
My string based approach looks like:
import grail.interfaces.DirectedEdgeInterface;
import grail.interfaces.DirectedGraphInterface;
import grail.interfaces.DirectedNodeInterface;
import grail.interfaces.EdgeInterface;
import grail.iterators.EdgeIterator;
import grail.iterators.NodeIterator;
import grail.properties.GraphProperties;
import grail.setbased.SetBasedDirectedGraph;
public class ClassName {
private SetBasedDirectedGraph graph = new SetBasedDirectedGraph();
private static DirectedNodeInterface state;
private static DirectedNodeInterface currentState;
protected DirectedEdgeInterface edge;
public ClassName() {
buildGraph();
}
protected void buildGraph() {
// Creating Graph Nodes (Automaton States)
state = graph.createNode(3);
state.setProperty(GraphProperties.LABEL, "3");
state.setProperty(GraphProperties.DESCRIPTION, "null");
graph.addNode(state);
state = graph.createNode(2);
state.setProperty(GraphProperties.LABEL, "2");
state.setProperty(GraphProperties.DESCRIPTION, "null");
graph.addNode(state);
state = graph.createNode(1);
state.setProperty(GraphProperties.LABEL, "1");
state.setProperty(GraphProperties.DESCRIPTION, "Accepted");
graph.addNode(state);
state = graph.createNode(0);
state.setProperty(GraphProperties.LABEL, "0");
state.setProperty(GraphProperties.DESCRIPTION, "Initial");
graph.addNode(state);
.....
// Creating Graph Edges (Automaton Transitions)
edge = graph.createEdge(null, (DirectedNodeInterface) graph.getNode(2),
(DirectedNodeInterface) graph.getNode(1));
edge.setProperty((GraphProperties.LABEL), "0");
graph.addEdge(edge);
edge = graph.createEdge(null, (DirectedNodeInterface) graph.getNode(2),
(DirectedNodeInterface) graph.getNode(2));
edge.setProperty((GraphProperties.LABEL), "1");
graph.addEdge(edge);
edge = graph.createEdge(null, (DirectedNodeInterface) graph.getNode(1),
(DirectedNodeInterface) graph.getNode(1));
edge.setProperty((GraphProperties.LABEL), "0");
graph.addEdge(edge);
edge = graph.createEdge(null, (DirectedNodeInterface) graph.getNode(1),
(DirectedNodeInterface) graph.getNode(3));
edge.setProperty((GraphProperties.LABEL), "1");
graph.addEdge(edge);
edge = graph.createEdge(null, (DirectedNodeInterface) graph.getNode(0),
(DirectedNodeInterface) graph.getNode(1));
edge.setProperty((GraphProperties.LABEL), "0");
graph.addEdge(edge);
edge = graph.createEdge(null, (DirectedNodeInterface) graph.getNode(0),
(DirectedNodeInterface) graph.getNode(2));
edge.setProperty((GraphProperties.LABEL), "1");
graph.addEdge(edge);
}
}
Another solution would be to stick to the current technology but provide a small layer with the builder pattern. To implement the builder you need a small one time effort, but get much better readable code.
I implemented the first part of your code. With the proper builder you could write:
Much more readable, isn’t it? To get this you need two builders. First comes the GraphBuilder:
and than the StateBuilder:
You would do the same for edges, but I did not implement this 🙂 .
In Groovy it is even more easier to create builders (my implementation is a builder written in Java), see for example Make a builder.