private DirectedWeightedMultigraph<Node, LabeledLink> computeSteinerTree(Set<Node> steinerNodes) {

    if (steinerNodes == null || steinerNodes.size() == 0) {
      logger.error("There is no steiner node.");
      return null;
    }

    //		System.out.println(steinerNodes.size());
    List<Node> steinerNodeList = new ArrayList<Node>(steinerNodes);

    long start = System.currentTimeMillis();
    UndirectedGraph<Node, DefaultLink> undirectedGraph =
        new AsUndirectedGraph<Node, DefaultLink>(this.graphBuilder.getGraph());

    logger.debug("computing steiner tree ...");
    SteinerTree steinerTree = new SteinerTree(undirectedGraph, steinerNodeList);
    DirectedWeightedMultigraph<Node, LabeledLink> tree =
        new TreePostProcess(this.graphBuilder, steinerTree.getDefaultSteinerTree(), null, false)
            .getTree();
    // (DirectedWeightedMultigraph<Node,
    // LabeledLink>)GraphUtil.asDirectedGraph(steinerTree.getDefaultSteinerTree());

    logger.debug(GraphUtil.labeledGraphToString(tree));

    long steinerTreeElapsedTimeMillis = System.currentTimeMillis() - start;
    logger.debug("total number of nodes in steiner tree: " + tree.vertexSet().size());
    logger.debug("total number of edges in steiner tree: " + tree.edgeSet().size());
    logger.debug("time to compute steiner tree: " + (steinerTreeElapsedTimeMillis / 1000F));

    return tree;

    //		long finalTreeElapsedTimeMillis = System.currentTimeMillis() - steinerTreeElapsedTimeMillis;
    //		DirectedWeightedMultigraph<Node, Link> finalTree = buildOutputTree(tree);
    //		logger.info("time to build final tree: " + (finalTreeElapsedTimeMillis/1000F));

    //		GraphUtil.printGraph(finalTree);
    //		return finalTree;

  }
  @Override
  public void generateJson(String prefix, PrintWriter pw, VWorkspace vWorkspace) {
    JSONObject topObj = new JSONObject();
    try {
      topObj.put(
          GenericJsonKeys.updateType.name(),
          SVGAlignmentUpdate_ForceKarmaLayout.class.getSimpleName());
      topObj.put(JsonKeys.alignmentId.name(), alignmentId);
      topObj.put(JsonKeys.worksheetId.name(), vWorksheetId);

      @SuppressWarnings("unchecked")
      DirectedWeightedMultigraph<Vertex, LabeledWeightedEdge> treeClone =
          (DirectedWeightedMultigraph<Vertex, LabeledWeightedEdge>) tree.clone();
      // Reversing the inverse links
      alignment.updateLinksDirections(this.root, null, treeClone);

      /** * Add the nodes and the links from the Steiner tree ** */
      List<String> hNodeIdsAdded = new ArrayList<String>();
      JSONArray vertArr = new JSONArray();
      JSONArray linksArr = new JSONArray();
      int maxTreeHeight = 0;

      if (tree != null && tree.vertexSet().size() != 0) {

        /** * Add the nodes ** */
        Set<Vertex> vertices = tree.vertexSet();
        HashMap<Vertex, Integer> verticesIndex = new HashMap<Vertex, Integer>();
        int nodesIndexcounter = 0;

        for (Vertex vertex : vertices) {
          JSONObject vertObj = new JSONObject();
          vertObj.put(JsonKeys.label.name(), vertex.getLocalID());
          vertObj.put(JsonKeys.id.name(), vertex.getID());
          vertObj.put(JsonKeys.nodeType.name(), vertex.getNodeType().name());

          List<Vertex> nodesWithSemTypesCovered = new ArrayList<Vertex>();
          int height = getHeight(vertex, nodesWithSemTypesCovered, treeClone);
          if (height >= maxTreeHeight) {
            maxTreeHeight = height;
          }

          vertObj.put(JsonKeys.height.name(), height);
          JSONArray hNodeIdsCoveredByVertex = new JSONArray();
          for (Vertex v : nodesWithSemTypesCovered)
            hNodeIdsCoveredByVertex.put(v.getSemanticType().getHNodeId());
          vertObj.put(JsonKeys.hNodesCovered.name(), hNodeIdsCoveredByVertex);

          // Add the semantic type information if required.
          if (vertex.getSemanticType() != null) {
            SemanticType type = vertex.getSemanticType();
            vertObj.put(JsonKeys.hNodeId.name(), type.getHNodeId());
            hNodeIdsAdded.add(type.getHNodeId());

            if (vertex.getNodeType() == NodeType.Class) {
              if (type.isPartOfKey()) {
                vertObj.put(JsonKeys.label.name(), vertex.getLocalID() + "*");
              }

              // Add the holder vertex object and the link that
              // attaches nodes to the columns
              JSONObject vertObj_holder = new JSONObject();
              vertObj_holder.put(JsonKeys.label.name(), JsonValues.key.name());
              vertObj_holder.put(JsonKeys.id.name(), vertex.getID() + "_holder");
              vertObj_holder.put(JsonKeys.nodeType.name(), NodeType.DataProperty.name());
              vertObj_holder.put(JsonKeys.hNodeId.name(), type.getHNodeId());

              JSONArray hNodeIdsCoveredByVertex_holder = new JSONArray();
              hNodeIdsCoveredByVertex_holder.put(vertex.getSemanticType().getHNodeId());
              vertObj_holder.put(JsonKeys.hNodesCovered.name(), hNodeIdsCoveredByVertex_holder);
              vertObj_holder.put(JsonKeys.height.name(), 0);
              vertArr.put(vertObj_holder);

              nodesIndexcounter++;

              // Add the holder link
              JSONObject linkObj = new JSONObject();
              linkObj.put(JsonKeys.source.name(), nodesIndexcounter);
              linkObj.put(JsonKeys.target.name(), nodesIndexcounter - 1);
              linkObj.put(JsonKeys.label.name(), JsonValues.key.name());
              linkObj.put(JsonKeys.id.name(), "");
              linksArr.put(linkObj);
            }
          }

          vertArr.put(vertObj);
          verticesIndex.put(vertex, nodesIndexcounter++);
        }

        /** * Add the links ** */
        Set<LabeledWeightedEdge> edges = tree.edgeSet();
        for (LabeledWeightedEdge edge : edges) {
          Vertex source = edge.getSource();
          Integer sourceIndex = verticesIndex.get(source);
          Vertex target = edge.getTarget();
          Integer targetIndex = verticesIndex.get(target);
          Set<LabeledWeightedEdge> outEdges = tree.outgoingEdgesOf(target);

          if (sourceIndex == null || targetIndex == null) {
            logger.error("Edge vertex index not found!");
            continue;
          }

          JSONObject linkObj = new JSONObject();
          linkObj.put(JsonKeys.source.name(), sourceIndex);
          linkObj.put(JsonKeys.target.name(), targetIndex);
          linkObj.put(JsonKeys.sourceNodeId.name(), source.getID());
          linkObj.put(JsonKeys.targetNodeId.name(), target.getID());
          linkObj.put(JsonKeys.label.name(), edge.getLocalLabel());
          linkObj.put(JsonKeys.id.name(), edge.getID() + "");
          linkObj.put(JsonKeys.linkStatus.name(), edge.getLinkStatus().name());

          if (target.getSemanticType() != null && outEdges.isEmpty()) {
            linkObj.put(JsonKeys.linkType.name(), JsonValues.holderLink.name());
            if (target.getSemanticType().isPartOfKey())
              linkObj.put(JsonKeys.label.name(), edge.getLocalLabel() + "*");
          }

          linksArr.put(linkObj);

          if (source.getNodeType() == NodeType.Class && target.getNodeType() == NodeType.Class) {
            linkObj.put(JsonKeys.linkType.name(), JsonValues.objPropertyLink.name());
          }
        }
      }

      // Add the vertices for the columns that were not in Steiner tree
      hNodeIdList.removeAll(hNodeIdsAdded);
      for (String hNodeId : hNodeIdList) {
        JSONObject vertObj = new JSONObject();
        vertObj.put(JsonKeys.id.name(), hNodeId);
        vertObj.put(JsonKeys.hNodeId.name(), hNodeId);
        vertObj.put(JsonKeys.nodeType.name(), JsonValues.Unassigned.name());
        vertArr.put(vertObj);
        vertObj.put(JsonKeys.height.name(), 0);
        JSONArray hNodeIdsCoveredByVertex = new JSONArray();
        hNodeIdsCoveredByVertex.put(hNodeId);
        vertObj.put(JsonKeys.hNodesCovered.name(), hNodeIdsCoveredByVertex);
      }

      topObj.put(JsonKeys.maxTreeHeight.name(), maxTreeHeight);
      topObj.put(JsonKeys.nodes.name(), vertArr);
      topObj.put(JsonKeys.links.name(), linksArr);

      pw.write(topObj.toString(4));
    } catch (JSONException e) {
      logger.error("Error occured while writing JSON!", e);
    }
  }
  public static void step9() throws IOException {
    ADW pipeLine = new ADW();

    double similarityThreshold = 0.8;

    File logFile = new File("step9-output-combineLog.txt");
    PrintStream outputPrintStream = new PrintStream(logFile);
    System.setOut(outputPrintStream);

    HashMap<String, Integer> allPhrases = new HashMap<String, Integer>(); // all
    // salient
    // S/P/O
    HashMap<String, Integer> allPhrases1 = new HashMap<String, Integer>();
    HashMap<String, String> allPhrases2forContributor = new HashMap<String, String>();
    HashMap<String, String> allPhrases2forContributorTriple = new HashMap<String, String>();
    // HashMap<String,String> hashMapReverse = new HashMap<String,String>();

    FileReader reader = new FileReader("step8-out-PyramidForCombination.txt");
    BufferedReader br = new BufferedReader(reader);
    String str = null;
    String nextStr = null;

    str = br.readLine();
    while (str != null) {
      if (str.startsWith("FROM")) {
        final DirectedWeightedMultigraph<String, RelationshipEdge> g =
            new DirectedWeightedMultigraph<String, RelationshipEdge>(RelationshipEdge.class);

        while ((str = br.readLine()) != null && !str.startsWith("FROM")) {
          String text = str;
          String[] splited = text.split("&");
          String twoPhrases = splited[3];

          String text1 = twoPhrases;
          String[] splited1 = text.split("\"");
          String triple1 = "*"; // for the output
          for (String iterator1 : splited1) {
            triple1 = triple1.concat(" " + iterator1);
          }
          triple1 = triple1.replace("* ", "");
          g.addVertex(twoPhrases);
        }

        for (String vertexIterator1 : g.vertexSet()) {
          // g.removeVertex(vertexIterator1);

          for (String vertexIterator2 : g.vertexSet()) {
            if (!vertexIterator2.equals(vertexIterator1)) {
              if (vertexIterator1.contains(vertexIterator2)
                  || vertexIterator2.contains(vertexIterator1)) {
                System.setOut(outputPrintStream);
                System.out.println(
                    "&"
                        + vertexIterator1
                        + "&"
                        + "   "
                        + "&"
                        + vertexIterator2
                        + "&"
                        + "   "
                        + "&"
                        + 1
                        + "&");
              } else {
                LexicalItemType text1Type = LexicalItemType.SURFACE;
                LexicalItemType text2Type = LexicalItemType.SURFACE;

                // measure for comparing semantic signatures
                SignatureComparison measure = new WeightedOverlap();

                // calculate the similarity of text1 and text2
                double similarity =
                    pipeLine.getPairSimilarity(
                        vertexIterator1,
                        vertexIterator2,
                        DisambiguationMethod.ALIGNMENT_BASED,
                        measure,
                        text1Type,
                        text2Type);
                if (similarity >= similarityThreshold) {
                  System.setOut(outputPrintStream);
                  System.out.println(
                      "&"
                          + vertexIterator1
                          + "&"
                          + "   "
                          + "&"
                          + vertexIterator2
                          + "&"
                          + "   "
                          + "&"
                          + similarity
                          + "&");
                }
              }
            } // inner for
          } // if
        } // outer for
      }
    }

    br.close();
  }
 public void testCornerCases() {
   DirectedWeightedMultigraph<Integer, DefaultWeightedEdge> simple =
       new DirectedWeightedMultigraph<>(DefaultWeightedEdge.class);
   simple.addVertex(0);
   simple.addVertex(1);
   DefaultWeightedEdge e = simple.addEdge(0, 1);
   try {
     new EdmondsKarpMFImpl<Integer, DefaultWeightedEdge>(null);
     fail();
   } catch (NullPointerException ex) {
   }
   try {
     new EdmondsKarpMFImpl<>(simple, -0.1);
     fail();
   } catch (IllegalArgumentException ex) {
   }
   try {
     simple.setEdgeWeight(e, -1.0);
     new EdmondsKarpMFImpl<>(simple);
     fail();
   } catch (IllegalArgumentException ex) {
   }
   try {
     simple.setEdgeWeight(e, 1.0);
     MaximumFlowAlgorithm<Integer, DefaultWeightedEdge> solver = new EdmondsKarpMFImpl<>(simple);
     Map<DefaultWeightedEdge, Double> flow = solver.buildMaximumFlow(0, 1).getFlow();
     flow.put(e, 25.0);
     fail();
   } catch (UnsupportedOperationException ex) {
   }
   try {
     MaximumFlowAlgorithm<Integer, DefaultWeightedEdge> solver = new EdmondsKarpMFImpl<>(simple);
     solver.buildMaximumFlow(2, 0);
     fail();
   } catch (IllegalArgumentException ex) {
   }
   try {
     MaximumFlowAlgorithm<Integer, DefaultWeightedEdge> solver = new EdmondsKarpMFImpl<>(simple);
     solver.buildMaximumFlow(1, 2);
     fail();
   } catch (IllegalArgumentException ex) {
   }
   try {
     MaximumFlowAlgorithm<Integer, DefaultWeightedEdge> solver = new EdmondsKarpMFImpl<>(simple);
     solver.buildMaximumFlow(0, 0);
     fail();
   } catch (IllegalArgumentException ex) {
   }
   try {
     MaximumFlowAlgorithm<Integer, DefaultWeightedEdge> solver = new EdmondsKarpMFImpl<>(simple);
     solver.buildMaximumFlow(null, 0);
     fail();
   } catch (IllegalArgumentException ex) {
   }
   try {
     MaximumFlowAlgorithm<Integer, DefaultWeightedEdge> solver = new EdmondsKarpMFImpl<>(simple);
     solver.buildMaximumFlow(0, null);
     fail();
   } catch (IllegalArgumentException ex) {
   }
 }
