Package edu.isi.karma.modeling.alignment

Source Code of edu.isi.karma.modeling.alignment.GraphBuilder

/*******************************************************************************
* Copyright 2012 University of Southern California
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This code was developed by the Information Integration Group as part
* of the Karma project at the Information Sciences Institute of the
* University of Southern California.  For more information, publications,
* and related projects, please see: http://www.isi.edu/integration
******************************************************************************/
package edu.isi.karma.modeling.alignment;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.jgrapht.graph.DirectedWeightedMultigraph;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import edu.isi.karma.config.ModelingConfiguration;
import edu.isi.karma.modeling.ModelingParams;
import edu.isi.karma.modeling.Namespaces;
import edu.isi.karma.modeling.Prefixes;
import edu.isi.karma.modeling.Uris;
import edu.isi.karma.modeling.alignment.learner.SemanticTypeMapping;
import edu.isi.karma.modeling.ontology.OntologyManager;
import edu.isi.karma.modeling.research.Params;
import edu.isi.karma.rep.alignment.ColumnNode;
import edu.isi.karma.rep.alignment.CompactLink;
import edu.isi.karma.rep.alignment.CompactObjectPropertyLink;
import edu.isi.karma.rep.alignment.CompactSubClassLink;
import edu.isi.karma.rep.alignment.DefaultLink;
import edu.isi.karma.rep.alignment.InternalNode;
import edu.isi.karma.rep.alignment.Label;
import edu.isi.karma.rep.alignment.LabeledLink;
import edu.isi.karma.rep.alignment.LinkPriorityComparator;
import edu.isi.karma.rep.alignment.LinkStatus;
import edu.isi.karma.rep.alignment.LinkType;
import edu.isi.karma.rep.alignment.Node;
import edu.isi.karma.rep.alignment.NodeType;
import edu.isi.karma.rep.alignment.ObjectPropertyLink;
import edu.isi.karma.rep.alignment.ObjectPropertyType;
import edu.isi.karma.rep.alignment.SubClassLink;
import edu.isi.karma.util.EncodingDetector;

public class GraphBuilder {

  static Logger logger = LoggerFactory.getLogger(GraphBuilder.class);

  protected DirectedWeightedMultigraph<Node, DefaultLink> graph;
  protected OntologyManager ontologyManager;
 
  private NodeIdFactory nodeIdFactory;
 
  private HashSet<String> visitedSourceTargetPairs;

  // HashMaps
 
  private HashMap<String, Node> idToNodeMap;
  private HashMap<String, LabeledLink> idToLinkMap;

  private HashMap<String, Set<Node>> uriToNodesMap;
  private HashMap<String, Set<LabeledLink>> uriToLinksMap;
 
  private HashMap<NodeType, Set<Node>> typeToNodesMap;
  private HashMap<LinkType, Set<LabeledLink>> typeToLinksMap;

  private HashMap<LinkStatus, Set<LabeledLink>> statusToLinksMap;
 
  private HashMap<String, Set<String>> uriClosure;

  private Set<Node> forcedNodes;
 
  // To be used in matching semantic types with graph nodes
  private HashSet<String> modelIds;
  private HashMap<String, Integer> linkCountMap;
  private HashMap<String, Integer> nodeDataPropertyCount; // nodeId + dataPropertyUri --> count
  private HashMap<String, Set<Node>> nodeDataProperties; // nodeId + dataPropertyUri --> ColumnNode
  private HashMap<String, Set<SemanticTypeMapping>> semanticTypeMatches; // nodeUri + dataPropertyUri --> SemanticType Mapping
  private int numberOfModelLinks = 0;

  // Constructor
 
  public GraphBuilder(OntologyManager ontologyManager, boolean addThingNode) {
   
    this.ontologyManager = ontologyManager;
    this.nodeIdFactory = new NodeIdFactory();

    this.idToNodeMap = new HashMap<String, Node>();
    this.idToLinkMap = new HashMap<String, LabeledLink>();
    this.uriToNodesMap = new HashMap<String, Set<Node>>();
    this.uriToLinksMap = new HashMap<String, Set<LabeledLink>>();
    this.typeToNodesMap = new HashMap<NodeType, Set<Node>>();
    this.typeToLinksMap = new HashMap<LinkType, Set<LabeledLink>>();
    this.statusToLinksMap = new HashMap<LinkStatus, Set<LabeledLink>>();
   
    this.uriClosure = new HashMap<String, Set<String>>();

    this.graph = new DirectedWeightedMultigraph<Node, DefaultLink>(DefaultLink.class);
   
    this.visitedSourceTargetPairs = new HashSet<String>();
     
    this.modelIds = new HashSet<String>();
    this.linkCountMap = new HashMap<String, Integer>();
    this.nodeDataPropertyCount = new HashMap<String, Integer>();
    this.semanticTypeMatches = new HashMap<String, Set<SemanticTypeMapping>>();
   
    this.nodeDataProperties= new HashMap<String,Set<Node>>();
   
    this.forcedNodes = new HashSet<Node>();
    if (addThingNode)
      this.initialGraph();
   
  }
 
  public GraphBuilder(OntologyManager ontologyManager, DirectedWeightedMultigraph<Node, DefaultLink> graph) {
   
    this(ontologyManager, false);
    if (graph == null)
      return;
   
    for (Node node : graph.vertexSet()) {
     
      this.addNode(node);
      // building NodeIdFactory
      if (node.getLabel() != null) {
        nodeIdFactory.getNodeId(node.getUri());
      }           
    }
   
    Node source;
    Node target;
   
    for (DefaultLink link : graph.edgeSet()) {
     
      source = link.getSource();
      target = link.getTarget();
     
      this.addLink(source, target, link);
    }
   
    logger.debug("graph has been loaded.");
  }
 
  public NodeIdFactory getNodeIdFactory() {
    return nodeIdFactory;
  }

  public OntologyManager getOntologyManager() {
    return this.ontologyManager;
  }
 
  public DirectedWeightedMultigraph<Node, DefaultLink> getGraph() {
    return this.graph;
  }
 
  public void setGraph(DirectedWeightedMultigraph<Node, DefaultLink> graph) {
    this.graph = graph;
  }
 
  public HashMap<String, Node> getIdToNodeMap() {
    return idToNodeMap;
  }

  public HashMap<String, LabeledLink> getIdToLinkMap() {
    return idToLinkMap;
  }

  public HashMap<String, Set<Node>> getUriToNodesMap() {
    return uriToNodesMap;
  }

  public HashMap<String, Set<LabeledLink>> getUriToLinksMap() {
    return uriToLinksMap;
  }

  public HashMap<NodeType, Set<Node>> getTypeToNodesMap() {
    return typeToNodesMap;
  }

