blob: 23433d85c9c9b59cecad1e3209f5b69db8980c92 [file] [log] [blame]
/**
* <copyright>
* OCL2AC is developed by Nebras Nassar based on an initial version developed by Thorsten Arendt and Jan Steffen Becker.
* </copyright>
*/
package graph.util.extensions;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.resources.IProject;
import org.eclipse.emf.common.util.EList;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import graph.Attribute;
import graph.Edge;
import graph.Graph;
import graph.Node;
public class GraphPrinter {
private Graph graph;
private int lastPrinted;
private StringBuffer result;
public GraphPrinter(Graph graph) {
this.graph = graph;
this.lastPrinted = -1;
}
private List<ExtendedNode> getExtendedNodes(Graph graph) {
List<ExtendedNode> extNodes = new ArrayList<ExtendedNode>();
// create extended nodes
for (Node n : graph.getNodes()) {
extNodes.add(new ExtendedNode(n));
}
// add predecessor and successors
for (ExtendedNode extNode : extNodes) {
for (Edge edge : graph.getEdges()) {
if (extNode.getNode() == edge.getTarget()) {
extNode.setPredecessor(getExtendedNode(extNodes, edge.getSource()));
}
if (extNode.getNode() == edge.getSource()) {
extNode.addSuccessor(getExtendedNode(extNodes, edge.getTarget()));
}
}
}
// reduce roots
List<ExtendedNode> rootExtNodes = new ArrayList<ExtendedNode>();
for (ExtendedNode extNode : extNodes) {
if (extNode.getPredecessor() == null) {
rootExtNodes.add(extNode);
}
}
return rootExtNodes;
}
private ExtendedNode getExtendedNode(List<ExtendedNode> extNodes, Node node) {
for (ExtendedNode extNode : extNodes) {
if (extNode.getNode() == node) {
return extNode;
}
}
return null;
}
public void printDocument() {
result = new StringBuffer(printPreambel());
result.append(Constants.BEGIN_DOCUMENT);
result.append(printGraph());
result.append(Constants.END_DOCUMENT);
saveFile();
}
public String printPreambel() {
StringBuffer preambel = new StringBuffer(Constants.DOCUMENTCLASS);
preambel.append(Constants.TIKZ_CELLULAR);
preambel.append(Constants.TIKZ_VCOND);
preambel.append(Constants.TIKZ_EXTENSION);
preambel.append(Constants.AMSSYMB);
return preambel.toString();
}
public String printPreambel2() {
StringBuffer preambel = new StringBuffer(Constants.DOCUMENTCLASS2);
preambel.append(Constants.TIKZ_CELLULAR);
preambel.append(Constants.TIKZ_VCOND);
preambel.append(Constants.TIKZ_EXTENSION);
preambel.append(Constants.TIKZ_ARROWS);
preambel.append(Constants.AMSSYMB);
return preambel.toString();
}
public String printGraph() {
StringBuffer ret;
if (graph.getNodes().isEmpty()) {
ret = new StringBuffer(Constants.EMPTYSET);
} else {
ret = new StringBuffer(Constants.TIKZ + Constants.SETBRACKETOPEN);
ret.append(printExtendedNodes(getExtendedNodes(graph), false));
for (Edge edge : graph.getEdges()) {
ret.append(printEdge(edge));
}
ret.append(Constants.SETBRACKETCLOSE);
}
lastPrinted = -1;
return ret.toString();
}
private String printEdge(Edge edge) {
EList<Node> nodes = graph.getNodes();
StringBuffer ret;
if (edge.getType().isContainment())
ret = new StringBuffer(
Constants.DRAWCONTAINMENT + getNodeName(nodes, edge.getSource()) + Constants.BRACKETCLOSE);
else
ret = new StringBuffer(Constants.DRAW + getNodeName(nodes, edge.getSource()) + Constants.BRACKETCLOSE);
ret.append(Constants.TONODE + edge.getType().getName() + Constants.SETBRACKETCLOSE);
ret.append(Constants.BRACKETOPEN + getNodeName(nodes, edge.getTarget()) + Constants.BRACKETCLOSE
+ Constants.SEMICOLON + Constants.NEWLINE);
return ret.toString();
}
private String printExtendedNodes(List<ExtendedNode> extendedNodes, boolean succ) {
int source = -1;
if (succ && !extendedNodes.isEmpty()) {
source = graph.getNodes().indexOf(extendedNodes.get(0).getPredecessor().getNode());
}
StringBuffer ret = new StringBuffer();
for (int i = 0; i < extendedNodes.size(); i++) {
ret.append(printNode(extendedNodes.get(i).getNode(), i, succ, source));
this.lastPrinted = graph.getNodes().indexOf(extendedNodes.get(i).getNode());
}
for (int i = 0; i < extendedNodes.size(); i++) {
ret.append(printExtendedNodes(extendedNodes.get(i).getSuccessors(), true));
}
return ret.toString();
}
private String printNode(Node node, int index, boolean succ, int source) {
EList<Node> nodes = graph.getNodes();
String sro = "";
if (lastPrinted > -1) {
sro = Constants.COMMA;
if (source < 0) {
sro += " strictly below of= " + getNodeName(nodes, nodes.get(lastPrinted)) + ",node distance=4em";
} else {
sro += " strictly right of= " + getNodeName(nodes, nodes.get(source)) + ",node distance=4em";
}
if (succ && index > 0) {
if (index == 1) {
sro += Constants.COMMA + " above=4ex";
} else {
sro += Constants.COMMA + " below=4ex";
}
}
}
StringBuffer ret = new StringBuffer(
Constants.NODE + Constants.BRACKETOPEN + getNodeName(nodes, node) + Constants.BRACKETCLOSE);
if (node.getAttributes().isEmpty()) {
ret.append(Constants.SCLASS + sro + Constants.CLASSCLOSE + Constants.SETBRACKETOPEN);
if (node.getName() != null && !node.getName().isEmpty()) {
ret.append(node.getName());
}
ret.append(Constants.COLON + node.getType().getName());
ret.append(Constants.SETBRACKETCLOSE);
} else {
ret.append(Constants.NORMALCLASS + sro + Constants.CLASSCLOSE + Constants.SETBRACKETOPEN);
ret.append(Constants.GNODELABELCLASS + Constants.SETBRACKETOPEN);
if (node.getName() != null && !node.getName().isEmpty()) {
ret.append(node.getName());
}
ret.append(Constants.COLON + node.getType().getName() + Constants.SETBRACKETCLOSE);
if (!node.getAttributes().isEmpty())
ret.append(Constants.SETBRACKETOPEN);
for (Attribute attr : node.getAttributes()) {
if (node.getAttributes().indexOf(attr) != 0)
ret.append(Constants.DOUBLEBS);
ret.append(printAttribute(attr));
}
if (!node.getAttributes().isEmpty())
ret.append(Constants.SETBRACKETCLOSE);
ret.append(Constants.SETBRACKETCLOSE);
}
ret.append(Constants.SEMICOLON + Constants.NEWLINE);
return ret.toString();
}
private String getNodeName(EList<Node> nodes, Node n) {
if (n.getName() != null && !n.getName().isEmpty()) {
return n.getName();
} else {
return "n" + String.valueOf(nodes.indexOf(n));
}
}
private String printAttribute(Attribute attr) {
StringBuffer ret = new StringBuffer(attr.getType().getName());
ret.append(Constants.SPACE);
ret.append(printOp(attr.getOp()));
ret.append(Constants.SPACE);
if (attr.getValue() == null || attr.getValue().isEmpty())
ret.append("' '");
else
ret.append(attr.getValue());
return ret.toString();
}
private String printOp(String op) {
// TODO to be extended
if (op.equals(Constants.GEQ)) {
return Constants.$GEQ$;
}
if (op.equals(Constants.NOTEQUALS)) {
return Constants.$NOTEQUALS$;
}
if (op.equals(Constants.NOTEQUALS2)) {
return Constants.$NOTEQUALS2$;
}
if (op.equals(Constants.GRTH)) {
return Constants.$GRTH$;
}
if (op.equals(Constants.EQUALS)) {
return Constants.$EQUALS$;
}
if (op.equals(Constants.LSTH)) {
return Constants.$LSTH$;
}
return "TODO";
}
private void saveFile() {
URI uri = getActualProject().getLocationURI();
String path = uri.getPath().concat(Constants.TEXFOLDER + Constants.GRAPH + Constants.TEX);
File file = new File(path);
Writer writer = null;
try {
writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file)));
writer.write(result.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
writer.close();
getActualProject().refreshLocal(IProject.DEPTH_INFINITE, null);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@SuppressWarnings("finally")
private IProject getActualProject() {
IProject actualProject = null;
IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
try {
IEditorPart editorPart = window.getActivePage().getActiveEditor();
if (editorPart != null) {
IEditorInput input = editorPart.getEditorInput();
if (input instanceof IFileEditorInput) {
IFileEditorInput fileInput = (IFileEditorInput) input;
actualProject = fileInput.getFile().getProject();
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
return actualProject;
}
}
}