/*
* Copyright Aduna (http://www.aduna-software.com/) (c) 2008.
*
* Licensed under the Aduna BSD-style license.
*/
package org.openrdf.sail.rdbms;
import java.sql.SQLException;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.openrdf.model.BNode;
import org.openrdf.model.Literal;
import org.openrdf.model.Resource;
import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import org.openrdf.model.ValueFactory;
import org.openrdf.model.impl.ValueFactoryBase;
import org.openrdf.sail.rdbms.exceptions.RdbmsException;
import org.openrdf.sail.rdbms.exceptions.RdbmsRuntimeException;
import org.openrdf.sail.rdbms.managers.BNodeManager;
import org.openrdf.sail.rdbms.managers.LiteralManager;
import org.openrdf.sail.rdbms.managers.PredicateManager;
import org.openrdf.sail.rdbms.managers.UriManager;
import org.openrdf.sail.rdbms.model.RdbmsBNode;
import org.openrdf.sail.rdbms.model.RdbmsLiteral;
import org.openrdf.sail.rdbms.model.RdbmsResource;
import org.openrdf.sail.rdbms.model.RdbmsStatement;
import org.openrdf.sail.rdbms.model.RdbmsURI;
import org.openrdf.sail.rdbms.model.RdbmsValue;
import org.openrdf.sail.rdbms.schema.IdSequence;
import org.openrdf.sail.rdbms.schema.LiteralTable;
import org.openrdf.sail.rdbms.schema.ValueTable;
/**
* Provides basic value creation both for traditional values as well as values
* with an internal id. {@link RdbmsValue}s behaviour similar to the default
* {@link Value} implementation with the addition that they also include an
* internal id and a version associated with that id. The internal ids should
* not be accessed directly, but rather either through this class or the
* corresponding manager class.
*
* @author James Leigh
*
*/
public class RdbmsValueFactory extends ValueFactoryBase {
@Deprecated
public static final String NIL_LABEL = "nil";
private ValueFactory vf;
private BNodeManager bnodes;
private UriManager uris;
private LiteralManager literals;
private PredicateManager predicates;
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private IdSequence ids;
public void setIdSequence(IdSequence ids) {
this.ids = ids;
}
public void setBNodeManager(BNodeManager bnodes) {
this.bnodes = bnodes;
}
public void setURIManager(UriManager uris) {
this.uris = uris;
}
public void setLiteralManager(LiteralManager literals) {
this.literals = literals;
}
public void setPredicateManager(PredicateManager predicates) {
this.predicates = predicates;
}
public void setDelegate(ValueFactory vf) {
this.vf = vf;
}
public void flush() throws RdbmsException {
try {
bnodes.flush();
uris.flush();
literals.flush();
} catch (SQLException e) {
throw new RdbmsException(e);
}
catch (InterruptedException e) {
throw new RdbmsException(e);
}
}
public RdbmsBNode createBNode(String nodeID) {
RdbmsBNode resource = bnodes.findInCache(nodeID);
if (resource == null) {
try {
BNode impl = vf.createBNode(nodeID);
resource = new RdbmsBNode(impl);
bnodes.cache(resource);
} catch (SQLException e) {
throw new RdbmsRuntimeException(e);
} catch (InterruptedException e) {
throw new RdbmsRuntimeException(e);
}
}
return resource;
}
public RdbmsLiteral createLiteral(String label) {
return asRdbmsLiteral(vf.createLiteral(label), null);
}
public RdbmsLiteral createLiteral(String label, String language) {
if (LiteralTable.ONLY_INSERT_LABEL)
return createLiteral(label);
return asRdbmsLiteral(vf.createLiteral(label, language), null);
}
public RdbmsLiteral createLiteral(String label, URI datatype) {
if (LiteralTable.ONLY_INSERT_LABEL)
return createLiteral(label);
return asRdbmsLiteral(vf.createLiteral(label, datatype), null);
}
public RdbmsLiteral createLiteral(String label, URI datatype, URI predicate) {
if (LiteralTable.ONLY_INSERT_LABEL)
return createLiteral(label);
return asRdbmsLiteral(vf.createLiteral(label, datatype), predicate);
}
public RdbmsStatement createStatement(Resource subject, URI predicate,
Value object, boolean explicit) {
return createStatement(subject, predicate, object, explicit, null);
}
public Statement createStatement(Resource subject, URI predicate,
Value object) {
return createStatement(subject, predicate, object, true, null);
}
public Statement createStatement(Resource subject, URI predicate,
Value object, Resource context) {
return createStatement(subject, predicate, object, true, context);
}
public RdbmsStatement createStatement(Resource subject, URI predicate,
Value object, boolean explicit, Resource context) {
RdbmsResource subj = asRdbmsResource(subject);
RdbmsURI pred = asRdbmsURI(predicate);
RdbmsValue obj = asRdbmsValue(object, predicate);
RdbmsResource ctx = asRdbmsResource(context);
return new RdbmsStatement(subj, pred, obj, explicit, ctx);
}
public RdbmsURI createURI(String uri) {
RdbmsURI resource = uris.findInCache(uri);
if (resource == null) {
try {
URI impl = vf.createURI(uri);
resource = new RdbmsURI(impl);
uris.cache(resource);
} catch (SQLException e) {
throw new RdbmsRuntimeException(e);
} catch (InterruptedException e) {
throw new RdbmsRuntimeException(e);
}
}
return resource;
}
public RdbmsURI createURI(String namespace, String localName) {
return createURI(namespace + localName);
}
public RdbmsResource getRdbmsResource(Number num, String stringValue) {
Number id = ids.idOf(num);
if (ids.isURI(id))
return new RdbmsURI(id, uris.getIdVersion(), vf.createURI(stringValue));
return new RdbmsBNode(id, bnodes.getIdVersion(), vf.createBNode(stringValue));
}
public RdbmsLiteral getRdbmsLiteral(Number num, String label, String language,
String datatype) {
Number id = ids.idOf(num);
if (datatype == null && language == null)
return new RdbmsLiteral(id, literals.getIdVersion(), vf.createLiteral(label), null);
if (datatype == null)
return new RdbmsLiteral(id, literals.getIdVersion(), vf.createLiteral(label, language), null);
return new RdbmsLiteral(id, literals.getIdVersion(), vf.createLiteral(label, vf.createURI(datatype)), null);
}
public RdbmsResource asRdbmsResource(Resource node) {
if (node == null)
return null;
if (node instanceof URI)
return asRdbmsURI((URI) node);
if (node instanceof RdbmsBNode) {
try {
bnodes.cache((RdbmsBNode) node);
return (RdbmsBNode) node;
} catch (SQLException e) {
throw new RdbmsRuntimeException(e);
} catch (InterruptedException e) {
throw new RdbmsRuntimeException(e);
}
}
return createBNode(((BNode) node).getID());
}
public RdbmsURI asRdbmsURI(URI uri) {
if (uri == null)
return null;
if (uri instanceof RdbmsURI) {
try {
uris.cache((RdbmsURI) uri);
return (RdbmsURI) uri;
} catch (SQLException e) {
throw new RdbmsRuntimeException(e);
} catch (InterruptedException e) {
throw new RdbmsRuntimeException(e);
}
}
return createURI(uri.stringValue());
}
public RdbmsValue asRdbmsValue(Value value, URI predicate) {
if (value == null)
return null;
if (value instanceof Literal)
return asRdbmsLiteral((Literal) value, predicate);
return asRdbmsResource((Resource) value);
}
public RdbmsLiteral asRdbmsLiteral(Literal literal, URI predicate) {
try {
if (literal instanceof RdbmsLiteral) {
literals.cache((RdbmsLiteral) literal);
((RdbmsLiteral)literal).setPredicate(predicate);
return (RdbmsLiteral) literal;
}
RdbmsLiteral lit = literals.findInCache(literal);
if (lit == null) {
lit = new RdbmsLiteral(literal, predicate);
literals.cache(lit);
}
return lit;
} catch (SQLException e) {
throw new RdbmsRuntimeException(e);
} catch (InterruptedException e) {
throw new RdbmsRuntimeException(e);
}
}
public RdbmsResource[] asRdbmsResource(Resource... contexts) {
RdbmsResource[] ctxs = new RdbmsResource[contexts.length];
for (int i = 0; i < ctxs.length; i++) {
ctxs[i] = asRdbmsResource(contexts[i]);
}
return ctxs;
}
public RdbmsStatement asRdbmsStatement(Statement stmt, boolean explicit) {
if (stmt instanceof RdbmsStatement)
return (RdbmsStatement) stmt;
Resource s = stmt.getSubject();
URI p = stmt.getPredicate();
Value o = stmt.getObject();
Resource c = stmt.getContext();
return createStatement(s, p, o, explicit, c);
}
public Number getInternalId(Value r)
throws RdbmsException
{
return getInternalId(r, null);
}
public Number getInternalId(Value r, URI predicate)
throws RdbmsException
{
try {
if (r == null)
return ValueTable.NIL_ID;
RdbmsValue value = asRdbmsValue(r, predicate);
if (value instanceof RdbmsURI)
return uris.getInternalId((RdbmsURI)value);
if (value instanceof RdbmsBNode)
return bnodes.getInternalId((RdbmsBNode)value);
return literals.getInternalId((RdbmsLiteral)value);
}
catch (SQLException e) {
throw new RdbmsException(e);
} catch (InterruptedException e) {
throw new RdbmsRuntimeException(e);
}
}
public Number getPredicateId(RdbmsURI predicate) throws RdbmsException {
try {
return predicates.getIdOfPredicate(predicate);
} catch (SQLException e) {
throw new RdbmsException(e);
} catch (InterruptedException e) {
throw new RdbmsRuntimeException(e);
}
}
public Lock getIdReadLock() {
return lock.readLock();
}
public Lock getIdWriteLock() {
return lock.writeLock();
}
}