  public HashMap<LinkType, Set<LabeledLink>> getTypeToLinksMap() {
    return typeToLinksMap;
  }

  public HashMap<LinkStatus, Set<LabeledLink>> getStatusToLinksMap() {
    return statusToLinksMap;
  }
 
  public Set<String> getModelIds() {
    return Collections.unmodifiableSet(modelIds);
  }

  public HashMap<String, Integer> getLinkCountMap() {
    return linkCountMap;
  }
 
  public HashMap<String, Integer> getNodeDataPropertyCount() {
    return nodeDataPropertyCount;
  }

  public HashMap<String, Set<SemanticTypeMapping>> getSemanticTypeMatches() {
    return semanticTypeMatches;
  }

  public int getNumberOfModelLinks() {
    return numberOfModelLinks;
  }

  public HashMap<String, Set<Node>> getNodeDataProperties() {
    return nodeDataProperties;
  }

  public void resetOntologyMaps() {
    String[] currentUris = this.uriClosure.keySet().toArray(new String[0]);
    this.uriClosure.clear();
    for (String uri : currentUris)
      computeUriClosure(uri);
  }

  public boolean addNodeAndUpdate(Node node) {
    return this.addNodeAndUpdate(node, null);
  }
 
  public boolean addNodeAndUpdate(Node node, Set<Node> addedNodes) {
   
    boolean result = addNode(node);
    if (!result || ModelingConfiguration.getManualAlignment())
      return result;
     
    if (addedNodes == null)
      addedNodes = new HashSet<Node>();
    addedNodes.add(node);
    if (node instanceof InternalNode)
      addClosureAndUpdateLinks((InternalNode)node, addedNodes);
   
    return result;
  }
 
  public InternalNode copyNodeAndUpdate(Node node, boolean copyLinksToColumnNodes) {
    InternalNode copyNode = null;
    if (node instanceof InternalNode) {
      copyNode = this.copyNode((InternalNode)node, copyLinksToColumnNodes);
    } else {
      logger.error("only can copy an internal node");
      return null;
    }
    return copyNode;
  }
 
  private void addClosureAndUpdateLinks(InternalNode node, Set<Node> addedNodes) {
   
    if (addedNodes == null) addedNodes = new HashSet<Node>();
    if (node instanceof InternalNode) {

      long start = System.currentTimeMillis();
      float elapsedTimeSec;

      addedNodes.add(node);
     
      if (ModelingConfiguration.getNodeClosure()) {
        addNodeClosure(node, addedNodes);
      }
     
      long addNodesClosure = System.currentTimeMillis();
      elapsedTimeSec = (addNodesClosure - start)/1000F;
      logger.debug("time to add nodes closure: " + elapsedTimeSec);

      updateLinks();
     
      // if we consider the set of current nodes as S1 and the set of new added nodes as S2:
      // (*) the direction of all the subclass links between S1 and S2 is from S2 to S1
      //    This is because superclasses of all the nodes in S1 are already added to the graph.
      // (*) the direction of all the object property links between S1 and S2 is from S1 to S2
      //    This is because all the nodes that are reachable from S1 are added to the graph before adding new nodes in S2.
      long updateLinks = System.currentTimeMillis();
      elapsedTimeSec = (updateLinks - addNodesClosure)/1000F;
      logger.debug("time to update links of the graph: " + elapsedTimeSec);
     
//      updateLinksFromThing();
     
//      long updateLinksFromThing = System.currentTimeMillis();
//      elapsedTimeSec = (updateLinksFromThing - updateLinks)/1000F;
//      logger.debug("time to update links to Thing (root): " + elapsedTimeSec);

      logger.debug("total number of nodes in graph: " + this.graph.vertexSet().size());
      logger.debug("total number of links in graph: " + this.graph.edgeSet().size());

    }
   
  }
 
  public void addClosureAndUpdateLinks(Set<InternalNode> internalNodes, Set<Node> addedNodes) {
   
    logger.debug("<enter");
    if (addedNodes == null) addedNodes = new HashSet<Node>();

    long start = System.currentTimeMillis();
    float elapsedTimeSec;

    if (internalNodes != null) {
      Node[] nodes = internalNodes.toArray(new Node[0]);
      for (Node node : nodes)
        if (this.idToNodeMap.containsKey(node.getId()))
          addNodeClosure(node, addedNodes);
    }

    long addNodesClosure = System.currentTimeMillis();
    elapsedTimeSec = (addNodesClosure - start)/1000F;
    logger.debug("time to add nodes closure: " + elapsedTimeSec);

    updateLinks();
   
    long updateLinks = System.currentTimeMillis();
    elapsedTimeSec = (updateLinks - addNodesClosure)/1000F;
    logger.debug("time to update links of the graph: " + elapsedTimeSec);
   
    logger.debug("total number of nodes in graph: " + this.graph.vertexSet().size());
    logger.debug("total number of links in graph: " + this.graph.edgeSet().size());

    logger.debug("exit>");   
  }
 
 
  public boolean addNode(Node node) {
   
    logger.debug("<enter");

    if (node == null) {
      logger.error("The node is null.");
      return false;
    }
   
    if (idToNodeMap.get(node.getId()) != null) {
      logger.error("The node with id=" + node.getId() + " already exists in the graph.");
      return false;
    }
   
    if (node instanceof InternalNode) {
      String uri = node.getUri();
      Label label = this.ontologyManager.getUriLabel(uri);
      if (label == null) {
        logger.error("The resource " + uri + " does not exist in the ontology.");
        return false;
      }
      node.getLabel().setNs(label.getNs());
      node.getLabel().setPrefix(label.getPrefix());
    }
   
    if(node.isForced())
      this.forcedNodes.add(node);
   
    this.graph.addVertex(node);
   
    this.idToNodeMap.put(node.getId(), node);
//    logger.info("Added in idToNodeMap:" + node.getId());
    Set<Node> nodesWithSameUri = uriToNodesMap.get(node.getUri());
    if (nodesWithSameUri == null) {
      nodesWithSameUri = new HashSet<Node>();
      uriToNodesMap.put(node.getUri(), nodesWithSameUri);
    }
    nodesWithSameUri.add(node);
   
    Set<Node> nodesWithSameType = typeToNodesMap.get(node.getType());
    if (nodesWithSameType == null) {
      nodesWithSameType = new HashSet<Node>();
      typeToNodesMap.put(node.getType(), nodesWithSameType);
    }
    nodesWithSameType.add(node);
   
    if (node.getModelIds() != null)
      this.modelIds.addAll(node.getModelIds());
         
    this.uriClosure.put(node.getUri(), null);

    logger.debug("exit>");   
    return true;
  }
 
