Package com.hp.hpl.jena.gvs.impl

Source Code of com.hp.hpl.jena.gvs.impl.FCAGraphImpl

/*
(c) Copyright 2005, 2006, Hewlett-Packard Development Company, LP
[See end of file]
$Id: FCAGraphImpl.java,v 1.5 2007/05/07 18:50:06 rebach Exp $
*/
package com.hp.hpl.jena.gvs.impl;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.wymiwyg.rdf.graphs.Graph;
import org.wymiwyg.rdf.graphs.GroundedNode;
import org.wymiwyg.rdf.graphs.LiteralNode;
import org.wymiwyg.rdf.graphs.NamedNode;
import org.wymiwyg.rdf.graphs.Node;
import org.wymiwyg.rdf.graphs.PlainLiteralNode;
import org.wymiwyg.rdf.graphs.PropertyNode;
import org.wymiwyg.rdf.graphs.Triple;
import org.wymiwyg.rdf.graphs.TypedLiteralNode;
import org.wymiwyg.rdf.graphs.fgnodes.FunctionallyGroundedNode;
import org.wymiwyg.rdf.graphs.fgnodes.impl.FunctionallyGroundedNodeImpl;
import org.wymiwyg.rdf.graphs.fgnodes.impl.InverseFunctionalPropertyNodeImpl;
import org.wymiwyg.rdf.graphs.impl.AnonymizedGraph;
import org.wymiwyg.rdf.graphs.impl.DeAnonymizedGraph;
import org.wymiwyg.rdf.graphs.impl.NodeImpl;
import org.wymiwyg.rdf.graphs.impl.TripleImpl;
import org.wymiwyg.rdf.graphs.impl.TypedLiteralNodeImpl;
import org.wymiwyg.rdf.graphs.jenaimpl.JenaUtil;
import org.wymiwyg.rdf.molecules.MaximumContextualMolecule;
import org.wymiwyg.rdf.molecules.NonTerminalMolecule;
import org.wymiwyg.rdf.molecules.TerminalMolecule;
import org.wymiwyg.rdf.molecules.diff.vocabulary.MODELDIFF;
import org.wymiwyg.rdf.molecules.functref.ReferenceGroundedDecomposition;
import org.wymiwyg.rdf.molecules.functref.impl.ReferenceGroundedDecompositionImpl;
import org.wymiwyg.rdf.molecules.functref.impl.ReferenceGroundedUtil;
import org.wymiwyg.rdf.molecules.impl.SimpleNonTerminalMolecule;
import org.wymiwyg.rdf.molecules.model.modelref.implgraph.ModelReferencingDecompositionImpl;

import com.hp.hpl.jena.datatypes.TypeMapper;
import com.hp.hpl.jena.graph.TripleMatch;
import com.hp.hpl.jena.graph.impl.GraphBase;
import com.hp.hpl.jena.gvs.FCAGraph;
import com.hp.hpl.jena.gvs.FilterableDecomposition;
import com.hp.hpl.jena.mem.TrackingTripleIterator;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;

/**
* This class implements FCAGraph, it does decomposition and reconstruction of
* the graph as needed. Once a decomposition or a reconstruction is created both
* graph and decomposition are kept in memory.
*
* Instances of this class are inmutable.
*
* When an instance is accessed as a Jena Graph a mapping from
* org.wymiwyg.rdf.graphs.NodeS to com.hp.hpl.jena.graph.NodeS is made.
*
* @author reto
*
*/
public class FCAGraphImpl extends GraphBase implements FCAGraph {

  private final static URI anyURIDataType;

  private final static PropertyNode nameProp = new InverseFunctionalPropertyNodeImpl(
      MODELDIFF.name.getURI());

  static {
    try {
      anyURIDataType = new URI("http://www.w3.org/2001/XMLSchema#anyURI");
    } catch (URISyntaxException e) {
      throw new RuntimeException(e);
    }
  }

  private FilterableDecomposition decomposition = null;

  private Graph graph = null;

