com.bigdata.rdf.sail.webapp.SD Maven / Gradle / Ivy
/**
Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved.
Contact:
SYSTAP, LLC DBA Blazegraph
2501 Calvert ST NW #106
Washington, DC 20008
[email protected]
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Created on Mar 2, 2012
*/
package com.bigdata.rdf.sail.webapp;
import java.util.Properties;
import org.openrdf.model.BNode;
import org.openrdf.model.Graph;
import org.openrdf.model.URI;
import org.openrdf.model.ValueFactory;
import org.openrdf.model.impl.URIImpl;
import org.openrdf.model.vocabulary.RDF;
import com.bigdata.ha.HAGlue;
import com.bigdata.ha.QuorumService;
import com.bigdata.journal.IIndexManager;
import com.bigdata.journal.IJournal;
import com.bigdata.quorum.Quorum;
import com.bigdata.rdf.axioms.Axioms;
import com.bigdata.rdf.axioms.NoAxioms;
import com.bigdata.rdf.axioms.OwlAxioms;
import com.bigdata.rdf.axioms.RdfsAxioms;
import com.bigdata.rdf.sail.BigdataSail;
import com.bigdata.rdf.store.AbstractTripleStore;
import com.bigdata.rdf.store.BD;
import com.bigdata.rdf.vocab.decls.VoidVocabularyDecl;
import com.bigdata.service.IBigdataFederation;
import com.bigdata.util.ClassPathUtil;
/**
* SPARQL 1.1 Service Description vocabulary class.
*
* @see SPARQL 1.1
* Service Description
*
* @see https://sourceforge.net/apps/trac/bigdata/ticket/500
*
* @author Bryan Thompson
* @version $Id$
*/
public class SD {
static public final String NS = "http://www.w3.org/ns/sparql-service-description#";
static public final URI Service = new URIImpl(NS + "Service");
static public final URI endpoint = new URIImpl(NS + "endpoint");
/**
*
*
*
*/
static public final URI supportedLanguage = new URIImpl(NS
+ "supportedLanguage");
static public final URI SPARQL10Query = new URIImpl(NS + "SPARQL10Query");
static public final URI SPARQL11Query = new URIImpl(NS + "SPARQL11Query");
static public final URI SPARQL11Update = new URIImpl(NS + "SPARQL11Update");
/**
* Relates an instance of {@link #Service} to a format that is supported for
* serializing query results. URIs for commonly used serialization formats
* are defined by Unique URIs for File Formats. For formats that do not have
* an existing URI, the
* media_type and preferred_suffix
* properties defined in that document SHOULD be used to describe the
* format.
*
* @see Unique URIs for File
* Formats
*/
// *
// *
// *
// *
static public final URI resultFormat = new URIImpl(NS + "resultFormat");
/**
* Relates an instance of sd:Service to a format that is supported for
* parsing RDF input; for example, via a SPARQL 1.1 Update LOAD statement,
* or when URIs are dereferenced in FROM/FROM NAMED/USING/USING NAMED
* clauses (see also sd:DereferencesURIs below).
*
* URIs for commonly used serialization formats are defined by Unique URIs
* for File Formats. For formats that do not have an existing URI, the media_type and preferred_suffix
* properties defined in that document SHOULD be used to describe the
* format.
*
* @see Unique URIs for File
* Formats
*/
static public final URI inputFormat = new URIImpl(NS + "inputFormat");
/**
*
*
*
*/
static public final URI feature = new URIImpl(NS + "feature");
static public final URI DereferencesURIs = new URIImpl(NS + "DereferencesURIs");
static public final URI UnionDefaultGraph = new URIImpl(NS + "UnionDefaultGraph");
static public final URI RequiresDataset = new URIImpl(NS + "RequiresDataset");
static public final URI EmptyGraphs = new URIImpl(NS + "EmptyGraphs");
static public final URI BasicFederatedQuery = new URIImpl(NS + "BasicFederatedQuery");
/**
* The namespace for the bigdata specific features.
*/
static public final String BDFNS = BD.NAMESPACE+"/features/";
/*
* KB modes.
*/
static public final URI ModeTriples = new URIImpl(BDFNS + "KB/Mode/Triples");
static public final URI ModeQuads = new URIImpl(BDFNS + "KB/Mode/Quads");
static public final URI ModeSids = new URIImpl(BDFNS + "KB/Mode/Sids");
/*
* Text Index modes.
*/
static public final URI TextIndexValueCentric = new URIImpl(BDFNS
+ "KB/TextIndex/ValueCentric");
static public final URI TextIndexSubjectCentric = new URIImpl(BDFNS
+ "KB/TextIndex/SubjectCentric");
/*
* Misc KB features.
*/
static public final URI TruthMaintenance = new URIImpl(BDFNS
+ "KB/TruthMaintenance");
static public final URI IsolatableIndices = new URIImpl(BDFNS
+ "KB/IsolatableIndices");
/**
* A highly available deployment - this feature refers to the presence of
* the {@link HAGlue} interface, the capability for online backups, and the
* existence of a targer {@link #ReplicationFactor}. You must consult the
* target {@link #ReplicationFactor} in order to determine whether the
* database is in principle capable of tolerating one or more failures and
* the actual #of running joined instances to determine whether the database
* can withstand a failure.
*/
static public final URI HighlyAvailable = new URIImpl(BDFNS
+ "HighlyAvailable");
/**
* The value of this feature is the target replication factor for the
* database expressed as an xsd:int
. If this is ONE (1), then
* the database is setup with a quorum and has the capability for online
* backup, but it is not replicated. TWO (2) indicates mirroring, but is not
* highly available. THREE (3) is the minimum configuration that can
* withstand a failure.
*/
static public final URI ReplicationFactor = new URIImpl(BDFNS
+ "replicationFactor");
/**
* An {@link IBigdataFederation}.
*/
static public final URI ScaleOut = new URIImpl(BDFNS
+ "ScaleOut");
/**
* This indicates that the namespace is compatible with mapgraph (aka GPU)
* acceleration, but this does not indicate whether or not the namespace is
* currently loaded in the mapgraph-runtime.
*/
static public final URI MapgraphCompatible = new URIImpl(BDFNS + "MapgraphCompatible");
/**
* This indicates that the namespace is currently loaded within the
* mapgraph-runtime.
*/
static public final URI MapgraphAcceleration = new URIImpl(BDFNS + "MapgraphAcceleration");
/**
* The namespace
for this KB instance as configured by the
* {@link BigdataSail.Options#NAMESPACE} property.
*/
static public final URI KB_NAMESPACE = new URIImpl(BDFNS
+ "KB/Namespace");
/**
*
* http://www.w3.org/ns/entailment/OWL-RDF-Based
* http://www.w3.org/ns/entailment/RDFS
* http://www.w3.org/ns/owl-profile/RL
*
*
* @see Unique URIs for Semantic
* Web Entailment Regimes [ENTAILMENT] (members of the class
* sd:EntailmentRegime usable with the properties
* sd:defaultEntailmentRegime and sd:entailmentRegime)
*
* @see Unique URIs for OWL 2
* Profiles [OWL2PROF] (members of the class sd:EntailmentProfile
* usable with the properties sd:defaultSupportedEntailmentProfile and
* sd:supportedEntailmentProfile)
*/
static public final URI defaultEntailmentRegime = new URIImpl(NS
+ "defaultEntailmentRegime");
static public final URI entailmentRegime = new URIImpl(NS
+ "entailmentRegime");
static public final URI supportedEntailmentProfile = new URIImpl(NS
+ "supportedEntailmentProfile");
static public final URI extensionFunction = new URIImpl(NS
+ "extensionFunction");
/*
* Entailment regimes.
*/
/**
* Simple Entailment
*
* @see http://www.w3.org/ns/entailment/Simple
*/
static public final URI simpleEntailment = new URIImpl(
"http://www.w3.org/ns/entailment/Simple");
/**
* RDF Entailment
*
* @see http://www.w3.org/ns/entailment/RDF
*/
static public final URI rdfEntailment = new URIImpl(
"http://www.w3.org/ns/entailment/RDF");
/**
* RDFS Entailment
*
* @see http://www.w3.org/ns/entailment/RDFS
*/
static public final URI rdfsEntailment = new URIImpl(
"http://www.w3.org/ns/entailment/RDFS");
static public final URI Function = new URIImpl(NS + "Function");
static public final URI defaultDataset = new URIImpl(NS + "defaultDataset");
static public final URI Dataset = new URIImpl(NS + "Dataset");
static public final URI defaultGraph = new URIImpl(NS + "defaultGraph");
static public final URI Graph = new URIImpl(NS + "Graph");
static public final URI namedGraph = new URIImpl(NS + "namedGraph");
static public final URI NamedGraph = new URIImpl(NS + "NamedGraph");
static public final URI name = new URIImpl(NS + "name");
/*
* RDF data
*
* TODO RDFa: http://www.w3.org/ns/formats/RDFa
*/
/**
* Unique URI for RDF/XML
*
* @see http://www.w3.org/ns/formats/
*/
static public final URI RDFXML = new URIImpl(
"http://www.w3.org/ns/formats/RDF_XML");
/**
* Unique URI for NTRIPLES
*
* @see http://www.w3.org/ns/formats/
*/
static public final URI NTRIPLES = new URIImpl(
"http://www.w3.org/ns/formats/N-Triples");
/**
* Unique URI for TURTLE
*
* @see http://www.w3.org/ns/formats/
*/
static public final URI TURTLE = new URIImpl(
"http://www.w3.org/ns/formats/Turtle");
// RDR specific extension of TURTLE.
static public final URI TURTLE_RDR = new URIImpl(
"http://www.bigdata.com/ns/formats/Turtle-RDR");
/**
* Unique URI for N3.
*
* @see http://www.w3.org/ns/formats/
*/
static public final URI N3 = new URIImpl("http://www.w3.org/ns/formats/N3");
// /**
// * TODO The TriX file format.
// */
// public static final RDFFormat TRIX = new RDFFormat("TriX",
// "application/trix", Charset.forName("UTF-8"),
// Arrays.asList("xml", "trix"), false, true);
/**
* The TriG file
* format.
*/
static public final URI TRIG = new URIImpl(
"http://www.wiwiss.fu-berlin.de/suhl/bizer/TriG/Spec/");
// /**
// * TODO A binary RDF format (openrdf)
// *
// * @see http://www.openrdf.org/issues/browse/RIO-79 (Request for unique
// URI)
// */
// public static final RDFFormat BINARY = new RDFFormat("BinaryRDF",
// "application/x-binary-rdf", null,
// "brf", true, true);
/**
* The URI that identifies the N-Quads syntax is
* http://sw.deri.org/2008/07/n-quads/#n-quads
.
*
* @see http://sw.deri.org/2008/07/n-quads/
*/
static public final URI NQUADS = new URIImpl(
"http://sw.deri.org/2008/07/n-quads/#n-quads");
// RDR specific extension of N-Triples.
static public final URI NTRIPLES_RDR = new URIImpl(
"http://www.bigdata.com/ns/formats/N-Triples-RDR");
/*
* SPARQL results
*/
/**
* Unique URI for SPARQL Results in XML
*
* @see http://www.w3.org/ns/formats/
*/
static public final URI SPARQL_RESULTS_XML = new URIImpl(
"http://www.w3.org/ns/formats/SPARQL_Results_XML");
/**
* Unique URI for SPARQL Results in JSON
*
* @see http://www.w3.org/ns/formats/
*
* TODO Does openrdf support this yet?
*/
static public final URI SPARQL_RESULTS_JSON = new URIImpl(
"http://www.w3.org/ns/formats/SPARQL_Results_JSON");
/**
* Unique URI for SPARQL Results in CSV
*
* @see http://www.w3.org/ns/formats/
*/
static public final URI SPARQL_RESULTS_CSV = new URIImpl(
"http://www.w3.org/ns/formats/SPARQL_Results_CSV");
/**
* Unique URI for SPARQL Results in TSV
*
* @see http://www.w3.org/ns/formats/
*/
static public final URI SPARQL_RESULTS_TSV = new URIImpl(
"http://www.w3.org/ns/formats/SPARQL_Results_TSV");
// TODO openrdf binary format.
// /**
// * Unique URI for SPARQL Results in TSV
// *
// * @see TupleQueryResultFormat#BINARY
// *
// * @see http://www.openrdf.org/issues/browse/RIO-79 (Request for unique URI)
// */
// static public final URI SPARQL_RESULTS_OPENRDF_BINARY = new URIImpl(
// "http://www.w3.org/ns/formats/SPARQL_Results_TSV");
/**
* The graph in which the service description is accumulated (from the
* constructor).
*/
protected final Graph g;
/**
* The KB instance that is being described (from the constructor).
*/
protected final AbstractTripleStore tripleStore;
/**
* The service end point (from the constructor).
*/
protected final String[] serviceURI;
/**
* The value factory used to create values for the service description graph
* {@link #g}.
*/
protected final ValueFactory f;
/**
* The resource which models the service.
*/
protected final BNode aService;
/**
* The resource which models the default data set for the service.
*/
protected final BNode aDefaultDataset;
// /**
// * The resource which models the default graph in the default data set for
// * the service.
// */
// protected final BNode aDefaultGraph;
/**
*
* @param g
* Where to assemble the description.
* @param tripleStore
* The KB instance to be described.
* @param serviceURIs
* One or more service end points for that KB instance.
*
* @see #describeService()
*/
public SD(final Graph g, final AbstractTripleStore tripleStore,
final String... serviceURI) {
if (g == null)
throw new IllegalArgumentException();
if (tripleStore == null)
throw new IllegalArgumentException();
if (serviceURI == null)
throw new IllegalArgumentException();
if (serviceURI.length == 0)
throw new IllegalArgumentException();
for (String s : serviceURI)
if (s == null)
throw new IllegalArgumentException();
this.g = g;
this.tripleStore = tripleStore;
this.serviceURI = serviceURI;
this.f = g.getValueFactory();
aService = f.createBNode("service");
aDefaultDataset = f.createBNode("defaultDataset");
}
/**
* Collect various information, building up a service description graph.
*
* @param describeStatistics
* When true
, the VoID description will include the
* {@link VoidVocabularyDecl#vocabulary} declarations, the
* property partition statistics, and the class partition
* statistics.
* @param describeNamedGraphs
* When true
and the KB instance is in the
* quads
mode, each named graph will also be
* described in in the same level of detail as the default graph.
* Otherwise only the default graph will be described.
*/
public void describeService(final boolean describeStatistics,
final boolean describeNamedGraphs) {
g.add(aService, RDF.TYPE, SD.Service);
// Service end point.
describeServiceEndpoints();
// Describe the supported languages (SPARQL Query, Update, etc).
describeLanguages();
// Describe other supported features.
describeOtherFeatures();
// Describe the supported data formats.
describeInputFormats();
describeResultFormats();
// Describe the entailment regime (if any).
describeEntailmentRegime();
// Describe the data set for this KB instance.
{
// Default data set
g.add(aService, SD.defaultDataset, aDefaultDataset);
g.add(aDefaultDataset, RDF.TYPE, SD.Dataset);
final VoID v = new VoID(g, tripleStore, serviceURI, aDefaultDataset);
v.describeDataSet(describeStatistics, describeNamedGraphs);
}
}
/**
* Describe the service end point(s).
*
* @see #endpoint
*/
protected void describeServiceEndpoints() {
for (String uri : serviceURI) {
g.add(aService, SD.endpoint, g.getValueFactory().createURI(uri));
}
}
/**
* Describe the supported Query Languages
*/
protected void describeLanguages() {
g.add(aService, SD.supportedLanguage, SD.SPARQL10Query);
g.add(aService, SD.supportedLanguage, SD.SPARQL11Query);
g.add(aService, SD.supportedLanguage, SD.SPARQL11Update);
}
/**
* Describe the supported input formats.
*
* @see http://www.openrdf.org/issues/browse/RIO-79 (Request for unique
* URIs)
*
* @see #inputFormat
*/
protected void describeInputFormats() {
g.add(aService, SD.inputFormat, SD.RDFXML);
g.add(aService, SD.inputFormat, SD.NTRIPLES);
g.add(aService, SD.inputFormat, SD.TURTLE);
g.add(aService, SD.inputFormat, SD.N3);
// g.add(service, SD.inputFormat, SD.TRIX); // TODO TRIX
g.add(aService, SD.inputFormat, SD.TRIG);
// g.add(service, SD.inputFormat, SD.BINARY); // TODO BINARY
g.add(aService, SD.inputFormat, SD.NQUADS);
if (tripleStore.getStatementIdentifiers()) {
// RDR specific data interchange.
g.add(aService, SD.inputFormat, SD.NTRIPLES_RDR);
g.add(aService, SD.inputFormat, SD.TURTLE_RDR);
}
g.add(aService, SD.inputFormat, SD.SPARQL_RESULTS_XML);
g.add(aService, SD.inputFormat, SD.SPARQL_RESULTS_JSON);
g.add(aService, SD.inputFormat, SD.SPARQL_RESULTS_CSV);
g.add(aService, SD.inputFormat, SD.SPARQL_RESULTS_TSV);
// g.add(service,SD.inputFormat,SD.SPARQL_RESULTS_OPENRDF_BINARY);
}
/**
* Describe the supported result formats.
*
* @see #resultFormat
*/
protected void describeResultFormats() {
g.add(aService, SD.resultFormat, SD.RDFXML);
g.add(aService, SD.resultFormat, SD.NTRIPLES);
g.add(aService, SD.resultFormat, SD.TURTLE);
g.add(aService, SD.resultFormat, SD.N3);
// g.add(service, SD.resultFormat, SD.TRIX); // TODO TRIX
g.add(aService, SD.resultFormat, SD.TRIG);
// g.add(service, SD.resultFormat, SD.BINARY); // TODO BINARY
// g.add(service, SD.resultFormat, SD.NQUADS); // TODO NQuads
// writer
g.add(aService, SD.resultFormat, SD.SPARQL_RESULTS_XML);
g.add(aService, SD.resultFormat, SD.SPARQL_RESULTS_JSON);
g.add(aService, SD.resultFormat, SD.SPARQL_RESULTS_CSV);
g.add(aService, SD.resultFormat, SD.SPARQL_RESULTS_TSV);
// g.add(service, SD.resultFormat,
// SD.SPARQL_RESULTS_OPENRDF_BINARY);
}
/**
* Describe non-language features.
*
* Note: Do NOT report the backing store type (Journal, TemporaryStore,
* Federation), the journal buffer mode, etc. here. That is all back end
* stuff and should be visible through an API which can be separately
* secured. The ServiceDescription is supposed to be "web" facing so it
* should not have that low level stuff.
*
* TODO sd:languageExtension or sd:feature could be used for query hints,
* NAMED SUBQUERY, the NSS REST API features, etc.
*/
protected void describeOtherFeatures() {
g.add(aService, SD.feature, SD.BasicFederatedQuery);
if (tripleStore.isQuads()) {
g.add(aService, SD.feature, SD.UnionDefaultGraph);
g.add(aService, SD.feature, ModeQuads);
} else if(tripleStore.isStatementIdentifiers()) {
g.add(aService, SD.feature, ModeSids);
} else {
g.add(aService, SD.feature, ModeTriples);
}
if (tripleStore.getLexiconRelation().isTextIndex()) {
g.add(aService, SD.feature, TextIndexValueCentric);
}
if (tripleStore.getLexiconRelation().isSubjectCentricTextIndex()) {
/*
* @deprecated Feature was never completed due to scalability
* issues. See BZLG-1548, BLZG-563. Code should be removed.
*/
g.add(aService, SD.feature, TextIndexSubjectCentric);
}
final Properties properties = tripleStore.getProperties();
if (Boolean.valueOf(properties.getProperty(
BigdataSail.Options.TRUTH_MAINTENANCE,
BigdataSail.Options.DEFAULT_TRUTH_MAINTENANCE))) {
g.add(aService, SD.feature, TruthMaintenance);
}
if (Boolean.valueOf(properties.getProperty(
BigdataSail.Options.ISOLATABLE_INDICES,
BigdataSail.Options.DEFAULT_ISOLATABLE_INDICES))) {
g.add(aService, SD.feature, IsolatableIndices);
}
if (isMapgraphCompatible()) {
g.add(aService, SD.feature, MapgraphCompatible);
if (isMapgraphAccelerated()) {
g.add(aService, SD.feature, MapgraphAcceleration);
}
}
{
final IIndexManager indexManager = tripleStore.getIndexManager();
if (indexManager instanceof IJournal) {
final IJournal jnl = (IJournal) indexManager;
final Quorum> quorum = jnl
.getQuorum();
if (quorum != null) {
final int k = quorum.replicationFactor();
g.add(aService, SD.ReplicationFactor, tripleStore
.getValueFactory().createLiteral(k));
g.add(aService, SD.feature, HighlyAvailable);
}
} else if (indexManager instanceof IBigdataFederation) {
g.add(aService, SD.feature, ScaleOut);
}
}
}
/**
* Describe the entailment regime.
*
* TODO The Axioms interface could self-report this.
*/
protected void describeEntailmentRegime() {
if (!tripleStore.isQuads())
return;
final URI entailmentRegime;
final Axioms axioms = tripleStore.getAxioms();
if (axioms == null || axioms instanceof NoAxioms) {
entailmentRegime = SD.simpleEntailment;
} else if (axioms instanceof OwlAxioms) {
// TODO This is really the RDFS+ entailment regime.
entailmentRegime = SD.rdfsEntailment;
} else if (axioms instanceof RdfsAxioms) {
entailmentRegime = SD.rdfsEntailment;
} else {
// Unknown.
entailmentRegime = null;
}
if (entailmentRegime != null)
g.add(aService, SD.entailmentRegime, entailmentRegime);
}
/**
* Return true iff the namespace is compatible with mapgraph acceleration.
*
* @see https://github.com/SYSTAP/bigdata-gpu/issues/134 (Need means to
* publish/update/drop graph in the mapgraph-runtime)
*/
boolean isMapgraphCompatible() {
final IFeatureSupported obj = ClassPathUtil.classForName(//
"com.blazegraph.rdf.gpu.MapgraphCompatibleNamespace", // preferredClassName,
null, // defaultClass,
IFeatureSupported.class, // sharedInterface,
getClass().getClassLoader() // classLoader
);
if (obj == null)
return false;
return obj.isSupported(tripleStore);
}
/**
* Return true iff the namespace is currently loaded in the mapgraph runtime.
*
* @see https://github.com/SYSTAP/bigdata-gpu/issues/134 (Need means to
* publish/update/drop graph in the mapgraph-runtime)
*/
boolean isMapgraphAccelerated() {
final IFeatureSupported obj = ClassPathUtil.classForName(//
"com.blazegraph.rdf.gpu.MapgraphAcceleratedNamespace", // preferredClassName,
null, // defaultClass,
IFeatureSupported.class, // sharedInterface,
getClass().getClassLoader() // classLoader
);
if (obj == null)
return false;
return obj.isSupported(tripleStore);
}
}