/******************************************************************************* * Copyright (c) 2014 Imperial College London * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Panagiotis Garefalakis - GEXF implementation ******************************************************************************/ package uk.ac.imperial.lsds.java2sdg.output; import it.uniroma1.dis.wsngroup.gexf4j.core.EdgeType; import it.uniroma1.dis.wsngroup.gexf4j.core.Gexf; import it.uniroma1.dis.wsngroup.gexf4j.core.Graph; import it.uniroma1.dis.wsngroup.gexf4j.core.Mode; import it.uniroma1.dis.wsngroup.gexf4j.core.Node; import it.uniroma1.dis.wsngroup.gexf4j.core.data.Attribute; import it.uniroma1.dis.wsngroup.gexf4j.core.data.AttributeClass; import it.uniroma1.dis.wsngroup.gexf4j.core.data.AttributeList; import it.uniroma1.dis.wsngroup.gexf4j.core.data.AttributeType; import it.uniroma1.dis.wsngroup.gexf4j.core.impl.GexfImpl; import it.uniroma1.dis.wsngroup.gexf4j.core.impl.StaxGraphWriter; import it.uniroma1.dis.wsngroup.gexf4j.core.impl.data.AttributeListImpl; import it.uniroma1.dis.wsngroup.gexf4j.core.viz.NodeShape; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; import java.util.Calendar; import java.util.HashMap; import java.util.List; import java.util.Map; import uk.ac.imperial.lsds.java2sdg.bricks.SDGAnnotation; import uk.ac.imperial.lsds.java2sdg.bricks.TaskElement; import uk.ac.imperial.lsds.java2sdg.bricks.SDG.OperatorBlock; import uk.ac.imperial.lsds.java2sdg.bricks.SDG.Stream; public class GEXFExporter implements SDGExporter{ //singleton instance private static volatile GEXFExporter instance = null; private GEXFExporter() { //If called the instance should be always null!!! if(instance != null) throw new IllegalStateException("GEXFExporter already instantiated!!"); } public static GEXFExporter getInstance(){ if(instance == null){ synchronized(GEXFExporter.class){ if(instance == null) instance = new GEXFExporter(); } } return instance; } public void export(List<OperatorBlock> sdg, String filename){ Gexf gexf = new GexfImpl(); Calendar date = Calendar.getInstance(); gexf.getMetadata() .setLastModified(date.getTime()) .setCreator("Seep project Imperial College London") .setDescription("Java2SDG Graph"); gexf.setVisualization(true); Graph graph = gexf.getGraph(); graph.setDefaultEdgeType(EdgeType.DIRECTED).setMode(Mode.STATIC); /* * Initializing Node Type * And Attributed going to be used */ AttributeList attrList = new AttributeListImpl(AttributeClass.NODE); graph.getAttributeLists().add(attrList); /* * Possible Attributes, can be expanded! */ Attribute stateAttr = attrList.createAttribute("0", AttributeType.STRING, "state"); Attribute taskAttr = attrList.createAttribute("1", AttributeType.STRING, "task"); Attribute idAttr = attrList.createAttribute("2", AttributeType.STRING, "id"); Attribute workflowIdAttr = attrList.createAttribute("3", AttributeType.STRING, "workflowID"); Attribute globalAttr = attrList.createAttribute("4", AttributeType.BOOLEAN, "global") .setDefaultValue("true"); Map<Integer, Node> nodeTable = new HashMap<Integer,Node>(); //Parsing the operations for(OperatorBlock ob : sdg){ // Check stateful to paint it differently if(ob.getStateId() != -1){ String stateName = ob.getTE().getOpType().getStateName(); /* output.add(""+stateName+" [shape=triangle,color=red,style=bold];\n"); output.add(stateName+" -> "+ob.getId()+";\n"); output.add(""+ob.getId()+" [color=green,style=filled];\n"); */ Node tmp1 = graph.createNode(stateName); tmp1.setLabel(stateName) .setSize(20) .getAttributeValues() .addValue(stateAttr, "1") .addValue(taskAttr, ob.getTE().getOpName()) .addValue(idAttr, ob.getTE().getAnn().name()) .addValue(workflowIdAttr, stateName) .addValue(globalAttr, false+""); tmp1.getShapeEntity().setNodeShape(NodeShape.DIAMOND); Node tmp2 = graph.createNode(ob.getId()+""); tmp2.setLabel(ob.getId()+"") .setSize(20) .getAttributeValues() .addValue(stateAttr, "0") .addValue(taskAttr, ob.getTE().getOpName()) .addValue(idAttr, ob.getId()+"") .addValue(workflowIdAttr, ob.getWorkflowId()+"") .addValue(globalAttr, false+""); tmp2.getShapeEntity().setNodeShape(NodeShape.SQUARE); nodeTable.put(ob.getId(), tmp1); nodeTable.put(ob.getId(), tmp2); tmp1.connectTo(tmp2); } // Check downstream to connect it appropiately if(ob.getDownstreamSize() > 0){ for(Stream downstream : ob.getDownstreamOperator()){ /* String me = ""+ob.getId()+""; String down = ""+downstream.getId()+""; output.add(me+" -> "+down+";\n"); */ Node tmp1 = graph.createNode(ob.getId()+""); tmp1.setLabel(ob.getId()+"") .setSize(20) .getAttributeValues() .addValue(stateAttr, "0") .addValue(taskAttr, ob.getTE().getOpName()) .addValue(idAttr, ob.getId()+"") .addValue(workflowIdAttr, ob.getWorkflowId()+"") .addValue(globalAttr, false+""); tmp1.getShapeEntity().setNodeShape(NodeShape.SQUARE); Node tmp2 = graph.createNode(downstream.getId()+""); tmp2.setLabel(downstream.getId()+"") .setSize(20) .getAttributeValues() .addValue(stateAttr, "0") .addValue(taskAttr, "nop") .addValue(idAttr, downstream.getId()+"") .addValue(workflowIdAttr, downstream.getWorkflowId()+"") .addValue(globalAttr, false+""); tmp2.getShapeEntity().setNodeShape(NodeShape.SQUARE); nodeTable.put(ob.getId(), tmp1); nodeTable.put(ob.getId(), tmp2); tmp1.connectTo(tmp2); } } else{ /* String me = ""+ob.getId()+""; String down = "sink"; output.add(me+" -> "+down+";\n"); */ Node tmp1 = graph.createNode(ob.getId()+""); tmp1.setLabel(ob.getId()+"") .setSize(20) .getAttributeValues() .addValue(stateAttr, "0") .addValue(taskAttr, ob.getTE().getOpName()) .addValue(idAttr,ob.getId()+"") .addValue(workflowIdAttr, ob.getWorkflowId()+"") .addValue(globalAttr, false+""); tmp1.getShapeEntity().setNodeShape(NodeShape.SQUARE); Node tmp2 = graph.createNode("sink"); tmp2.setLabel("sink") .setSize(20) .getAttributeValues() .addValue(stateAttr, "0") .addValue(taskAttr, "nop") .addValue(idAttr, ob.getId()+"") .addValue(workflowIdAttr, ob.getWorkflowId()+"") .addValue(globalAttr, false+""); tmp2.getShapeEntity().setNodeShape(NodeShape.DISC); nodeTable.put(ob.getId(), tmp1); nodeTable.put(ob.getId(), tmp2); tmp1.connectTo(tmp2); } // Use a different shape for merge ops for(TaskElement te : ob.getTEs()){ if(te.getAnn() != null && te.getAnn().equals(SDGAnnotation.COLLECTION)){ /* output.add(""+ob.getId()+" [shape=polygon,sides=5];\n"); */ Node tmp1 = graph.createNode(ob.getId()+""); tmp1.setLabel(ob.getId()+"") .setSize(20) .getAttributeValues() .addValue(stateAttr, "0") .addValue(taskAttr, ob.getTE().getOpName()) .addValue(idAttr, ob.getTE().getAnn().name()) .addValue(workflowIdAttr, ob.getWorkflowId()+"") .addValue(globalAttr, false+""); tmp1.getShapeEntity().setNodeShape(NodeShape.TRIANGLE); nodeTable.put(ob.getId(), tmp1); } } } // // Node gephi = graph.createNode("0"); // gephi // .setLabel("Gephi") // .setSize(20) // .getAttributeValues() // .addValue(attUrl, "http://gephi.org") // .addValue(attIndegree, "1"); // gephi.getShapeEntity().setNodeShape(NodeShape.DIAMOND).setUri("GephiURI"); // // Node webatlas = graph.createNode("1"); // webatlas // .setLabel("Webatlas") // .getAttributeValues() // .addValue(attUrl, "http://webatlas.fr") // .addValue(attIndegree, "2"); // // Node rtgi = graph.createNode("2"); // rtgi // .setLabel("RTGI") // .getAttributeValues() // .addValue(attUrl, "http://rtgi.fr") // .addValue(attIndegree, "1"); // // Node blab = graph.createNode("3"); // blab // .setLabel("BarabasiLab") // .getAttributeValues() // .addValue(attUrl, "http://barabasilab.com") // .addValue(attIndegree, "1") // .addValue(attFrog, "false"); // // gephi.connectTo("0", webatlas); // gephi.connectTo("1", rtgi); // webatlas.connectTo("2", gephi); // rtgi.connectTo("3", webatlas); // gephi.connectTo("4", blab); StaxGraphWriter graphWriter = new StaxGraphWriter(); File f = new File(filename+".gexf"); Writer out; try { out = new FileWriter(f, false); graphWriter.writeToStream(gexf, out, "UTF-8"); System.out.println(f.getAbsolutePath()); } catch (IOException e) { e.printStackTrace(); } } }