  public InternalNode copyNode(InternalNode node, boolean copyLinksToColumnNodes) {
   
    if (node == null) {
      logger.error("input node is null");
      return null;
    }
   
    String id = this.nodeIdFactory.getNodeId(node.getUri());
    InternalNode newNode = new InternalNode(id, node.getLabel());
   
    if (!this.addNode(newNode)) {
      logger.error("could not add the new node " + newNode.getId());
      return null;
    }
   
    Node source , target;
    String newId;
    Set<DefaultLink> incomingLinks = this.getGraph().incomingEdgesOf(node);
    if (incomingLinks != null) {
      for (DefaultLink l : incomingLinks) {
        source = l.getSource();
        if (source instanceof ColumnNode) continue;
        target = newNode;
        newId = LinkIdFactory.getLinkId(l.getUri(), source.getId(), target.getId());
        DefaultLink copyLink = l.getCopy(newId);
        this.addLink(source, target, copyLink, l.getWeight());
      }
    }
   
    Set<DefaultLink> outgoingLinks = this.getGraph().outgoingEdgesOf(node);
    if (outgoingLinks != null) {
      for (DefaultLink l : outgoingLinks) {
        source = newNode;
        target = l.getTarget();
        if (!copyLinksToColumnNodes && target instanceof ColumnNode) continue; // skip links to column nodes
        newId = LinkIdFactory.getLinkId(l.getUri(), source.getId(), target.getId());
        DefaultLink copyLink = l.getCopy(newId);
        this.addLink(source, target, copyLink, l.getWeight());
      }
    }
   
    return newNode;

  }
 
  public Set<Node> getForcedNodes() {
    return this.forcedNodes;
  }

  public boolean addLink(Node source, Node target, DefaultLink link, Double weight) {
    if (addLink(source, target, link)) {
      if (weight != null) changeLinkWeight(link, weight);
      return true;
    }
    return false;
  }
 
  public boolean addLink(Node source, Node target, DefaultLink link) {

    logger.debug("<enter");

    if (source == null || target == null || link == null) {
      logger.error("Source, target, and the link cannot be null.");
      return false;
    }
   
    if (this.idToLinkMap.containsKey(link.getId())) {
      logger.warn("The link with id=" + link.getId() + " already exists in the graph");
      return false;
    }
   
    if (!this.idToNodeMap.containsKey(source.getId())) {
      logger.error("The link source " + link.getSource().getId() + " does not exist in the graph");
      return false;
    }

    if (!this.idToNodeMap.containsKey(target.getId())) {
      logger.error("The link target " + link.getTarget().getId() + " does not exist in the graph");
      return false;
    }

    if (link instanceof LabeledLink) {
      String uri = link.getUri();
      Label label = this.ontologyManager.getUriLabel(uri);
      if (label == null) {
        logger.error("The resource " + uri + " does not exist in the ontology.");
        return false;
      }
      ((LabeledLink)link).getLabel().setNs(label.getNs());
      ((LabeledLink)link).getLabel().setPrefix(label.getPrefix());
    }
     
    if (source instanceof InternalNode && target instanceof ColumnNode) {
     
      // remove other incoming links to this column node
      DefaultLink oldIncomingLink = null;
      Set<DefaultLink> incomingLinks = this.getGraph().incomingEdgesOf(target);
      if (incomingLinks != null && incomingLinks.size() == 1) {
        oldIncomingLink = incomingLinks.iterator().next();
      }
      if (oldIncomingLink != null)
        this.removeLink(oldIncomingLink);
    }
     
    this.graph.addEdge(source, target, link);
   
    this.visitedSourceTargetPairs.add(source.getId() + target.getId());
   
    double w = computeWeight(link);
   
    this.graph.setEdgeWeight(link, w);
       
    if (link instanceof CompactLink) {
      logger.debug("exit>");   
      return true;
    }
     
    // update the corresponding lists and hashmaps
    LabeledLink labeledLink = null;
//    if (link instanceof LabeledLink)
    labeledLink = (LabeledLink)link;
   
    this.idToLinkMap.put(labeledLink.getId(), labeledLink);
   
    Set<LabeledLink> linksWithSameUri = uriToLinksMap.get(labeledLink.getUri());
    if (linksWithSameUri == null) {
      linksWithSameUri = new HashSet<LabeledLink>();
      uriToLinksMap.put(labeledLink.getUri(), linksWithSameUri);
    }
    linksWithSameUri.add(labeledLink);
       
    Set<LabeledLink> linksWithSameType = typeToLinksMap.get(labeledLink.getType());
    if (linksWithSameType == null) {
      linksWithSameType = new HashSet<LabeledLink>();
      typeToLinksMap.put(labeledLink.getType(), linksWithSameType);
    }
    linksWithSameType.add(labeledLink);
   
    if (labeledLink.getStatus() != LinkStatus.Normal) {
      Set<LabeledLink> linksWithSameStatus = statusToLinksMap.get(labeledLink.getStatus());
      if (linksWithSameStatus == null) {
        linksWithSameStatus = new HashSet<LabeledLink>();
        statusToLinksMap.put(labeledLink.getStatus(), linksWithSameStatus);
      }
    }

    if (source instanceof InternalNode && target instanceof ColumnNode) {

      ((ColumnNode)target).setDomainNode((InternalNode)source);
      ((ColumnNode)target).setDomainLink(labeledLink);
     
      String key = source.getId() + link.getUri();
      Integer count = this.nodeDataPropertyCount.get(key);
      if (count == null) this.nodeDataPropertyCount.put(key, 1);
      else this.nodeDataPropertyCount.put(key, count.intValue() + 1);
     
      Set<Node> dataPropertyColumnNodes = this.nodeDataProperties.get(key);
      if (dataPropertyColumnNodes == null) {
        dataPropertyColumnNodes = new HashSet<Node>();
        this.nodeDataProperties.put(key, dataPropertyColumnNodes);
      }
      dataPropertyColumnNodes.add(target);
     
      key = source.getUri() + link.getUri();
      Set<SemanticTypeMapping> SemanticTypeMappings = this.semanticTypeMatches.get(key);
      if (SemanticTypeMappings == null) {
        SemanticTypeMappings = new HashSet<SemanticTypeMapping>();
        this.semanticTypeMatches.put(key, SemanticTypeMappings);
      }
      SemanticTypeMappings.add(new SemanticTypeMapping(null, null, (InternalNode)source, labeledLink, (ColumnNode)target));
    }
       
    if (labeledLink.getModelIds() != null) {
      this.modelIds.addAll(labeledLink.getModelIds());
      this.numberOfModelLinks++;
    }
   
    this.updateLinkCountMap(link);
   
    logger.debug("exit>");   
    return true;
  }
 
