
com.hp.hpl.jena.db.impl.SpecializedGraphReifier_RDB Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jena Show documentation
Show all versions of jena Show documentation
Jena is a Java framework for building Semantic Web applications. It provides a programmatic environment for RDF, RDFS and OWL, SPARQL and includes a rule-based inference engine.
The newest version!
/*
* (c) Copyright 2003 Hewlett-Packard Development Company, LP
* All rights reserved.
*
*/
package com.hp.hpl.jena.db.impl;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.hp.hpl.jena.db.GraphRDB;
import com.hp.hpl.jena.graph.*;
import com.hp.hpl.jena.util.iterator.*;
import com.hp.hpl.jena.shared.*;
import com.hp.hpl.jena.vocabulary.RDF;
/**
* @author hkuno
* @version $Version$
*
* TripleStoreGraph is an abstract superclass for TripleStoreGraph
* implementations. By "triple store," we mean that the subjects, predicate
* and object URI's are stored in a single collection (denormalized).
*
*/
public class SpecializedGraphReifier_RDB
extends SpecializedGraphBase
implements SpecializedGraphReifier {
/**
* holds PSet
*/
public PSet_ReifStore_RDB m_pset;
/**
* caches a copy of LSet properties
*/
public DBPropLSet m_dbPropLSet;
/**
* holds ID of graph in database (defaults to "0")
*/
public IDBID my_GID = null;
// cache of reified statement status
private ReificationCacheMap m_reifCache;
public PSet_ReifStore_RDB m_reif;
// constructors
/**
* Constructor
* Create a new instance of a TripleStore graph.
*/
SpecializedGraphReifier_RDB(DBPropLSet lProp, IPSet pSet, Integer dbGraphID) {
m_pset = (PSet_ReifStore_RDB) pSet;
m_dbPropLSet = lProp;
my_GID = new DBIDInt(dbGraphID);
m_reifCache = new ReificationCacheMap(this, 1);
m_reif = m_pset;
}
/**
* Constructor
*
* Create a new instance of a TripleStore graph, taking
* DBPropLSet and a PSet as arguments
*/
public SpecializedGraphReifier_RDB(IPSet pSet, Integer dbGraphID) {
m_pset = (PSet_ReifStore_RDB) pSet;
my_GID = new DBIDInt(dbGraphID);
m_reifCache = new ReificationCacheMap(this, 1);
m_reif = m_pset;
}
/* (non-Javadoc)
* @see com.hp.hpl.jena.db.impl.SpecializedGraphReifier#add(com.hp.hpl.jena.graph.Node, com.hp.hpl.jena.graph.Triple, com.hp.hpl.jena.db.impl.SpecializedGraph.CompletionFlag)
*/
public void add(Node n, Triple t, CompletionFlag complete) throws CannotReifyException {
ReificationStatementMask same = new ReificationStatementMask();
ReificationStatementMask diff = new ReificationStatementMask();
ReificationCache rs = m_reifCache.load(n, t, same, diff);
if (rs == null) {
m_reif.storeReifStmt(n, t, my_GID);
} else {
/* node already reifies something. is that a subset of triple t? */
if ( diff.hasNada() ) {
boolean didUpdate = false;
/* add whatever is missing to reify t */
if ( !same.hasSubj() ) {
Triple st = Triple.create(n,RDF.Nodes.subject,t.getSubject());
m_reif.updateFrag(n, st, new ReificationStatementMask(st), my_GID);
didUpdate = true;
}
if ( !same.hasPred() ) {
Triple pt = Triple.create(n,RDF.Nodes.predicate,t.getPredicate());
m_reif.updateFrag(n, pt, new ReificationStatementMask(pt), my_GID);
didUpdate = true;
}
if ( !same.hasObj() ) {
Triple ot = Triple.create(n,RDF.Nodes.object,t.getObject());
m_reif.updateFrag(n, ot, new ReificationStatementMask(ot), my_GID);
didUpdate = true;
}
if ( !rs.mask.hasType() ) {
Triple tt = Triple.create(n,RDF.Nodes.type,RDF.Nodes.Statement);
m_reif.updateFrag(n, tt, new ReificationStatementMask(tt), my_GID);
didUpdate = true;
}
if ( didUpdate )
fragCompact(n);
m_reifCache.flushAll();
} else {
/* node reifies something that is not a subset of triple t */
if ( rs.mask.isStmt() )
throw new AlreadyReifiedException(n);
else
throw new CannotReifyException(n);
}
}
complete.setDone();
}
/* (non-Javadoc)
* @see com.hp.hpl.jena.db.impl.SpecializedGraphReifier#delete(com.hp.hpl.jena.graph.Node, com.hp.hpl.jena.graph.Triple, com.hp.hpl.jena.db.impl.SpecializedGraph.CompletionFlag)
*/
public void delete(Node n, Triple t, CompletionFlag complete) {
m_reifCache.flushAll();
m_reif.deleteReifStmt( n, t, my_GID);
complete.setDone();
}
/* (non-Javadoc)
* @see com.hp.hpl.jena.db.impl.SpecializedGraphReifier#contains(com.hp.hpl.jena.graph.Node, com.hp.hpl.jena.graph.Triple, com.hp.hpl.jena.db.impl.SpecializedGraph.CompletionFlag)
*/
public boolean contains(Node n, Triple t, CompletionFlag complete) {
if (true)
throw new JenaException("SpecializedGraphReifier.contains called");
return false;
}
/* (non-Javadoc)
* @see com.hp.hpl.jena.db.impl.SpecializedGraphReifier#findReifiedNodes(com.hp.hpl.jena.graph.TripleMatch, com.hp.hpl.jena.db.impl.SpecializedGraph.CompletionFlag)
*/
public ExtendedIterator findReifiedNodes(Triple t, CompletionFlag complete) {
complete.setDone();
return m_reif.findReifStmtURIByTriple(t, my_GID);
}
/* (non-Javadoc)
* @see com.hp.hpl.jena.db.impl.SpecializedGraphReifier#findReifiedTriple(com.hp.hpl.jena.graph.Node, com.hp.hpl.jena.db.impl.SpecializedGraph.CompletionFlag)
*/
public Triple findReifiedTriple(Node n, CompletionFlag complete) {
ResultSetReifIterator it = m_reif.findReifStmt(n, true, my_GID, false);
Triple res = null;
if ( it.hasNext() ) {
res = it.next();
}
complete.setDone();
return res;
}
/** Find all the triples corresponding to a given reified node.
* In a perfect world, there would only ever be one, but when a user calls
* add(Triple) there is nothing in RDF that prevents them from adding several
* subjects,predicates or objects for the same statement.
*
* The resulting Triples may be incomplete, in which case some of the
* nodes may be Node_ANY.
*
* For example, if an application had previously done:
* add( new Triple( a, rdf.subject A )) and
* add( new Triple( a, rdf.object B )) and
* add( new Triple( a, rdf.object B2 ))
*
* Then the result of findReifiedTriple(a, flag) will be an iterator containing
* Triple(A, ANY, B) and Triple(ANY, ANY, B2).
*
* @param n is the Node for which we are querying.
* @param complete is true if we know we've returned all the triples which may exist.
* @return ExtendedIterator.
*/
public ExtendedIterator findReifiedTriples(Node n, CompletionFlag complete) {
complete.setDone();
return m_reif.findReifStmt(n, false, my_GID, true);
}
/**
* Attempt to add all the triples from a graph to the specialized graph
*
* Caution - this call changes the graph passed in, deleting from
* it each triple that is successfully added.
*
* Node that when calling add, if complete is true, then the entire
* graph was added successfully and the graph g will be empty upon
* return. If complete is false, then some triples in the graph could
* not be added. Those triples remain in g after the call returns.
*
* If the triple can't be stored for any reason other than incompatability
* (for example, a lack of disk space) then the implemenation should throw
* a runtime exception.
*
* @param g is a graph containing triples to be added
* @param complete is true if a subsequent call to contains(triple) will return true for any triple in g.
*/
public void add( Graph g, CompletionFlag complete ) {
throw new AddDeniedException( "sorry, not implemented" );
}
/* (non-Javadoc)
* @see com.hp.hpl.jena.db.impl.SpecializedGraph#add(com.hp.hpl.jena.graph.Triple, com.hp.hpl.jena.db.impl.SpecializedGraph.CompletionFlag)
*/
public void add(Triple frag, CompletionFlag complete) throws AlreadyReifiedException {
ReificationStatementMask fragMask = new ReificationStatementMask(frag);
if (fragMask.hasNada())
return;
boolean fragHasType = fragMask.hasType();
Node stmtURI = frag.getSubject();
ReificationCache cachedFrag = m_reifCache.load(stmtURI);
if (cachedFrag == null) {
// not in database
m_reif.storeFrag(stmtURI, frag, fragMask, my_GID);
complete.setDone();
} else {
ReificationStatementMask cachedMask = cachedFrag.getStmtMask();
if (cachedMask.hasIntersect(fragMask)) {
// see if this is a duplicate fragment
boolean dup = fragHasType && cachedMask.hasType();
if (dup == false) {
// not a type fragement; have to search db to check for dup
ExtendedIterator it = m_reif.findFrag (stmtURI, frag, fragMask, my_GID);
dup = it.hasNext();
if ( dup == false ) {
if ( cachedMask.isStmt())
throw new AlreadyReifiedException(frag.getSubject());
// cannot perform a reificiation; store fragment
m_reif.storeFrag(stmtURI, frag, fragMask, my_GID);
m_reifCache.flush(cachedFrag);
}
}
} else {
// reification may be possible; update if possible, else compact
if (cachedFrag.canMerge(fragMask)) {
if ( cachedFrag.canUpdate(fragMask) ) {
m_reif.updateFrag(stmtURI, frag, fragMask, my_GID);
cachedFrag.update(fragMask);
} else
fragCompact(stmtURI);
} else {
// reification not possible
m_reif.storeFrag(stmtURI, frag, fragMask, my_GID);
}
}
}
complete.setDone();
}
/* (non-Javadoc)
* @see com.hp.hpl.jena.db.impl.SpecializedGraph#delete(com.hp.hpl.jena.graph.Triple, com.hp.hpl.jena.db.impl.SpecializedGraph.CompletionFlag)
*/
public void delete(Triple frag, CompletionFlag complete) {
ReificationStatementMask fragMask = new ReificationStatementMask(frag);
if (fragMask.hasNada())
return;
Node stmtURI = frag.getSubject();
ResultSetReifIterator it = m_reif.findFrag(stmtURI, frag, fragMask, my_GID);
if ( it.hasNext() ) {
if ( it.getFragCount() == 1 ) {
/* last fragment in this tuple; can just delete it */
m_reif.deleteFrag(frag, fragMask, my_GID);
it.close();
} else {
/* remove fragment from row */
m_reif.nullifyFrag(stmtURI, fragMask, my_GID);
/* compact remaining fragments, if possible */
it.close();
fragCompact(stmtURI);
}
// remove cache entry, if any
ReificationCache cachedFrag = m_reifCache.lookup(stmtURI);
if ( cachedFrag != null ) m_reifCache.flush(cachedFrag);
}
complete.setDone();
}
/* fragCompact
*
* Compact fragments for a given statement URI.
*
* first, find the unique row for stmtURI that with the HasType Statement fragment.
* if no such row exists, we are done. then, get all fragments for stmtURI and
* try to merge them with the hasType fragment, deleting each as they are merged.
*/
protected void fragCompact ( Node stmtURI ) {
ResultSetReifIterator itHasType;
Triple t;
itHasType = m_reif.findReifStmt(stmtURI,true,my_GID, false);
if ( itHasType.hasNext() ) {
/* something to do */
t = itHasType.next();
if ( itHasType.hasNext() )
throw new JenaException("Multiple HasType fragments for URI");
ReificationStatementMask htMask = new ReificationStatementMask(t);
itHasType.close();
// now, look at fragments and try to merge them with the hasType fragement
ResultSetReifIterator itFrag = m_reif.findReifStmt(stmtURI,false,my_GID, false);
ReificationStatementMask upMask = new ReificationStatementMask();
while ( itFrag.hasNext() ) {
t = itFrag.next();
if ( itFrag.getHasType() ) continue;
ReificationStatementMask fm = new ReificationStatementMask(rowToFrag(stmtURI, t));
if ( htMask.hasIntersect(fm) )
break; // can't merge all fragments
// at this point, we can merge in the current fragment
m_reif.updateFrag(stmtURI, t, fm, my_GID);
htMask.setMerge(fm);
m_reif.deleteFrag(t, fm, my_GID);
}
}
}
protected Triple rowToFrag ( Node stmtURI, Triple row )
{
Node pred = null;
Node obj = null;
int valCnt = 0;
if ( row.getSubject() != null ) {
obj = row.getSubject();
pred = RDF.Nodes.subject;
valCnt++;
}
if ( row.getPredicate() != null ) {
obj = row.getPredicate();
pred = RDF.Nodes.predicate;
valCnt++;
}
if ( row.getObject() != null ) {
obj = row.getObject();
pred = RDF.Nodes.object;
valCnt++;
}
if ( valCnt != 1 )
throw new JenaException("Partially reified row must have exactly one value");
return Triple.create(stmtURI, pred, obj);
}
/* (non-Javadoc)
* @see com.hp.hpl.jena.db.impl.SpecializedGraph#add(java.util.List, com.hp.hpl.jena.db.impl.SpecializedGraph.CompletionFlag)
*/
public void add(List triples, CompletionFlag complete) {
List remainingTriples = new ArrayList();
for( int i=0; i< triples.size(); i++) {
CompletionFlag partialResult = newComplete();
add( triples.get(i), partialResult);
if( !partialResult.isDone())
remainingTriples.add(triples.get(i));
}
triples.clear();
if( remainingTriples.isEmpty())
complete.setDone();
else
triples.addAll(remainingTriples);
}
/* (non-Javadoc)
* @see com.hp.hpl.jena.db.impl.SpecializedGraph#delete(java.util.List, com.hp.hpl.jena.db.impl.SpecializedGraph.CompletionFlag)
*/
public void delete(List triples, CompletionFlag complete) {
boolean result = true;
Iterator it = triples.iterator();
while(it.hasNext()) {
CompletionFlag partialResult = newComplete();
delete( it.next(), partialResult);
result = result && partialResult.isDone();
}
if( result )
complete.setDone();
}
/* (non-Javadoc)
* @see com.hp.hpl.jena.db.impl.SpecializedGraph#tripleCount()
*/
public int tripleCount() {
// A very inefficient, but simple implementation
ExtendedIterator it = find( null, null, null, newComplete() );
int count = 0;
while (it.hasNext()) {
it.next(); count++;
}
it.close();
return count;
}
/* (non-Javadoc)
* @see com.hp.hpl.jena.db.impl.SpecializedGraph#find(com.hp.hpl.jena.graph.TripleMatch, com.hp.hpl.jena.db.impl.SpecializedGraph.CompletionFlag)
*/
public ExtendedIterator find(TripleMatch t, CompletionFlag complete) {
// Node stmtURI = t.getMatchSubject(); // note: can be null
// ResultSetReifIterator it = m_reif.findReifStmt(stmtURI, false, my_GID, true);
// return it.filterKeep( new TripleMatchFilter( t.asTriple() ) );
ResultSetReifIterator it = m_reif.findReifTripleMatch(t, my_GID);
return it;
}
/**
* Tests if a triple is contained in the specialized graph.
* @param t is the triple to be tested
* @param complete is true if the graph can guarantee that
* no other specialized graph could hold any matching triples.
* @return boolean result to indicate if the triple was contained
*/
public boolean contains(Triple t, CompletionFlag complete) {
// A very inefficient, but simple implementation
ExtendedIterator it = find( t, complete );
try { return it.hasNext(); } finally { it.close(); }
}
/*
* @see com.hp.hpl.jena.db.impl.SpecializedGraph#close()
*/
public void close() {
m_reif.close();
}
/*
* @see com.hp.hpl.jena.db.impl.SpecializedGraph#clear()
*/
public void clear() {
m_reif.removeStatementsFromDB(my_GID);
}
static boolean isReifProp ( Node_URI p ) {
return p.equals(RDF.Nodes.subject) ||
p.equals(RDF.Nodes.predicate)||
p.equals(RDF.Nodes.object) ||
p.equals(RDF.Nodes.type);
}
/* (non-Javadoc)
* @see com.hp.hpl.jena.db.impl.SpecializedGraphReifier#graphIdGet()
*/
public int getGraphId() {
return ((DBIDInt)my_GID).getIntID();
}
/* (non-Javadoc)
* @see com.hp.hpl.jena.db.impl.SpecializedGraphReifier#PSetGet()
*/
public IPSet getPSet() {
return m_pset;
}
/* (non-Javadoc)
* @see com.hp.hpl.jena.db.impl.SpecializedGraphReifier#DBPropLSetGet()
*/
public DBPropLSet getDBPropLSet() {
return m_dbPropLSet;
}
/*
* (non-Javadoc)
* @see com.hp.hpl.jena.db.impl.SpecializedGraph#subsumes(com.hp.hpl.jena.graph.Triple, int)
*
* determine if the reifier graph has any triples of the given pattern.
* the table below indicates the return value for each reif style for
* the various types of patterns.
* note: "conc" means the node in the pattern is not a concrete node.
*
* Pattern Minimal Conv Standard
* ANY rdf:subj ANY none none all
* ANY rdf:pred ANY none none all
* ANY rdf:obj ANY none none all
* ANY rdf:type rdf:stmt none none all
* ANY rdf:type conc none none none
* ANY rdf:type !conc none none some
* ANY !conc ANY none none some
* else none none none
*/
public char subsumes ( Triple pattern, int reifBehavior ) {
char res = noTriplesForPattern;
if ( reifBehavior != GraphRDB.OPTIMIZE_ALL_REIFICATIONS_AND_HIDE_NOTHING )
return res;
Node pred = pattern.getPredicate();
if ( pred.isConcrete() ) {
if ( pred.equals(RDF.Nodes.subject) ||
pred.equals(RDF.Nodes.predicate) ||
pred.equals(RDF.Nodes.object) )
res = allTriplesForPattern;
else if ( pred.equals(RDF.Nodes.type) ) {
Node obj = pattern.getObject();
if ( obj.equals(RDF.Nodes.Statement) )
res = allTriplesForPattern;
else if ( !obj.isConcrete() )
res = someTriplesForPattern;
}
} else if ( (pred.isVariable()) || pred.equals(Node.ANY) ) {
res = someTriplesForPattern;
} else
throw new JenaException("Unexpected predicate: " + pred.toString());
return res;
}
}
/*
* (c) Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 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.
*/
© 2015 - 2025 Weber Informatics LLC | Privacy Policy