  private Map<Node, com.hp.hpl.jena.graph.Node> node2jenaNodeMap = new HashMap<Node, com.hp.hpl.jena.graph.Node>();

  // private Collection<com.hp.hpl.jena.graph.Triple> jenaTriples;

  /**
   * Creates a FCAGraph using a FilterableDecomposition
   *
   * @param decomposition
   *            the decomposition to be decorated
   */
  public FCAGraphImpl(FilterableDecomposition decomposition) {
    super();
    this.decomposition = decomposition;
  }

  /**
   * Creates a FCAGraph using a graph
   *
   * @param graph
   *            the graph to be decorated
   */
  public FCAGraphImpl(Graph graph) {
    super();
    this.graph = graph;
  }

  /**
   * Creates a FCAGraph using a Model
   *
   * @param model
   *            the model to be converted
   */
  public FCAGraphImpl(Model model) {
    super();
    this.graph = JenaUtil.getGraphFromModel(model, true);
  }

  /**
   * Creates a FCAGraph using a ReferenceGroundedDecomposition
   *
   * @param decomposition
   *            the decomposition to be decorated
   */
  public FCAGraphImpl(ReferenceGroundedDecomposition decomposition) {
    super();
    this.decomposition = new SimpleFilterableDecomposition(decomposition);
  }

  /*
   * (non-Javadoc)
   *
   * @see java.util.Collection#add(java.lang.Object)
   */
  public boolean add(Triple arg0) {
    throw new UnsupportedOperationException();
  }

  /*
   * (non-Javadoc)
   *
   * @see java.util.Collection#addAll(java.util.Collection)
   */
  public boolean addAll(Collection<? extends Triple> arg0) {
    throw new UnsupportedOperationException();
  }

  /*
   * (non-Javadoc)
   *
   * @see java.util.Collection#clear()
   */
  public void clear() {
    throw new UnsupportedOperationException();
  }

  /*
   * (non-Javadoc)
   *
   * @see java.util.Collection#contains(java.lang.Object)
   */
  public boolean contains(Object triple) {
    if (graph == null)
      createGraph();
    return graph.contains(triple);
  }

  /*
   * (non-Javadoc)
   *
   * @see java.util.Collection#containsAll(java.util.Collection)
   */
  public boolean containsAll(Collection<?> arg0) {
    if (graph == null)
      createGraph();
    return graph.containsAll(arg0);
  }

  @Override
  public boolean equals(Object obj) {
    if (graph == null)
      createGraph();
    return graph.equals(obj);
  }

  /*
   * (non-Javadoc)
   *
   * @see com.hp.hpl.jena.gvs.FCAGraph#filter(java.util.Set)
   */
  public FCAGraph filter(Set<GroundedNode> onlyForGroundedNodes) {
    onlyForGroundedNodes = functionalyze(onlyForGroundedNodes);
    Set<GroundedNode> expandedGroundedNodeSet = new HashSet<GroundedNode>();
    expandedGroundedNodeSet.addAll(onlyForGroundedNodes);
    ReconstructedReferenceGroundedDecompositionImpl resultDec = new ReconstructedReferenceGroundedDecompositionImpl();
    Set<FunctionallyGroundedNode> resultFgNodes = resultDec
        .getEditableFunctionallyGroundedNodes();
    for (GroundedNode node : expandedGroundedNodeSet) {
      if (node instanceof FunctionallyGroundedNode) {
        resultFgNodes.add((FunctionallyGroundedNode) node);
      }
    }

    int previousSize = -1;
    while (resultFgNodes.size() > previousSize) {
      previousSize = resultFgNodes.size();
      Set<FunctionallyGroundedNode> addition = getFunctionallyGroundedNodes(expandedGroundedNodeSet);
      resultFgNodes.addAll(addition);
      expandedGroundedNodeSet.addAll(addition);
    }

    Set<TerminalMolecule> resultTerminalMolecules = resultDec
        .getEditableTerminalMolecules();
    resultTerminalMolecules
        .addAll(getTerminalMolecules(expandedGroundedNodeSet));

    Set<MaximumContextualMolecule> resultContextualMolecules = resultDec
        .getEditableContextualMolecules();
    resultContextualMolecules
        .addAll(getContextualMolecules(expandedGroundedNodeSet));

    resultFgNodes.addAll(getContainedFgNodes(resultTerminalMolecules));
    resultFgNodes.addAll(getContainedFgNodes(resultContextualMolecules));

    // add fg-nodes contained in fg-nodes
    previousSize = 0;
    while (resultFgNodes.size() > previousSize) {
      previousSize = resultFgNodes.size();
      Set<FunctionallyGroundedNode> addition = new HashSet<FunctionallyGroundedNode>();
      for (FunctionallyGroundedNode node : resultFgNodes) {
        addition.addAll(getContainedFgNodes(node.getGroundingMolecules()));
      }
      resultFgNodes.addAll(addition);
    }
    return new FCAGraphImpl(resultDec);

  }