  private double computeWeight(DefaultLink link) {
    double w = 0.0;
   
    if (link instanceof LabeledLink && ((LabeledLink)link).getStatus() == LinkStatus.PreferredByUI)
      w = ModelingParams.PROPERTY_UI_PREFERRED_WEIGHT;
   
    if (link instanceof LabeledLink &&
        ((LabeledLink)link).getModelIds() != null &&
        !((LabeledLink)link).getModelIds().isEmpty())
      w = ModelingParams.PATTERN_LINK_WEIGHT;

    if (link instanceof LabeledLink && ((LabeledLink)link).getStatus() == LinkStatus.ForcedByUser)
      w = ModelingParams.PROPERTY_USER_PREFERRED_WEIGHT;
   
    if (w != 0.0)
      return w;
   
    if (link instanceof ObjectPropertyLink && ((ObjectPropertyLink)link).getObjectPropertyType() == ObjectPropertyType.Direct)
      w = ModelingParams.PROPERTY_DIRECT_WEIGHT;
    else if (link instanceof CompactObjectPropertyLink && ((CompactObjectPropertyLink)link).getObjectPropertyType() == ObjectPropertyType.Direct)
      w = ModelingParams.PROPERTY_DIRECT_WEIGHT;
    else if (link instanceof ObjectPropertyLink && ((ObjectPropertyLink)link).getObjectPropertyType() == ObjectPropertyType.Indirect)
      w = ModelingParams.PROPERTY_INDIRECT_WEIGHT;
    else if (link instanceof CompactObjectPropertyLink && ((CompactObjectPropertyLink)link).getObjectPropertyType() == ObjectPropertyType.Indirect)
      w = ModelingParams.PROPERTY_INDIRECT_WEIGHT;
    else if (link instanceof ObjectPropertyLink && ((ObjectPropertyLink)link).getObjectPropertyType() == ObjectPropertyType.WithOnlyDomain)
      w = ModelingParams.PROPERTY_WITH_ONLY_DOMAIN_WEIGHT;
    else if (link instanceof CompactObjectPropertyLink && ((CompactObjectPropertyLink)link).getObjectPropertyType() == ObjectPropertyType.WithOnlyDomain)
      w = ModelingParams.PROPERTY_WITH_ONLY_DOMAIN_WEIGHT;
    else if (link instanceof ObjectPropertyLink && ((ObjectPropertyLink)link).getObjectPropertyType() == ObjectPropertyType.WithOnlyRange)
      w = ModelingParams.PROPERTY_WITH_ONLY_RANGE_WEIGHT;
    else if (link instanceof CompactObjectPropertyLink && ((CompactObjectPropertyLink)link).getObjectPropertyType() == ObjectPropertyType.WithOnlyRange)
      w = ModelingParams.PROPERTY_WITH_ONLY_RANGE_WEIGHT;
    else if (link instanceof ObjectPropertyLink && ((ObjectPropertyLink)link).getObjectPropertyType() == ObjectPropertyType.WithoutDomainAndRange)
      w = ModelingParams.PROPERTY_WITHOUT_DOMAIN_RANGE_WEIGHT;
    else if (link instanceof CompactObjectPropertyLink && ((CompactObjectPropertyLink)link).getObjectPropertyType() == ObjectPropertyType.WithoutDomainAndRange)
      w = ModelingParams.PROPERTY_WITHOUT_DOMAIN_RANGE_WEIGHT;
    else if (link instanceof SubClassLink)
      w = ModelingParams.SUBCLASS_WEIGHT;
    else if (link instanceof CompactSubClassLink)
      w = ModelingParams.SUBCLASS_WEIGHT;
    else
      w = ModelingParams.PROPERTY_DIRECT_WEIGHT;
   
    return w;
  }
 
  public void changeLinkStatus(LabeledLink link, LinkStatus newStatus) {

    LinkStatus oldStatus = link.getStatus();
    if (newStatus == oldStatus)
      return;
   
    link.setStatus(newStatus);
    this.changeLinkWeight(link, computeWeight(link));
   
    Set<LabeledLink> linksWithOldStatus = this.statusToLinksMap.get(oldStatus);
    if (linksWithOldStatus != null) linksWithOldStatus.remove(link);

    if (newStatus == LinkStatus.Normal) // we don't need to index normal links
      return;
   
    Set<LabeledLink> linksWithNewStatus = this.statusToLinksMap.get(newStatus);
    if (linksWithNewStatus == null) {
      linksWithNewStatus = new HashSet<LabeledLink>();
      statusToLinksMap.put(newStatus, linksWithNewStatus);
    }
    linksWithNewStatus.add(link);
  }
 
  public void changeLinkWeight(DefaultLink link, double weight) {
    this.graph.setEdgeWeight(link, weight);
  }
 
  public boolean removeLink(DefaultLink link) {
   
    if (link == null) {
      logger.debug("The link is null.");
      return false;
    }
   
    if (link instanceof CompactLink)
      return false;

    if (idToLinkMap.get(link.getId()) == null) {
      logger.debug("The link with id=" + link.getId() + " does not exists in the graph.");
      return false;
    }
   
    logger.debug("removing the link " + link.getId() + "...");
   
    if (!this.graph.removeEdge(link))
      return false;

    // update hashmaps

    if (link instanceof LabeledLink) {
      this.idToLinkMap.remove(link.getId());
 
      Set<LabeledLink> linksWithSameUri = uriToLinksMap.get(link.getUri());
      if (linksWithSameUri != null)
        linksWithSameUri.remove(link);
     
      Set<LabeledLink> linksWithSameType = typeToLinksMap.get(((LabeledLink)link).getType());
      if (linksWithSameType != null)
        linksWithSameType.remove(link);
     
      Set<LabeledLink> linksWithSameStatus = statusToLinksMap.get(((LabeledLink)link).getStatus());
      if (linksWithSameStatus != null)
        linksWithSameStatus.remove(link);
    }
   
    return true;
  }
 