Beispiel #5
0
  private static DirectedWeightedMultigraph<Node, LabeledLink> buildGraphsFromStatements2(
      List<Statement> statements) {

    if (statements == null || statements.size() == 0) return null;

    DirectedWeightedMultigraph<Node, LabeledLink> graph =
        new DirectedWeightedMultigraph<Node, LabeledLink>(LabeledLink.class);

    // Assumption: there is only one rdf:type for each URI
    HashMap<String, Node> uri2Classes = new HashMap<String, Node>();
    for (Statement st : statements) {

      String subjStr = st.getSubject();
      String predicateStr = st.getPredicate();
      String objStr = st.getObject();

      subjStr = getUri(subjStr);
      predicateStr = getUri(predicateStr);
      objStr = getUri(objStr);

      if (predicateStr.equalsIgnoreCase(typePredicate)) {

        Node classNode = new InternalNode(objStr, new Label(objStr));
        uri2Classes.put(subjStr, classNode);
        graph.addVertex(classNode);
      }
    }

    //		int countOfLiterals = 0;
    String id;
    for (Statement st : statements) {

      String subjStr = st.getSubject();
      String predicateStr = st.getPredicate();
      String objStr = st.getObject();

      subjStr = getUri(subjStr);
      predicateStr = getUri(predicateStr);
      objStr = getUri(objStr);

      if (predicateStr.equalsIgnoreCase(typePredicate)) continue;

      Node subj = uri2Classes.get(subjStr);
      if (subj == null) {
        subj = new InternalNode(subjStr, new Label(subjStr));
        graph.addVertex(subj);
      }

      Node obj = uri2Classes.get(objStr);
      if (obj == null) {
        if (objStr.startsWith(attPrefix)) {
          id = new RandomGUID().toString();
          obj = new ColumnNode(id, objStr, objStr, null, null);
          SemanticType semanticType =
              new SemanticType(
                  ((ColumnNode) obj).getHNodeId(),
                  new Label(predicateStr),
                  subj.getLabel(),
                  Origin.User,
                  1.0,
                  false);
          ((ColumnNode) obj).setUserSelectedSemanticType(semanticType);

        } else if (objStr.indexOf(":") == -1 && objStr.indexOf("\"") != -1) {
          //					String literalId = "lit:" + serviceId + "_l" + String.valueOf(countOfLiterals);
          obj = new LiteralNode(objStr, objStr, null);
          //					countOfLiterals ++;
        } else obj = new InternalNode(objStr, new Label(objStr));

        graph.addVertex(obj);
      }

      LabeledLink e;
      if (obj instanceof InternalNode)
        e =
            new ObjectPropertyLink(
                LinkIdFactory.getLinkId(predicateStr, subj.getId(), obj.getId()),
                new Label(predicateStr),
                ObjectPropertyType.None);
      else
        e =
            new DataPropertyLink(
                LinkIdFactory.getLinkId(predicateStr, subj.getId(), obj.getId()),
                new Label(predicateStr));
      graph.addEdge(subj, obj, e);
    }

    return graph;
  }
  @Override
  public void generateJson(String prefix, PrintWriter pw, VWorkspace vWorkspace) {
    VWorksheet vWorksheet = vWorkspace.getViewFactory().getVWorksheetByWorksheetId(worksheetId);
    List<String> hNodeIdList = new ArrayList<String>();
    List<HNodePath> columns = vWorksheet.getColumns();
    for (HNodePath path : columns) hNodeIdList.add(path.getLeaf().getId());
    String alignmentId =
        AlignmentManager.Instance()
            .constructAlignmentId(vWorkspace.getWorkspace().getId(), vWorksheet.getWorksheetId());

    JSONObject topObj = new JSONObject();
    try {
      topObj.put(
          GenericJsonKeys.updateType.name(), AlignmentSVGVisualizationUpdate.class.getSimpleName());
      topObj.put(JsonKeys.alignmentId.name(), alignmentId);
      topObj.put(JsonKeys.worksheetId.name(), worksheetId);

      // Using Mohsen's GraphUtils method for graph traversal
      HashMap<Node, Integer> nodeHeightsMap = GraphUtil.levelingCyclicGraph(alignmentGraph);
      HashMap<Node, Set<ColumnNode>> nodeCoverage =
          GraphUtil.getNodesCoverage(alignmentGraph, nodeHeightsMap);
      /** Identify the max height * */
      int maxTreeHeight = 0;
      for (Node node : nodeHeightsMap.keySet()) {
        if (nodeHeightsMap.get(node) >= maxTreeHeight) {
          maxTreeHeight = nodeHeightsMap.get(node);
        }
      }

      /** * Add the nodes and the links from the Steiner tree ** */
      List<String> hNodeIdsAdded = new ArrayList<String>();
      JSONArray nodesArr = new JSONArray();
      JSONArray linksArr = new JSONArray();

      if (alignmentGraph != null && alignmentGraph.vertexSet().size() != 0) {
        /** Add the nodes * */
        Set<Node> nodes = alignmentGraph.vertexSet();
        HashMap<Node, Integer> verticesIndex = new HashMap<Node, Integer>();
        int nodesIndexcounter = 0;
        for (Node node : nodes) {
          /** Get info about the nodes that this node covers or sits above * */
          int height = maxTreeHeight - nodeHeightsMap.get(node);

          /** Add the hnode ids of the columns that this vertex covers * */
          JSONArray hNodeIdsCoveredByVertex = new JSONArray();
          for (Node v : nodeCoverage.get(node)) {
            if (v instanceof ColumnNode) {
              ColumnNode cNode = (ColumnNode) v;
              hNodeIdsCoveredByVertex.put(cNode.getHNodeId());
            }
          }

          String hNodeId = "";

          /** Add the semantic type information * */
          if (node instanceof ColumnNode) {
            ColumnNode cNode = (ColumnNode) node;
            hNodeId = cNode.getHNodeId();
            hNodeIdsAdded.add(cNode.getHNodeId());
          }
          JSONObject nodeObj =
              getNodeJsonObject(
                  node.getLocalId(),
                  node.getId(),
                  node.getType().name(),
                  height,
                  hNodeIdsCoveredByVertex,
                  hNodeId);
          nodesArr.put(nodeObj);
          verticesIndex.put(node, nodesIndexcounter++);
        }

        /** * Add the links ** */
        Set<Link> links = alignmentGraph.edgeSet();
        for (Link link : links) {
          Node source = link.getSource();
          Integer sourceIndex = verticesIndex.get(source);
          Node target = link.getTarget();
          Integer targetIndex = verticesIndex.get(target);
          Set<Link> outEdges = alignmentGraph.outgoingEdgesOf(target);

          if (sourceIndex == null || targetIndex == null) {
            logger.error("Edge vertex index not found!");
            continue;
          }

          JSONObject linkObj = new JSONObject();
          linkObj.put(JsonKeys.source.name(), sourceIndex);
          linkObj.put(JsonKeys.target.name(), targetIndex);
          linkObj.put(JsonKeys.sourceNodeId.name(), source.getId());
          linkObj.put(JsonKeys.targetNodeId.name(), target.getId());

          linkObj.put(JsonKeys.label.name(), link.getLabel().getLocalName());
          linkObj.put(JsonKeys.id.name(), link.getId() + "");
          linkObj.put(JsonKeys.linkStatus.name(), link.getStatus().name());
          linkObj.put(JsonKeys.linkUri.name(), link.getLabel().getUri());

          if (target.getType() == NodeType.ColumnNode && outEdges.isEmpty()) {
            linkObj.put(JsonKeys.linkType.name(), JsonValues.holderLink.name());
            if (link.getKeyType() == LinkKeyInfo.PartOfKey)
              linkObj.put(JsonKeys.label.name(), link.getLabel().getLocalName() + "*");
          }

          linksArr.put(linkObj);

          if (link.getType() == LinkType.ClassInstanceLink
              && link.getKeyType() == LinkKeyInfo.PartOfKey
              && target instanceof ColumnNode) {
            ColumnNode cNode = (ColumnNode) target;
            // Add the holder vertex object and the link that attaches nodes to the columns
            JSONArray hNodeIdsCoveredByVertex_holder = new JSONArray();
            hNodeIdsCoveredByVertex_holder.put(cNode.getHNodeId());

            JSONObject vertObj_holder =
                getNodeJsonObject(
                    JsonValues.key.name(),
                    source.getId() + "_holder",
                    NodeType.ColumnNode.name(),
                    0,
                    hNodeIdsCoveredByVertex_holder,
                    cNode.getHNodeId());
            nodesArr.put(vertObj_holder);
            nodesIndexcounter++;

            // Add the holder link
            JSONObject linkObj_holder =
                getLinkJsonObject(
                    JsonValues.key.name(),
                    "",
                    nodesIndexcounter,
                    nodesIndexcounter - 1,
                    "",
                    "",
                    "",
                    "");
            linksArr.put(linkObj_holder);
          }

          if (link.getType() == LinkType.DataPropertyOfColumnLink) {
            DataPropertyOfColumnLink dpLink = (DataPropertyOfColumnLink) link;
            String startHNodeId = dpLink.getSpecializedColumnHNodeId();

            // Get height of the class instance node
            int height = maxTreeHeight - nodeHeightsMap.get(link.getSource());

            // Add 2 more holder nodes
            // Start node
            JSONArray hNodeIdsCoveredByVertex_holder = new JSONArray();
            hNodeIdsCoveredByVertex_holder.put(startHNodeId);
            JSONObject startNode =
                getNodeJsonObject(
                    "",
                    source.getId() + "_holder",
                    JsonValues.DataPropertyOfColumnHolder.name(),
                    height - 0.35,
                    hNodeIdsCoveredByVertex_holder,
                    startHNodeId);
            nodesArr.put(startNode);

            nodesIndexcounter++;

            // End node
            String endHNodeId = ((ColumnNode) link.getTarget()).getHNodeId();
            JSONArray hNodeIdsCoveredByVertex_holder_2 = new JSONArray();
            hNodeIdsCoveredByVertex_holder_2.put(endHNodeId);
            JSONObject endNode =
                getNodeJsonObject(
                    "",
                    target.getId() + "_holder",
                    JsonValues.DataPropertyOfColumnHolder.name(),
                    height - 0.35,
                    hNodeIdsCoveredByVertex_holder_2,
                    endHNodeId);
            nodesArr.put(endNode);

            nodesIndexcounter++;

            // Add the horizontal link
            JSONObject linkObj_holder =
                getLinkJsonObject(
                    "",
                    "",
                    nodesIndexcounter - 2,
                    nodesIndexcounter - 1,
                    JsonValues.horizontalDataPropertyLink.name(),
                    "",
                    "",
                    "");
            linksArr.put(linkObj_holder);
          } else if (link.getType() == LinkType.ObjectPropertySpecializationLink) {
            ObjectPropertySpecializationLink opLink = (ObjectPropertySpecializationLink) link;
            Link specializedLink = opLink.getSpecializedLink();

            // Get height of the class instance node
            int height = nodeHeightsMap.get(specializedLink.getTarget());

            // Add 2 more holder nodes
            // Start node
            JSONArray hNodeIdsCoveredByVertex_holder = new JSONArray();
            for (Node v : nodeCoverage.get(specializedLink.getTarget())) {
              if (v instanceof ColumnNode) {
                ColumnNode cNode = (ColumnNode) v;
                hNodeIdsCoveredByVertex_holder.put(cNode.getHNodeId());
              }
            }
            JSONObject startNode =
                getNodeJsonObject(
                    "",
                    source.getId() + "_holder",
                    JsonValues.DataPropertyOfColumnHolder.name(),
                    height + 0.65,
                    hNodeIdsCoveredByVertex_holder,
                    "");
            nodesArr.put(startNode);

            nodesIndexcounter++;

            // End node
            String endHNodeId = ((ColumnNode) link.getTarget()).getHNodeId();
            JSONArray hNodeIdsCoveredByVertex_holder_2 = new JSONArray();
            hNodeIdsCoveredByVertex_holder_2.put(endHNodeId);
            JSONObject endNode =
                getNodeJsonObject(
                    "",
                    target.getId() + "_holder",
                    JsonValues.DataPropertyOfColumnHolder.name(),
                    height + 0.65,
                    hNodeIdsCoveredByVertex_holder_2,
                    endHNodeId);
            nodesArr.put(endNode);

            nodesIndexcounter++;

            // Add the horizontal link
            JSONObject linkObj_holder =
                getLinkJsonObject(
                    "",
                    "",
                    nodesIndexcounter - 2,
                    nodesIndexcounter - 1,
                    JsonValues.horizontalDataPropertyLink.name(),
                    "",
                    "",
                    "");
            linksArr.put(linkObj_holder);
          }

          linkObj.put(JsonKeys.linkType.name(), link.getType());
        }
      }

      // Add the vertices for the columns that were not in Steiner tree
      hNodeIdList.removeAll(hNodeIdsAdded);
      for (String hNodeId : hNodeIdList) {
        JSONArray hNodeIdsCoveredByVertex = new JSONArray();
        hNodeIdsCoveredByVertex.put(hNodeId);
        JSONObject vertObj =
            getNodeJsonObject(
                "", hNodeId, JsonValues.Unassigned.name(), 0, hNodeIdsCoveredByVertex, hNodeId);
        nodesArr.put(vertObj);
      }

      topObj.put(JsonKeys.maxTreeHeight.name(), maxTreeHeight);
      topObj.put(JsonKeys.nodes.name(), nodesArr);
      topObj.put(JsonKeys.links.name(), linksArr);

      pw.write(topObj.toString());
    } catch (JSONException e) {
      logger.error("Error occured while writing JSON!", e);
    }
  }
  @Override
  public UpdateContainer doIt(Workspace workspace) throws CommandException {
    final OntologyManager ontMgr = workspace.getOntologyManager();
    Set<LabeledLink> properties = new HashSet<>();

    logger.debug(
        "GetPropertiesCommand:"
            + propertiesRange
            + ":"
            + classURI
            + ","
            + domainURI
            + ", "
            + rangeURI);

    if (propertiesRange == INTERNAL_PROP_RANGE.allObjectProperties) {
      HashMap<String, Label> linkList = ontMgr.getObjectProperties();
      if (linkList != null) {
        for (Label label : linkList.values()) {
          properties.add(new DataPropertyLink(label.getUri(), label));
        }
      }
    } else if (propertiesRange == INTERNAL_PROP_RANGE.allDataProperties) {
      HashMap<String, Label> linkList = ontMgr.getDataProperties();
      for (Label label : linkList.values()) {
        properties.add(new DataPropertyLink(label.getUri(), label));
      }
    } else if (propertiesRange == INTERNAL_PROP_RANGE.propertiesWithDomainRange) {
      Map<String, Label> linkList =
          ontMgr.getObjectPropertiesByDomainRange(domainURI, rangeURI, true);
      for (Label label : linkList.values()) {
        properties.add(new DataPropertyLink(label.getUri(), label));
      }
    } else if (propertiesRange == INTERNAL_PROP_RANGE.dataPropertiesForClass) {
      Map<String, Label> linkList = ontMgr.getDataPropertiesByDomain(classURI, true);
      for (Label label : linkList.values()) {
        properties.add(new DataPropertyLink(label.getUri(), label));
      }
    } else if (propertiesRange == INTERNAL_PROP_RANGE.existingProperties) {
      Alignment alignment =
          AlignmentManager.Instance()
              .getAlignmentOrCreateIt(workspace.getId(), worksheetId, ontMgr);
      Set<String> steinerTreeNodeIds = new HashSet<String>();
      if (alignment != null && !alignment.isEmpty()) {
        DirectedWeightedMultigraph<Node, LabeledLink> steinerTree = alignment.getSteinerTree();
        for (Node node : steinerTree.vertexSet()) {
          if (node.getType() == NodeType.InternalNode) {
            steinerTreeNodeIds.add(node.getId());
          }
        }

        List<LabeledLink> specializedLinks = new ArrayList<LabeledLink>();
        Set<LabeledLink> temp = null;
        temp = alignment.getLinksByType(LinkType.DataPropertyLink);
        if (temp != null) specializedLinks.addAll(temp);
        for (LabeledLink link : steinerTree.edgeSet())
          if (link instanceof ObjectPropertyLink) specializedLinks.add(link);

        // Store the data property links for specialized edge link options
        properties.addAll(specializedLinks);
      }
    }

    logger.debug("Got back " + properties.size() + " results");
    final Set<LabeledLink> finalProperties = properties;

    UpdateContainer upd =
        new UpdateContainer(
            new AbstractUpdate() {
              @Override
              public void generateJson(String prefix, PrintWriter pw, VWorkspace vWorkspace) {
                JSONObject obj = new JSONObject();
                JSONArray resultArray = new JSONArray();

                try {
                  obj.put(JsonKeys.updateType.name(), "PropertyList");

                  for (LabeledLink link : finalProperties) {
                    Label linkLabel = link.getLabel();
                    String edgeLabelStr = linkLabel.getDisplayName();
                    JSONObject edgeObj = new JSONObject();
                    if (linkLabel.getUri() != null
                        && linkLabel.getNs() != null
                        && linkLabel.getUri().equalsIgnoreCase(linkLabel.getNs())) {
                      edgeLabelStr = linkLabel.getUri();
                    }

                    edgeObj.put(JsonKeys.label.name(), edgeLabelStr);
                    edgeObj.put(JsonKeys.uri.name(), linkLabel.getUri());
                    edgeObj.put(JsonKeys.id.name(), link.getId());
                    resultArray.put(edgeObj);
                  }

                  obj.put(JsonKeys.properties.name(), resultArray);
                  pw.println(obj.toString());
                } catch (Exception e) {
                  logger.error("Exception:", e);
                  e.printStackTrace();
                }
              }
            });
    return upd;
  }