  /*
   * (non-Javadoc)
   *
   * @see org.wymiwyg.rdf.molecules.functref.ReferenceGroundedDecomposition#getContextualMolecules()
   */
  public Set<MaximumContextualMolecule> getContextualMolecules() {
    if (decomposition == null)
      createDecomposition();
    return decomposition.getContextualMolecules();
  }

  /*
   * (non-Javadoc)
   *
   * @see org.wymiwyg.rdf.molecules.functref.ReferenceGroundedDecomposition#getFunctionallyGroundedNodes()
   */
  public Set<FunctionallyGroundedNode> getFunctionallyGroundedNodes() {
    if (decomposition == null)
      createDecomposition();
    return decomposition.getFunctionallyGroundedNodes();
  }

  /*
   * (non-Javadoc)
   *
   * @see org.wymiwyg.rdf.molecules.functref.ReferenceGroundedDecomposition#getTerminalMolecules()
   */
  public Set<TerminalMolecule> getTerminalMolecules() {
    if (decomposition == null)
      createDecomposition();
    return decomposition.getTerminalMolecules();
  }

  @Override
  public int hashCode() {
    if (graph == null)
      createGraph();
    return graph.hashCode();
  }

  /*
   * (non-Javadoc)
   *
   * @see java.util.Collection#iterator()
   */
  public Iterator<Triple> iterator() {
    if (graph == null)
      createGraph();
    return graph.iterator();
  }

  /*
   * (non-Javadoc)
   *
   * @see java.util.Collection#remove(java.lang.Object)
   */
  public boolean remove(Object arg0) {
    throw new UnsupportedOperationException();
  }

  /*
   * (non-Javadoc)
   *
   * @see java.util.Collection#removeAll(java.util.Collection)
   */
  public boolean removeAll(Collection<?> arg0) {
    throw new UnsupportedOperationException();
  }

  /*
   * (non-Javadoc)
   *
   * @see java.util.Collection#retainAll(java.util.Collection)
   */
  public boolean retainAll(Collection<?> arg0) {
    throw new UnsupportedOperationException();
  }

  /*
   * (non-Javadoc)
   *
   * @see java.util.Collection#toArray()
   */
  public Object[] toArray() {
    if (graph == null)
      createGraph();
    return graph.toArray();
  }

  /*
   * (non-Javadoc)
   *
   * @see java.util.Collection#toArray(T[])
   */
  public <T> T[] toArray(T[] arg0) {
    if (graph == null)
      createGraph();
    return graph.toArray(arg0);
  }


  private Set<FunctionallyGroundedNode> getContainedFgNodes(Set<? extends Graph> graphs) {
    Set<FunctionallyGroundedNode> resultFgNodes = new HashSet<FunctionallyGroundedNode>();
    for (Graph graph : graphs) {
      for (Triple triple : graph) {
        if (triple.getSubject() instanceof FunctionallyGroundedNode) {
          resultFgNodes.add((FunctionallyGroundedNode) triple
              .getSubject());
        }
        if (triple.getObject() instanceof FunctionallyGroundedNode) {
          resultFgNodes.add((FunctionallyGroundedNode) triple
              .getObject());
        }
      }
    }
    return resultFgNodes;
  }