  public boolean removeNode(Node node) {
   
    if (node == null) {
      logger.error("The node is null");
      return false;
    }
   
    if (idToNodeMap.get(node.getId()) == null) {
      logger.error("The node with id=" + node.getId() + " does not exists in the graph.");
      return false;
    }

    logger.debug("removing the node " + node.getId() + "...");
   
    Set<DefaultLink> incomingLinks = this.graph.incomingEdgesOf(node);
    if (incomingLinks != null) {
      DefaultLink[] incomingLinksArray = incomingLinks.toArray(new DefaultLink[0]);
      for (DefaultLink inLink: incomingLinksArray) {
        this.removeLink(inLink);
      }
    }

    Set<DefaultLink> outgoingLinks = this.graph.outgoingEdgesOf(node);
    if (outgoingLinks != null) {
      DefaultLink[] outgoingLinksArray = outgoingLinks.toArray(new DefaultLink[0]);
      for (DefaultLink outLink: outgoingLinksArray) {
        this.removeLink(outLink);
      }
    }
   
    if(node.isForced())
      this.forcedNodes.remove(node);
   
    if (!this.graph.removeVertex(node))
      return false;
   
    // updating hashmaps
   
    this.idToNodeMap.remove(node.getId());
   
    Set<Node> nodesWithSameUri = uriToNodesMap.get(node.getUri());
    if (nodesWithSameUri != null)
      nodesWithSameUri.remove(node);
   
    Set<Node> nodesWithSameType = typeToNodesMap.get(node.getType());
    if (nodesWithSameType != null)
      nodesWithSameType.remove(node);
   
    logger.debug("total number of nodes in graph: " + this.graph.vertexSet().size());
    logger.debug("total number of links in graph: " + this.graph.edgeSet().size());
   
    return true;
  }
 

  public LinkFrequency getMoreFrequentLinkBetweenNodes(String sourceUri, String targetUri) {

    List<String> possibleLinksFromSourceToTarget = new ArrayList<String>();

    HashSet<String> objectPropertiesDirect;
    HashSet<String> objectPropertiesIndirect;
    HashSet<String> objectPropertiesWithOnlyDomain;
    HashSet<String> objectPropertiesWithOnlyRange;
    HashMap<String, Label> objectPropertiesWithoutDomainAndRange =
        ontologyManager.getObjectPropertiesWithoutDomainAndRange();

    possibleLinksFromSourceToTarget.clear();

    objectPropertiesDirect = ontologyManager.getObjectPropertiesDirect(sourceUri, targetUri);
    if (objectPropertiesDirect != null) possibleLinksFromSourceToTarget.addAll(objectPropertiesDirect);

    objectPropertiesIndirect = ontologyManager.getObjectPropertiesIndirect(sourceUri, targetUri);
    if (objectPropertiesIndirect != null) possibleLinksFromSourceToTarget.addAll(objectPropertiesIndirect);

    objectPropertiesWithOnlyDomain = ontologyManager.getObjectPropertiesWithOnlyDomain(sourceUri);
    if (objectPropertiesWithOnlyDomain != null) possibleLinksFromSourceToTarget.addAll(objectPropertiesWithOnlyDomain);

    objectPropertiesWithOnlyRange = ontologyManager.getObjectPropertiesWithOnlyRange(targetUri);
    if (objectPropertiesWithOnlyRange != null) possibleLinksFromSourceToTarget.addAll(objectPropertiesWithOnlyRange);

    if (ontologyManager.isSubClass(sourceUri, targetUri, true))
      possibleLinksFromSourceToTarget.add(Uris.RDFS_SUBCLASS_URI);

    if (objectPropertiesWithoutDomainAndRange != null) {
      possibleLinksFromSourceToTarget.addAll(objectPropertiesWithoutDomainAndRange.keySet());
    }
   
//    Collection<String> userLinks = this.sourceToTargetLinks.get(sourceUri + "---" + targetUri);
//    if (userLinks != null) {
//      for (String s : userLinks)
//        possibleLinksFromSourceToTarget.add(s);
//    }

    String selectedLinkUri1 = null;
    int maxCount1 = 0;

    String selectedLinkUri2 = null;
    int maxCount2 = 0;

    String selectedLinkUri3 = null;
    int maxCount3 = 0;

    String selectedLinkUri4 = null;
    int maxCount4 = 0;

    String key;
   
    if (possibleLinksFromSourceToTarget != null  && possibleLinksFromSourceToTarget.size() > 0) {

      for (String linkUri : possibleLinksFromSourceToTarget) {
        key = "domain:" + sourceUri + ",link:" + linkUri + ",range:" + targetUri;
        Integer count1 = this.linkCountMap.get(key);
        if (count1 != null && count1.intValue() > maxCount1) {
          maxCount1 = count1.intValue();
          selectedLinkUri1 = linkUri;
        }
      }
     
      for (String linkUri : possibleLinksFromSourceToTarget) {
        key = "range:" + targetUri + ",link:" + linkUri ;
        Integer count2 = this.linkCountMap.get(key);
        if (count2 != null && count2.intValue() > maxCount2) {
          maxCount2 = count2.intValue();
          selectedLinkUri2 = linkUri;
        }
      }
     
      for (String linkUri : possibleLinksFromSourceToTarget) {
        key = "domain:" + sourceUri + ",link:" + linkUri;
        Integer count3 = this.linkCountMap.get(key);
        if (count3 != null && count3.intValue() > maxCount3) {
          maxCount3 = count3.intValue();
          selectedLinkUri3 = linkUri;
        }
      }

      for (String linkUri : possibleLinksFromSourceToTarget) {
        key = "link:" + linkUri;
        Integer count4 = this.linkCountMap.get(key);
        if (count4 != null && count4.intValue() > maxCount4) {
          maxCount4 = count4.intValue();
          selectedLinkUri4 = linkUri;
        }
      }

    } else {
      logger.error("Something is going wrong. There should be at least one possible object property between " +
          sourceUri + " and " + targetUri);
      return null;
    }
   
    String selectedLinkUri;
    int maxCount;
    int type;

    if (selectedLinkUri1 != null && selectedLinkUri1.trim().length() > 0) {
      selectedLinkUri = selectedLinkUri1;
      maxCount = maxCount1;
      type = 1; // match domain and link and range
    } else if (selectedLinkUri2 != null && selectedLinkUri2.trim().length() > 0) {
      selectedLinkUri = selectedLinkUri2;
      maxCount = maxCount2;
      type = 2; // match link and range
    } else if (selectedLinkUri3 != null && selectedLinkUri3.trim().length() > 0) {
      selectedLinkUri = selectedLinkUri3;
      maxCount = maxCount3;
      type = 3; // match domain and link
    } else if (selectedLinkUri4 != null && selectedLinkUri4.trim().length() > 0) {
      selectedLinkUri = selectedLinkUri4;
      maxCount = maxCount4;
      type = 4; // match link label
    } else {
      if (objectPropertiesDirect != null && objectPropertiesDirect.size() > 0) {
        selectedLinkUri = objectPropertiesDirect.iterator().next();
        type = 5;
      } else   if (objectPropertiesIndirect != null && objectPropertiesIndirect.size() > 0) {
        selectedLinkUri = objectPropertiesIndirect.iterator().next();
        type = 6;
      } else   if (objectPropertiesWithOnlyDomain != null && objectPropertiesWithOnlyDomain.size() > 0) {
        selectedLinkUri = objectPropertiesWithOnlyDomain.iterator().next();
        type = 7;
      } else   if (objectPropertiesWithOnlyRange != null && objectPropertiesWithOnlyRange.size() > 0) {
        selectedLinkUri = objectPropertiesWithOnlyRange.iterator().next();;
        type = 8;
      } else if (ontologyManager.isSubClass(sourceUri, targetUri, true)) {
        selectedLinkUri = Uris.RDFS_SUBCLASS_URI;
        type = 9;
      } else // if (objectPropertiesWithoutDomainAndRange != null && objectPropertiesWithoutDomainAndRange.keySet().size() > 0) {
        selectedLinkUri = new ArrayList<String>(objectPropertiesWithoutDomainAndRange.keySet()).get(0);
        type = 10;
      }

      maxCount = 0;
    }
   
