Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
prerna.reactor.masterdatabase.util.GenerateMetamodelLayout Maven / Gradle / Ivy
package prerna.reactor.masterdatabase.util;
import java.awt.geom.Rectangle2D;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.graphstream.algorithm.Toolkit;
import org.graphstream.graph.Graph;
import org.graphstream.graph.Node;
import org.graphstream.graph.implementations.MultiGraph;
import org.graphstream.ui.layout.Layout;
import org.graphstream.ui.layout.springbox.implementations.SpringBox;
import com.google.gson.GsonBuilder;
import prerna.algorithm.api.SemossDataType;
import prerna.engine.impl.AbstractDatabaseEngine;
import prerna.engine.impl.SmssUtilities;
import prerna.engine.impl.owl.OWLEngineFactory;
import prerna.engine.impl.owl.ReadOnlyOWLEngine;
import prerna.engine.impl.rdf.RDFFileSesameEngine;
import prerna.util.Constants;
import prerna.util.DIHelper;
import prerna.util.Utility;
public class GenerateMetamodelLayout {
private static final Logger classLogger = LogManager.getLogger(GenerateMetamodelLayout.class);
public static void generateLayout(String engineId) {
String smssFile = (String) DIHelper.getInstance().getEngineProperty(engineId + "_" + Constants.STORE);
Properties prop = Utility.loadProperties(smssFile);
String owlFileLocation = SmssUtilities.getOwlFile(prop).getAbsolutePath();
File owlF = new File(owlFileLocation);
// owl is stored as RDF/XML file
RDFFileSesameEngine rfse = null;
try {
rfse = new RDFFileSesameEngine();
rfse.setBasic(true);
Properties owlSmss = new Properties();
owlSmss.put(Constants.RDF_FILE_PATH, owlFileLocation);
owlSmss.put(Constants.ENGINE, engineId + "_" + Constants.OWL_ENGINE_SUFFIX);
rfse.open(owlSmss);
// we create the meta helper to facilitate querying the engine OWL
ReadOnlyOWLEngine owlReader = new OWLEngineFactory(rfse, null, engineId, prop.getProperty(Constants.ENGINE_ALIAS)).getReadOWL();
long startTimer = System.currentTimeMillis();
Graph graph = new MultiGraph(Utility.getRandomString(6));
Layout layout = new SpringBox(false);
graph.addSink(layout);
layout.addAttributeSink(graph);
List nodes = owlReader.getPhysicalConcepts();
Map nodeSizes = new HashMap();
for (String node : nodes) {
String nodeName = Utility.getInstanceName(node);
List properties = owlReader.getPropertyUris4PhysicalUri(node);
nodeSizes.put(nodeName, properties.size());
graph.addNode(Utility.getInstanceName(node));
}
List relationships = owlReader.getPhysicalRelationships();
for (String[] relation : relationships) {
String start = Utility.getInstanceName(relation[0]);
String end = Utility.getInstanceName(relation[1]);
String edge = Utility.getInstanceName(relation[2]) + "-" + start + "-" + end;
graph.addEdge(edge, start, end);
}
while (layout.getStabilization() < 0.9) {
layout.compute();
}
Map rectangles = GenerateMetamodelLayout.getRectangles(graph, nodeSizes);
Rectangles fixRectangles = new Rectangles();
// get map of correctly spaced nodes/rectangles for metamodel
Map fixedRectangles = fixRectangles.fix(rectangles);
Map> positionMap = GenerateMetamodelLayout.generatePositionMap(graph, fixedRectangles);
long endTimer = System.currentTimeMillis();
classLogger.info("Compute time = " + (endTimer - startTimer) + " ms");
// now write the file
String baseFolder = owlF.getParent();
String positionJson = baseFolder + "/" + AbstractDatabaseEngine.OWL_POSITION_FILENAME;
FileWriter writer = null;
try {
writer = new FileWriter(positionJson);
writer.write(new GsonBuilder().setPrettyPrinting().create().toJson(positionMap));
} catch (IOException e) {
classLogger.error(Constants.STACKTRACE, e);
} finally {
if(writer != null) {
try {
writer.close();
} catch (IOException e) {
classLogger.error(Constants.STACKTRACE, e);
}
}
}
} catch (Exception e) {
classLogger.error(Constants.STACKTRACE, e);
} finally {
if(rfse != null) {
try {
rfse.close();
} catch (IOException e) {
classLogger.error(Constants.STACKTRACE, e);
}
}
}
}
/////////////////////////////////////////// for owl metamodel reactor ///////////////////////////////////////////
public static Map> generateOWLMetamodelLayout(Map> databaseTables, List> databaseJoins) {
Rectangles fixRectangles = new Rectangles();
Graph graph = addNodesToGraphOwl(databaseTables, databaseJoins);
Map nodeSizes = getNodeSizesOwl(databaseTables);
Map rectangles = getRectangles(graph, nodeSizes);
Map fixedRectangles = fixRectangles.fix(rectangles);
Map> nodePositionMap = generatePositionMap(graph, fixedRectangles);
return nodePositionMap;
}
/////////////////////////////////////////// owl metamodel reactor helper functions ///////////////////////////////////////////
private static Graph addNodesToGraphOwl(Map> databaseTables, List> databaseJoins) {
Graph graph = new MultiGraph(Utility.getRandomString(6));
Layout layout = new SpringBox(false);
graph.addSink(layout);
layout.addAttributeSink(graph);
databaseTables.forEach((conceptName, properties) -> {
graph.addNode(conceptName);
});
for (Map relations : databaseJoins) {
String start = relations.get("source");
String end = relations.get("target");
String edge = relations.get("rel").toString() + "-" + start + "-" + end;
graph.addEdge(edge, start, end);
}
while (layout.getStabilization() < 0.9) {
layout.compute();
}
return graph;
}
private static Map getNodeSizesOwl(Map> databaseTables) {
Map nodeSizes = new HashMap();
databaseTables.forEach((conceptName, properties) -> {
nodeSizes.put(conceptName, properties.size());
});
return nodeSizes;
}
/////////////////////////////////////////// for graph metamodel reactors ///////////////////////////////////////////
public static Map> generateMetamodelLayoutForGraphDBs(Map graphMap) {
Rectangles fixRectangles = new Rectangles();
Map> nodeMap = (Map>) graphMap.get("nodes");
Map> relationshipMap = (Map>) graphMap.get("edges");
Graph graph = addNodesToGraph(nodeMap, relationshipMap);
Map nodeSizes = getNodeSizes(nodeMap);
Map rectangles = getRectangles(graph, nodeSizes);
Map fixedRectangles = fixRectangles.fix(rectangles);
Map> nodePositionMap = generatePositionMap(graph, fixedRectangles);
return nodePositionMap;
}
/////////////////////////////////////////// graph metamodel reactors helper functions ///////////////////////////////////////////
private static Graph addNodesToGraph(Map> nodeMap, Map> relationshipMap) {
Graph graph = new MultiGraph(Utility.getRandomString(6));
Layout layout = new SpringBox(false);
graph.addSink(layout);
layout.addAttributeSink(graph);
nodeMap.forEach((nodeName, properties) -> {
graph.addNode(nodeName);
});
relationshipMap.forEach((edgeName, fromAndToTable) -> {
String start = fromAndToTable.get(0);
String end = fromAndToTable.get(1);
String edge = edgeName + "-" + start + "-" + end;
graph.addEdge(edge, start, end);
});
while (layout.getStabilization() < 0.9) {
layout.compute();
}
return graph;
}
private static Map getNodeSizes(Map> nodeMap) {
Map nodeSizes = new HashMap();
nodeMap.forEach((nodeName, properties) -> {
nodeSizes.put(nodeName, properties.size());
});
return nodeSizes;
}
/////////////////////////////////////////// for external jdbc schema reactor ///////////////////////////////////////////
public static Map> generateMetamodelLayoutForExternal(List> databaseTables, List> databaseJoins) {
Rectangles fixRectangles = new Rectangles();
Graph graph = addNodesToGraph(databaseTables, databaseJoins);
Map nodeSizes = getNodeSizes(databaseTables);
Map rectangles = getRectangles(graph, nodeSizes);
Map fixedRectangles = fixRectangles.fix(rectangles);
Map> nodePositionMap = generatePositionMap(graph, fixedRectangles);
return nodePositionMap;
}
/////////////////////////////////////////// external jdbc schema reactor helper functions ///////////////////////////////////////////
private static Graph addNodesToGraph(List> databaseTables, List> databaseJoins) {
Graph graph = new MultiGraph(Utility.getRandomString(6));
Layout layout = new SpringBox(false);
graph.addSink(layout);
layout.addAttributeSink(graph);
for (Map nodes : databaseTables) {
String tableName = (String) nodes.get("table");
try {
graph.addNode(tableName);
} catch(org.graphstream.graph.IdAlreadyInUseException e) {
classLogger.error(Constants.STACKTRACE, e);
}
}
for (Map relations : databaseJoins) {
String start = relations.get("fromTable");
String end = relations.get("toTable");
String edge = relations.get("fromCol") + "_" + relations.get("toCol") + "-" + start + "-" + end;
try {
graph.addEdge(edge, start, end);
} catch(org.graphstream.graph.IdAlreadyInUseException e) {
classLogger.error(Constants.STACKTRACE, e);
}
}
while (layout.getStabilization() < 0.9) {
layout.compute();
}
return graph;
}
private static Map getNodeSizes(List> databaseTables) {
Map nodeSizes = new HashMap();
for (Map nodes: databaseTables) {
List columns = (List) nodes.get("columns");
String tableName = (String) nodes.get("table");
// if no columns, just why....
if(columns != null) {
nodeSizes.put(tableName, columns.size());
}
}
return nodeSizes;
}
/////////////////////////////////////////// for predict metamodel reactor ///////////////////////////////////////////
public static Map> generateMetamodelPredictionLayout(Map> nodePropMap, List> relationMapList) {
Rectangles fixRectangles = new Rectangles();
Graph graph = addNodesToGraph(nodePropMap, relationMapList);
Map nodeSizes = getNodeSizes(nodePropMap, relationMapList);
Map rectangles = getRectangles(graph, nodeSizes);
Map fixedRectangles = fixRectangles.fix(rectangles);
Map> nodePositionMap = generatePositionMap(graph, fixedRectangles);
return nodePositionMap;
}
/////////////////////////////////////////// predict metamodel reactor helper functions ///////////////////////////////////////////
private static Graph addNodesToGraph(Map> nodePropMap, List> relationMapList) {
Graph graph = new MultiGraph(Utility.getRandomString(6));
Layout layout = new SpringBox(false);
graph.addSink(layout);
layout.addAttributeSink(graph);
for (Map relations : relationMapList) {
String nodeToInsert = relations.get("fromTable").toString();
Node nodeExists = graph.getNode(nodeToInsert);
if (nodeExists == null) {
graph.addNode(nodeToInsert);
}
nodeToInsert = relations.get("toTable").toString();
nodeExists = graph.getNode(nodeToInsert);
if (nodeExists == null) {
graph.addNode(nodeToInsert);
}
}
for (Map relations : relationMapList) {
String start = relations.get("fromTable").toString();
String end = relations.get("toTable").toString();
String edge = relations.get("relName").toString() + "-" + start + "-" + end;
graph.addEdge(edge, start, end);
}
while (layout.getStabilization() < 0.9) {
layout.compute();
}
return graph;
}
private static Map getNodeSizes(Map> nodePropMap, List> relationMapList) {
Map nodeSizes = new HashMap();
nodePropMap.forEach((nodeName, properties) -> {
nodeSizes.put(nodeName, properties.size());
});
// go through relations map and any node without properties add to nodeSizes map
for (Map relations : relationMapList) {
String start = relations.get("fromTable").toString();
String end = relations.get("toTable").toString();
if (!nodeSizes.containsKey(start)) {
nodeSizes.put(start, 0);
}
if (!nodeSizes.containsKey(end)) {
nodeSizes.put(end, 0);
}
}
return nodeSizes;
}
private static Map getRectangles(Graph graph, Map nodeSizes) {
Map rectangles = new HashMap<>();
Iterator nodeIt = graph.iterator();
while (nodeIt.hasNext()) {
Node node = nodeIt.next();
String nodeName = node.getId();
float nodeSize = 0;
if (nodeSizes.containsKey(nodeName)) {
nodeSize = nodeSizes.get(nodeName);
}
double pos[] = Toolkit.nodePosition(node);
float heightMultiplier = 10;
if (nodeSize > 1) {
heightMultiplier = 5*nodeSize;
}
// Float(x, y, w, h)
rectangles.put(nodeName, new Rectangle2D.Float((float) pos[0], (float) pos[1], 160, 2*heightMultiplier));
}
return rectangles;
}
private static Map> generatePositionMap(Graph graph, Map fixedRectangles) {
Map> positionMap = new HashMap<>();
double minx = 0;
double miny = 0;
for (Entry fixedRectEntrySet: fixedRectangles.entrySet()) {
Rectangle2D rectangle = fixedRectEntrySet.getValue();
double x = rectangle.getX();
double y = rectangle.getY();
if (x < minx) {
minx = x;
}
if (y < miny) {
miny = y;
}
}
Iterator nodeIt = graph.iterator();
int numberOfNodes = graph.getNodeCount();
double leftM;
double topM;
if (numberOfNodes < 10) {
leftM = 6;
topM = 6;
} else if (numberOfNodes > 10 && numberOfNodes < 25) {
leftM = 4;
topM = 4;
} else {
leftM = 3;
topM = 3;
}
while (nodeIt.hasNext()) {
Node node = nodeIt.next();
String nodeName = node.getId();
Rectangle2D nodePosition = fixedRectangles.get(nodeName);
double upperLeftX = nodePosition.getX();
double upperLeftY = nodePosition.getY();
Map posMap = new HashMap<>();
if (minx < 0) {
posMap.put("left", leftM * (upperLeftX + (-1 * minx)));
} else {
posMap.put("left", leftM * upperLeftX);
}
if (miny < 0) {
posMap.put("top", topM * (upperLeftY + (-1 * miny)));
} else {
posMap.put("top", topM * upperLeftY);
}
positionMap.put(nodeName, posMap);
}
// clean up the graph
graph.clearSinks();
graph.clear();
return positionMap;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
// public static void main(String[] args) throws Exception {
// TestUtilityMethods.loadAll("C:\\workspace\\Semoss_Dev\\RDF_Map.prop");
//
// String tapCoreSmss = "C:\\workspace\\Semoss_Dev\\db\\TAP_Core_Data__133db94b-4371-4763-bff9-edf7e5ed021b.smss";
// BigDataEngine engine = new BigDataEngine();
// engine.open(tapCoreSmss);
//
// generateLayout("133db94b-4371-4763-bff9-edf7e5ed021b");
// }
}