  private Iterator<com.hp.hpl.jena.graph.Triple> convertNodes(
      final Iterator<Triple> base) {
    return new Iterator<com.hp.hpl.jena.graph.Triple>() {

      public boolean hasNext() {
        return base.hasNext();
      }

      public com.hp.hpl.jena.graph.Triple next() {
        return convertTriple(base.next());
      }

      public void remove() {
        throw new UnsupportedOperationException();
      }

      private com.hp.hpl.jena.graph.Node convert(Node node) {
        com.hp.hpl.jena.graph.Node result = node2jenaNodeMap.get(node);
        if (result != null)
          return result;
        if (node instanceof GroundedNode) {
          if (node instanceof NamedNode) {
            result = com.hp.hpl.jena.graph.Node
                .createURI(((NamedNode) node).getURIRef());
          } else {
            if (node instanceof PlainLiteralNode) {
              PlainLiteralNode lit = (PlainLiteralNode) node;
              result = com.hp.hpl.jena.graph.Node.createLiteral(
                  lit.getLexicalForm(),
                  lit.getLocale() == null ? null : lit
                      .getLocale().toString(), false);
            } else {
              TypedLiteralNode lit = (TypedLiteralNode) node;
              result = com.hp.hpl.jena.graph.Node.createLiteral(
                  lit.getLexicalForm(), null, TypeMapper
                      .getInstance().getSafeTypeByName(
                          lit.getDataType()
                              .toString()));
            }
          }
        } else {
          result = com.hp.hpl.jena.graph.Node.createAnon();
        }
        node2jenaNodeMap.put(node, result);
        return result;
      }

      private com.hp.hpl.jena.graph.Triple convertTriple(Triple triple) {
        return new com.hp.hpl.jena.graph.Triple(convert(triple
            .getSubject()), convert(triple.getPredicate()),
            convert(triple.getObject()));
      }

    };
  }

  /**
   *
   */
  private void createDecomposition() {
    decomposition = new SimpleFilterableDecomposition(
        new ReferenceGroundedDecompositionImpl(
            new ModelReferencingDecompositionImpl(
                new AnonymizedGraph(graph))));

  }

  /**
   *
   */
  private void createGraph() {
    graph = new DeAnonymizedGraph(ReferenceGroundedUtil
        .reconstructGraph(decomposition));

  }

  private Iterator filterTriples(
      final Iterator<com.hp.hpl.jena.graph.Triple> base,
      final TripleMatch filter) {
    return new Iterator<com.hp.hpl.jena.graph.Triple>() {

      com.hp.hpl.jena.graph.Triple next = getNext();

      public boolean hasNext() {
        return next != null;
      }

      public com.hp.hpl.jena.graph.Triple next() {
        com.hp.hpl.jena.graph.Triple result = next;
        next = getNext();
        return result;
      }

      public void remove() {
        throw new UnsupportedOperationException();

      }

      private com.hp.hpl.jena.graph.Triple getNext() {
        while (base.hasNext()) {
          com.hp.hpl.jena.graph.Triple nextInBase = base.next();
          if (match(nextInBase, filter)) {
            return nextInBase;
          }
        }
        return null;
      }

      private boolean match(com.hp.hpl.jena.graph.Triple triple,
          TripleMatch filter) {
        if (filter.getMatchSubject() != null) {
          if (!filter.getMatchSubject().equals(triple.getSubject())) {
            return false;
          }
        }
        if (filter.getMatchObject() != null) {
          if (!filter.getMatchObject().equals(triple.getObject())) {
            return false;
          }
        }
        if (filter.getMatchPredicate() != null) {
          if (!filter.getMatchPredicate().equals(
              triple.getPredicate())) {
            return false;
          }
        }
        return true;
      }

    };
  }