    LinkFrequency lf = new LinkFrequency(selectedLinkUri, type, maxCount);
   
    return lf;
   
  }
 
  // Private Methods
 
  private void initialGraph() {
   
    logger.debug("<enter");
   
    // Add Thing to the Graph
    if (ModelingConfiguration.getThingNode()) {
      String id = nodeIdFactory.getNodeId(Uris.THING_URI);
      Label label = new Label(Uris.THING_URI, Namespaces.OWL, Prefixes.OWL);
      Node thing = new InternalNode(id, label);
      addNode(thing);
    }
   
    logger.debug("exit>");
  }

  private void updateLinkCountMap(DefaultLink link) {

    String key, sourceUri, targetUri, linkUri;
    Integer count;
    Node source, target;
   
    source = link.getSource();
    target = link.getTarget();
   
    sourceUri = source.getUri();
    targetUri = target.getUri();
    linkUri = link.getUri();

//    if (link instanceof DataPropertyLink) return;

    if (target instanceof InternalNode) {
      key = "domain:" + sourceUri + ",link:" + linkUri + ",range:" + targetUri;
      count = this.linkCountMap.get(key);
      if (count == null) this.linkCountMap.put(key, 1);
      else this.linkCountMap.put(key, count.intValue() + 1);
     
      key = "range:" + targetUri + ",link:" + linkUri ;
      count = this.linkCountMap.get(key);
      if (count == null) this.linkCountMap.put(key, 1);
      else this.linkCountMap.put(key, count.intValue() + 1);
    }
   
    key = "domain:" + sourceUri + ",link:" + linkUri;
    count = this.linkCountMap.get(key);
    if (count == null) this.linkCountMap.put(key, 1);
    else this.linkCountMap.put(key, count.intValue() + 1);

    key = "link:" + linkUri;
    count = this.linkCountMap.get(key);
    if (count == null) this.linkCountMap.put(key, 1);
    else this.linkCountMap.put(key, count.intValue() + 1);
  }

  private HashSet<String> getUriDirectConnections(String uri) {
   
    HashSet<String> uriDirectConnections = new HashSet<String>();
   
    HashSet<String> opDomainClasses = null;
    HashMap<String, Label> superClasses = null;

    // We don't need to add subclasses of each class separately.
    // The only place in which we add children is where we are looking for domain class of a property.
    // In this case, in addition to the domain class, we add all of its children too.
   
    opDomainClasses = ontologyManager.getDomainsGivenRange(uri, true);
    superClasses = ontologyManager.getSuperClasses(uri, false);

    if (opDomainClasses != null)
      uriDirectConnections.addAll(opDomainClasses);
    if (superClasses != null)
      uriDirectConnections.addAll(superClasses.keySet());

    return uriDirectConnections;
  }

  private Set<String> computeUriClosure(String uri) {
   
    Set<String> closure = this.uriClosure.get(uri);
    if (closure != null)
      return closure;
 
    closure = new HashSet<String>();
    List<String> closedList = new ArrayList<String>();
    HashMap<String, Set<String>> dependentUrisMap = new HashMap<String, Set<String>>();
    computeUriClosureRecursive(uri, closure, closedList, dependentUrisMap);
    if (closedList.contains(uri) && !closure.contains(uri))
      closure.add(uri);
   
    int count = 1;
    while (count != 0) {
      count = 0;
      for (String s : dependentUrisMap.keySet()) {
        Set<String> temp = this.uriClosure.get(s);
        Set<String> dependentUris = dependentUrisMap.get(s);
        for (String ss : dependentUris) {
          if (!temp.contains(ss)) { temp.add(ss); count++;}
          if (this.uriClosure.get(ss) != null) {
            String[] cc = this.uriClosure.get(ss).toArray(new String[0]);
            for (String c : cc) {
              if (!temp.contains(c)) {temp.add(c); count++;}
            }
          }
           
        }
      }
    }

    return closure;
  }

  private void computeUriClosureRecursive(String uri, Set<String> closure,
      List<String> closedList, HashMap<String, Set<String>> dependentUrisMap) {
   
    logger.debug("<enter");
   
    closedList.add(uri);
    Set<String> currentClosure = this.uriClosure.get(uri);
    if (currentClosure != null) {
      closure.addAll(currentClosure);
      return;
    }

    HashSet<String> uriDirectConnections = getUriDirectConnections(uri);
    if (uriDirectConnections.size() == 0) {
      this.uriClosure.put(uri, new HashSet<String>());
    } else {
      for (String c : uriDirectConnections) {
        if (closedList.contains(c)) {
          Set<String> dependentUris = dependentUrisMap.get(uri);
          if (dependentUris == null) {
            dependentUris = new HashSet<String>();
            dependentUrisMap.put(uri, dependentUris);
          }
          if (!dependentUris.contains(c)) dependentUris.add(c);
          continue;
        }
        if (!closure.contains(c)) closure.add(c);
        if (!closedList.contains(c)) closedList.add(c);
        Set<String> localClosure = new HashSet<String>();
        computeUriClosureRecursive(c, localClosure, closedList, dependentUrisMap);
        for (String s : localClosure)
          if (!closure.contains(s)) closure.add(s);
      }
      this.uriClosure.put(uri, closure);
    }
   
    logger.debug("exit>");
  }
 
  public List<Node> getNodeClosure(Node node) {
   
    List<Node> nodeClosure = new ArrayList<Node>();
    if (node instanceof ColumnNode) return nodeClosure;
   
    String uri = node.getUri();
    Set<String> closure = this.uriClosure.get(uri);
    if (closure == null) {  // the closure has already been computed.
      closure = computeUriClosure(uri);
    }
    for (String s : closure) {
      Set<Node> nodes = uriToNodesMap.get(s);
      if (nodes != null) nodeClosure.addAll(nodes);
    }
    return nodeClosure;
  }
 
  /**
   * returns all the new nodes that should be added to the graph due to adding the input node
   * @param node
   * @param closure: contains all the nodes that are connected to the input node
   * by ObjectProperty or SubClass links
   * @return
   */
  private void addNodeClosure(Node node, Set<Node> newAddedNodes) {

    logger.debug("<enter");
   
    if (newAddedNodes == null) newAddedNodes = new HashSet<Node>();
   
    String uri = node.getUri();
    if (this.uriClosure.get(uri) != null) // the closure is already computed and added to the graph.
      return;

    Set<String> uriClosure = computeUriClosure(uri);

    for (String c : uriClosure) {
      Set<Node> nodesOfSameUri = this.uriToNodesMap.get(c);
      if (nodesOfSameUri == null || nodesOfSameUri.size() == 0) { // the internal node is not added to the graph before
        Node nn = new InternalNode(nodeIdFactory.getNodeId(c),
            ontologyManager.getUriLabel(c));
        if (addNode(nn)) newAddedNodes.add(nn);
      }
    }
   
    logger.debug("exit>");
  }
 
  private void updateLinks() {
   
    logger.debug("<enter");
   
    Set<Node> nodeSet = this.typeToNodesMap.get(NodeType.InternalNode);
    if (nodeSet == null || nodeSet.isEmpty())
      return;
   
    List<Node> nodes = new ArrayList<Node>(nodeSet);
    logger.debug("number of internal nodes: " + nodes.size());
   
    Node source;
    Node target;
    String sourceUri;
    String targetUri;

    String id = null;
   
    for (int i = 0; i < nodes.size(); i++) {
     
      Node n1 = nodes.get(i);
      for (int j = i+1; j < nodes.size(); j++) {

        Node n2 = nodes.get(j);

        if (n1.equals(n2))
          continue;

        if (this.visitedSourceTargetPairs.contains(n1.getId() + n2.getId()))
          continue;
        if (this.visitedSourceTargetPairs.contains(n2.getId() + n1.getId()))
          continue;
       
        source = n1;
        target = n2;

        sourceUri = source.getUri();
        targetUri = target.getUri();

        id = LinkIdFactory.getLinkId(Uris.DEFAULT_LINK_URI, source.getId(), target.getId());
        CompactLink link = null;

        boolean connected = false;
       
        // order of adding the links is based on the ascending sort of their weight value
       
        if (ModelingConfiguration.getPropertiesDirect()) {
          if (this.ontologyManager.isConnectedByDirectProperty(sourceUri, targetUri) ||
              this.ontologyManager.isConnectedByDirectProperty(targetUri, sourceUri)) {
            logger.debug( sourceUri + " and " + targetUri + " are connected by a direct object property.");
            link = new CompactObjectPropertyLink(id, ObjectPropertyType.Direct);
            addLink(source, target, link);
            connected = true;
          }
        }
       
        if (ModelingConfiguration.getPropertiesIndirect() && !connected) {
          if (this.ontologyManager.isConnectedByIndirectProperty(sourceUri, targetUri) ||
              this.ontologyManager.isConnectedByIndirectProperty(targetUri, sourceUri)) {
            logger.debug( sourceUri + " and " + targetUri + " are connected by an indirect object property.");
            link = new CompactObjectPropertyLink(id, ObjectPropertyType.Indirect);
            addLink(source, target, link);
            connected = true;
          }
        }
       
        if (ModelingConfiguration.getPropertiesWithOnlyRange() && !connected) {
          if (this.ontologyManager.isConnectedByDomainlessProperty(sourceUri, targetUri) ||
              this.ontologyManager.isConnectedByDomainlessProperty(targetUri, sourceUri)) {
            logger.debug( sourceUri + " and " + targetUri + " are connected by an object property whose range is " + sourceUri + " or " + targetUri);
            link = new CompactObjectPropertyLink(id, ObjectPropertyType.WithOnlyRange);
            addLink(source, target, link);
            connected = true;
          }
        }
       
        if (ModelingConfiguration.getPropertiesWithOnlyDomain() && !connected) {
          if (this.ontologyManager.isConnectedByRangelessProperty(sourceUri, targetUri) ||
              this.ontologyManager.isConnectedByRangelessProperty(targetUri, sourceUri)) {
            logger.debug( sourceUri + " and " + targetUri + " are connected by an object property whose domain is " + sourceUri + " or " + targetUri);
            link = new CompactObjectPropertyLink(id, ObjectPropertyType.WithOnlyDomain);
            addLink(source, target, link)
            connected = true;
          }
        }
       
        if (ModelingConfiguration.getPropertiesSubClass() && !connected) {
          if (this.ontologyManager.isSubClass(sourceUri, targetUri, false) ||
              this.ontologyManager.isSubClass(targetUri, sourceUri, false)) {
            logger.debug( sourceUri + " and " + targetUri + " are connected by a subClassOf relation.");
            link = new CompactSubClassLink(id);
            addLink(source, target, link);
            connected = true;
          }
        }
       
        if (ModelingConfiguration.getPropertiesWithoutDomainRange() && !connected) {
          if (this.ontologyManager.isConnectedByDomainlessAndRangelessProperty(sourceUri, targetUri)) {// ||
  //            this.ontologyManager.isConnectedByDomainlessAndRangelessProperty(targetUri, sourceUri)) {
            link = new CompactObjectPropertyLink(id, ObjectPropertyType.WithoutDomainAndRange);
            addLink(source, target, link);
            connected = true;
          }
        }

        if (!connected) {
          this.visitedSourceTargetPairs.add(n1.getId() + n2.getId());
          logger.debug("did not put a link between (" + n1.getId() + ", " + n2.getId() + ")");
        }
      }
    }

    logger.debug("exit>");
  }
 

  public List<LabeledLink> getPossibleLinks(String sourceId, String targetId) {
    return getPossibleLinks(sourceId, targetId, null, null);
  }
 
  public List<LabeledLink> getPossibleLinks(String sourceId, String targetId, LinkType linkType,
      ObjectPropertyType objectProertyType) {
   
    List<LabeledLink> sortedLinks = new ArrayList<LabeledLink>();

    Node source = this.idToNodeMap.get(sourceId);
    Node target = this.idToNodeMap.get(targetId);
   
    if (source == null || target == null) {
      logger.debug("Cannot find source or target in the graph.");
      return sortedLinks;
    }

    if (source instanceof ColumnNode || target instanceof ColumnNode) {
      logger.debug("Source or target is a column node.");
      return sortedLinks;
    }

    String sourceUri, targetUri;
    sourceUri = source.getUri();
    targetUri = target.getUri();

    HashSet<String> links =
        this.ontologyManager.getPossibleUris(sourceUri, targetUri);

    String id;
    Label label;
    ObjectPropertyType linkObjectPropertyType;

    for (String uri : links) {
     
      if (linkType == LinkType.SubClassLink && !uri.equalsIgnoreCase(Uris.RDFS_SUBCLASS_URI))
        continue;
     
      if (linkType == LinkType.ObjectPropertyLink && uri.equalsIgnoreCase(Uris.RDFS_SUBCLASS_URI))
        continue;
     
      linkObjectPropertyType = ontologyManager.getObjectPropertyType(sourceUri, targetUri, uri);
      if (linkType == LinkType.ObjectPropertyLink &&
          objectProertyType != null &&
          objectProertyType != ObjectPropertyType.None &&
          objectProertyType != linkObjectPropertyType)
        continue;
     
      id = LinkIdFactory.getLinkId(uri, sourceId, targetId);
      label = new Label(ontologyManager.getUriLabel(uri));
     
      LabeledLink newLink;
      if (uri.equalsIgnoreCase(Uris.RDFS_SUBCLASS_URI))
        newLink = new SubClassLink(id);
      else
        newLink = new ObjectPropertyLink(id, label, linkObjectPropertyType);
     
      sortedLinks.add(newLink);
    }
   
    Collections.sort(sortedLinks, new LinkPriorityComparator());
   
    return sortedLinks;
  }
 
  public static void main(String[] args) throws Exception {
   
    logger.info(Integer.class.getFields()[0].getName());
   
    /** Check if any ontology needs to be preloaded **/
    File ontDir = new File(Params.ONTOLOGY_DIR);
    if (ontDir.exists()) {
      File[] ontologies = ontDir.listFiles();
      OntologyManager mgr = new OntologyManager();
      for (File ontology: ontologies) {
        System.out.println(ontology.getName());
        if (ontology.getName().endsWith(".owl") ||
            ontology.getName().endsWith(".rdf") ||
            ontology.getName().endsWith(".n3") ||
            ontology.getName().endsWith(".ttl") ||
            ontology.getName().endsWith(".xml")) {
          logger.info("Loading ontology file: " + ontology.getAbsolutePath());
          try {
            String encoding = EncodingDetector.detect(ontology);
            mgr.doImport(ontology, encoding);
          } catch (Exception t) {
//            logger.error("Error loading ontology: " + ontology.getAbsolutePath(), t);
          }
        } else {
          logger.error ("the file: " + ontology.getAbsolutePath() + " does not have proper format: xml/rdf/n3/ttl/owl");
        }
      }
      // update the cache at the end when all files are added to the model
      mgr.updateCache();
      Set<String> test = mgr.getPossibleUris("http://example.com/layout/C01_", "http://example.com/layout/C02_");
      for (String s : test) {
        System.out.println(s);
      }
      Alignment al = new Alignment(mgr);
      ColumnNode c1 = al.addColumnNode("h1", "c1", null);
      ColumnNode c2 = al.addColumnNode("h2", "c2", null);
      InternalNode n1 = al.addInternalNode(new Label("http://example.com/layout/C01_"));
      InternalNode n2 = al.addInternalNode(new Label("http://example.com/layout/C02_"));
      al.addDataPropertyLink(n1, c1, new Label("http://example.com/layout/d1"));
      al.addDataPropertyLink(n2, c2, new Label("http://example.com/layout/d2"));
      al.align();
      System.out.println(GraphUtil.labeledGraphToString(al.getSteinerTree()));
    } else {
      logger.info("No directory for preloading ontologies exists.");
    }
       
//    DirectedWeightedMultigraph<Node, DefaultLink> g = new
//        DirectedWeightedMultigraph<Node, DefaultLink>(DefaultLink.class);
//   
//    Node n1 = new InternalNode("n1", null);
//    Node n2 = new InternalNode("n2", null);
//    Node n3 = new InternalNode("n3", null);
//    Node n4 = new InternalNode("n4", null);
//    Node n8 = new ColumnNode("n8", "h1", "B", null);
//    Node n9 = new ColumnNode("n9", "h2", "B", null);
//   
//    DefaultLink l1 = new ObjectPropertyLink("e1", null, ObjectPropertyType.None);
//    DefaultLink l2 = new ObjectPropertyLink("e2", null, ObjectPropertyType.None);
//    DefaultLink l3 = new ObjectPropertyLink("e3", null, ObjectPropertyType.None);
//    DefaultLink l4 = new ObjectPropertyLink("e4", null, ObjectPropertyType.None);
//    DefaultLink l5 = new ObjectPropertyLink("e5", null, ObjectPropertyType.None);
//    DefaultLink l6 = new ObjectPropertyLink("e6", null, ObjectPropertyType.None);
////    Link l7 = new ObjectPropertyLink("e7", null);
////    Link l8 = new DataPropertyLink("e8", null);
////    Link l9 = new DataPropertyLink("e9", null);
//   
//    g.addVertex(n1);
//    g.addVertex(n2);
//    g.addVertex(n3);
//    g.addVertex(n4);
//    g.addVertex(n8);
//    g.addVertex(n9);
//   
//    g.addEdge(n1, n2, l1);
//    g.addEdge(n1, n3, l2);
//    g.addEdge(n2, n3, l6);
//    g.addEdge(n2, n4, l3);
//    g.addEdge(n4, n8, l4);
//    g.addEdge(n3, n9, l5);
//   
//    GraphUtil.printGraph(g);
//   
//    DisplayModel dm = new DisplayModel(GraphUtil.asLabeledGraph(g));
//    HashMap<Node, Integer> nodeLevels = dm.getNodesLevel();
//    for (Node n : g.vertexSet())
//      logger.info(n.getId() + " --- " + nodeLevels.get(n));
//   
//    HashMap<Node, Set<ColumnNode>> coveredColumnNodes = dm.getNodesSpan();
//   
//    logger.info("Internal Nodes Coverage ...");
//    for (Entry<Node, Set<ColumnNode>> entry : coveredColumnNodes.entrySet()) {
//      logger.info(entry.getKey().getId());
//      for (Node n : entry.getValue())
//        logger.info("-----" + n.getId());
//    }
   
//    GraphUtil.serialize(g, "test");
//    DirectedWeightedMultigraph<Node, Link> gprime = GraphUtil.deserialize("test");
//   
//    GraphUtil.printGraph(gprime);

//    g.removeEdge(l1);
//    GraphUtil.printGraph(g);
   
//    g.removeVertex(n2);
//    GraphUtil.printGraph(g);
  }


}
TOP

Related Classes of edu.isi.karma.modeling.alignment.GraphBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.