package edu.isi.karma.controller.command.alignment; import java.io.PrintWriter; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import edu.isi.karma.controller.command.CommandException; import edu.isi.karma.controller.command.CommandType; import edu.isi.karma.controller.command.WorksheetCommand; import edu.isi.karma.controller.update.AbstractUpdate; import edu.isi.karma.controller.update.UpdateContainer; import edu.isi.karma.modeling.alignment.Alignment; import edu.isi.karma.modeling.alignment.AlignmentManager; import edu.isi.karma.modeling.ontology.OntologyManager; import edu.isi.karma.rep.Workspace; import edu.isi.karma.rep.alignment.InternalNode; import edu.isi.karma.rep.alignment.Label; import edu.isi.karma.rep.alignment.Node; import edu.isi.karma.rep.alignment.NodeType; import edu.isi.karma.view.VWorkspace; public class GetClassesCommand extends WorksheetCommand { final private INTERNAL_NODES_RANGE range; public enum INTERNAL_NODES_RANGE { allClasses, classesInModel, classesWithProperty, allClassesRaw } private enum JsonKeys { updateType, nodeLabel, nodeId, nodes, nodeUri, nodeRDFSLabel } private String propertyURI; private static Logger logger = LoggerFactory.getLogger(GetClassesCommand.class.getSimpleName()); protected GetClassesCommand(String id, String model, String worksheetId, INTERNAL_NODES_RANGE range, String propertyURI) { super(id, model, worksheetId); this.range = range; this.propertyURI = propertyURI; } @Override public String getCommandName() { return GetClassesCommand.class.getSimpleName(); } @Override public String getTitle() { return "Get Classes"; } @Override public String getDescription() { return null; } @Override public CommandType getCommandType() { return CommandType.notInHistory; } @Override public UpdateContainer doIt(Workspace workspace) throws CommandException { Map<Node,Boolean> nodeSet = null; if (range == INTERNAL_NODES_RANGE.classesInModel) { nodeSet = getClassesInModel(workspace); } else if (range == INTERNAL_NODES_RANGE.allClasses) { nodeSet = getAllClasses(workspace); } else if(range == INTERNAL_NODES_RANGE.classesWithProperty) { nodeSet = getClassesWithProperty(workspace, propertyURI); } else if (range == INTERNAL_NODES_RANGE.allClassesRaw) { final OntologyManager ontMgr = workspace.getOntologyManager(); final HashMap<String, Label> allClasses = ontMgr.getClasses(); UpdateContainer upd = new UpdateContainer(new AbstractUpdate() { @Override public void generateJson(String prefix, PrintWriter pw, VWorkspace vWorkspace) { JSONArray nodesArray = new JSONArray(); JSONObject obj = new JSONObject(); for (Entry<String, Label> entry : allClasses.entrySet()) { JSONObject nodeObj = new JSONObject(); Label label = entry.getValue(); nodeObj.put(JsonKeys.nodeLabel.name(), label.getDisplayName()); nodeObj.put(JsonKeys.nodeId.name(), label.getUri()); nodeObj.put(JsonKeys.nodeUri.name(), label.getUri()); nodeObj.put(JsonKeys.nodeRDFSLabel.name(), label.getRdfsLabel()); nodesArray.put(nodeObj); } obj.put(JsonKeys.nodes.name(), nodesArray); pw.println(obj.toString()); } }); return upd; } if (nodeSet == null) { nodeSet = new HashMap<>(); } final Map<Node,Boolean> finalNodeSet = nodeSet; UpdateContainer upd = new UpdateContainer(new AbstractUpdate() { @Override public void generateJson(String prefix, PrintWriter pw, VWorkspace vWorkspace) { JSONObject obj = new JSONObject(); JSONArray nodesArray = new JSONArray(); try { obj.put(JsonKeys.updateType.name(), "InternalNodesList"); for (Entry<Node,Boolean> entry:finalNodeSet.entrySet()) { Node node = entry.getKey(); if (!(node instanceof InternalNode)) { continue; } JSONObject nodeObj = new JSONObject(); String nodeLabelStr = node.getDisplayId(); Label nodeLabel = node.getLabel(); if (nodeLabel.getUri() != null && nodeLabel.getNs() != null && nodeLabel.getUri().equalsIgnoreCase(nodeLabel.getNs())) { nodeLabelStr = node.getId(); } else if(nodeLabel.getPrefix() == null && nodeLabel.getUri() != null) { nodeLabelStr = nodeLabel.getUri() + "/" + nodeLabelStr; } if (entry.getValue().booleanValue() == false) nodeLabelStr += " (add)"; nodeObj.put(JsonKeys.nodeLabel.name(), nodeLabelStr); nodeObj.put(JsonKeys.nodeId.name(), node.getId()); nodeObj.put(JsonKeys.nodeUri.name(), nodeLabel.getUri()); nodeObj.put(JsonKeys.nodeRDFSLabel.name(), nodeLabel.getRdfsLabel()); nodesArray.put(nodeObj); } obj.put(JsonKeys.nodes.name(), nodesArray); pw.println(obj.toString()); } catch (JSONException e) { e.printStackTrace(); } } }); return upd; } private Map<Node,Boolean> getAllClasses(Workspace workspace) { final OntologyManager ontMgr = workspace.getOntologyManager(); HashMap<String, Label> allClasses = ontMgr.getClasses(); logger.info("Got " + allClasses.size() + " classes from OntologyManager"); Set<Label> nodeLabels = new HashSet<>(); nodeLabels.addAll(allClasses.values()); return getNodesUsingAlignment(workspace, nodeLabels); } private Map<Node,Boolean> getClassesInModel(Workspace workspace) { final Alignment alignment = AlignmentManager.Instance().getAlignment( workspace.getId(), worksheetId); Map<Node,Boolean> nodeSet = new HashMap<>(); Set<Node> treeNodes = alignment.getSteinerTree().vertexSet(); if (treeNodes != null) { for (Node n : treeNodes) { nodeSet.put(n, true); } } return nodeSet; } private Map<Node,Boolean> getClassesWithProperty(Workspace workspace, String propertyURI) { final OntologyManager ontMgr = workspace.getOntologyManager(); final HashSet<String> domains = ontMgr.getDomainsOfProperty( propertyURI, true); if (domains == null || domains.isEmpty()) { return null; } Set<Label> nodeLabels = new HashSet<>(); for(String domain : domains) { Label domainURI = ontMgr.getUriLabel(domain); if(domainURI == null) continue; nodeLabels.add(domainURI); } return getNodesUsingAlignment(workspace, nodeLabels); } private Map<Node, Boolean> getNodesUsingAlignment(Workspace workspace, Set<Label> nodeLabels) { Map<Node,Boolean> nodeSet = new HashMap<>(); final Alignment alignment = AlignmentManager.Instance().getAlignment( workspace.getId(), worksheetId); final Set<String> steinerTreeNodeIds = new HashSet<>(); if (alignment != null && !alignment.isEmpty()) { for (Node node: alignment.getSteinerTree().vertexSet()) { if (node.getType() == NodeType.InternalNode) { steinerTreeNodeIds.add(node.getId()); } } } for (Label nodeLabel : nodeLabels) { String nodeUri = nodeLabel.getUri(); int graphLastIndex = -1; if (alignment != null) { graphLastIndex = alignment.getLastIndexOfNodeUri(nodeUri); } String nodeId; // If the node exists in graph but not in tree then use the graph node id if (graphLastIndex != -1) { int i = 1; for (; i <= graphLastIndex && steinerTreeNodeIds.contains(nodeUri + i); i++) ; nodeId = nodeUri + i; } else { nodeId = nodeUri + "1"; } boolean alreadyInTheModel = false; if (steinerTreeNodeIds.contains(nodeId)) alreadyInTheModel = true; InternalNode node = new InternalNode(nodeId, nodeLabel); nodeSet.put(node, alreadyInTheModel); // Populate the graph nodes also if (alignment != null) { Set<Node> graphNodes = alignment.getNodesByUri(nodeUri); if (graphNodes != null && !graphNodes.isEmpty()) { for (Node graphNode: graphNodes) { if (steinerTreeNodeIds.contains(graphNode.getId())) { nodeSet.put(graphNode, true); } } } } } return nodeSet; } @Override public UpdateContainer undoIt(Workspace workspace) { return null; } }