  private FunctionallyGroundedNode functionalyze(FunctionallyGroundedNode node) {
    FunctionallyGroundedNodeImpl result = new FunctionallyGroundedNodeImpl();
    for (NonTerminalMolecule molecule : node.getGroundingMolecules()) {
      result.addMolecule(functionalyze(molecule));
    }
    result.markFinalized();
    return result;
  }

  private GroundedNode functionalyze(GroundedNode node) {
    if (node instanceof NamedNode) {
      return functionalyze((NamedNode) node);
    } else {
      if (node instanceof FunctionallyGroundedNode) {
        return functionalyze((FunctionallyGroundedNode) node);
      } else {
        return node;
      }
    }
  }

  private FunctionallyGroundedNode functionalyze(NamedNode node) {
    FunctionallyGroundedNodeImpl result = new FunctionallyGroundedNodeImpl();
    Node afgn = new NodeImpl();
    SimpleNonTerminalMolecule molecule = new SimpleNonTerminalMolecule(afgn);
    String uriString = node.getURIRef();
    LiteralNode uriLit = new TypedLiteralNodeImpl(uriString, anyURIDataType);
    Triple triple = new TripleImpl(afgn, nameProp, uriLit);
    molecule.add(triple);
    molecule.markFinalized();
    result.addMolecule(molecule);
    result.markFinalized();
    result.notifyAllFinalized();
    return result;
  }

  private NonTerminalMolecule functionalyze(NonTerminalMolecule molecule) {
    SimpleNonTerminalMolecule result = new SimpleNonTerminalMolecule(NonTerminalMolecule.GROUNDED_NODE);
    Triple origTriple = molecule.iterator().next();
    Node subject = origTriple.getSubject();
    if (subject instanceof GroundedNode) {
      subject = functionalyze((GroundedNode)subject);
    }
    Node object = origTriple.getObject();
    if (object instanceof GroundedNode) {
      object = functionalyze((GroundedNode)object);
    }
    Triple newTriple = new TripleImpl(subject, origTriple.getPredicate(), object);
    result.add(newTriple);
    return result;
  }

  /**
   * Replaces NamedNode with FG-nodes
   *
   */
  private Set<GroundedNode> functionalyze(
      Set<GroundedNode> onlyForGroundedNodes) {
    Set<GroundedNode> result = new HashSet<GroundedNode>();
    for (GroundedNode node : onlyForGroundedNodes) {
      result.add(functionalyze(node));
     
    }
    return result;
  }

  private Set<MaximumContextualMolecule> getContextualMolecules(
      Set<GroundedNode> onlyForGroundedNodes) {
    if (decomposition == null)
      createDecomposition();
    return decomposition.getContextualMolecules(onlyForGroundedNodes);
  }


  private Set<FunctionallyGroundedNode> getFunctionallyGroundedNodes(
      Set<GroundedNode> onlyForGroundedNodes) {
    if (decomposition == null)
      createDecomposition();
    return decomposition.getFunctionallyGroundedNodes(onlyForGroundedNodes);
  }

  private Set<TerminalMolecule> getTerminalMolecules(
      Set<GroundedNode> onlyForGroundedNodes) {
    if (decomposition == null)
      createDecomposition();
    return decomposition.getTerminalMolecules(onlyForGroundedNodes);
  }

  /*
   * (non-Javadoc)
   *
   * @see com.hp.hpl.jena.graph.impl.GraphBase#graphBaseFind(com.hp.hpl.jena.graph.TripleMatch)
   */
  @Override
  protected ExtendedIterator graphBaseFind(TripleMatch m) {
    if (graph == null)
      createGraph();
    return new TrackingTripleIterator(filterTriples(convertNodes(graph
        .iterator()), m));
  }

}

/*
* (c) Copyright 2005, 2006 Hewlett-Packard Development Company, LP All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
TOP

Related Classes of com.hp.hpl.jena.gvs.impl.FCAGraphImpl

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.