/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
package org.apache.jena.rdf.model.impl;
import java.io.* ;
import java.net.URL ;
import java.util.* ;
import java.util.function.Supplier ;
import org.apache.jena.datatypes.DatatypeFormatException ;
import org.apache.jena.datatypes.RDFDatatype ;
import org.apache.jena.datatypes.TypeMapper ;
import org.apache.jena.datatypes.xsd.XSDDatatype ;
import org.apache.jena.datatypes.xsd.XSDDateTime ;
import org.apache.jena.enhanced.BuiltinPersonalities ;
import org.apache.jena.enhanced.EnhGraph ;
import org.apache.jena.enhanced.Personality ;
import org.apache.jena.graph.* ;
import org.apache.jena.graph.impl.LiteralLabel ;
import org.apache.jena.graph.impl.LiteralLabelFactory ;
import org.apache.jena.rdf.model.* ;
import org.apache.jena.shared.* ;
import org.apache.jena.shared.impl.PrefixMappingImpl ;
import org.apache.jena.system.JenaSystem ;
import org.apache.jena.util.CollectionFactory ;
import org.apache.jena.util.iterator.* ;
import org.apache.jena.vocabulary.RDF ;
/** Common methods for model implementations.
*
* <P>This class implements common methods, mainly convenience methods, for
* model implementations. It is intended use is as a base class from which
* model implemenations can be derived.</P>
*/
public class ModelCom extends EnhGraph
implements Model, PrefixMapping, Lock
{
private static final RDFReaderF readerFactory = new RDFReaderFImpl();
private static final RDFWriterF writerFactory = new RDFWriterFImpl();
private Lock modelLock = null ;
private static PrefixMapping defaultPrefixMapping = PrefixMapping.Factory.create();
static {
// This forces RIOT (in ARQ) to initialize but after Jena readers/writers
// have cleanly initialized from the calls of RDFReaderFImpl and RDFWriterFImpl
// above. RIOT initialization happens before model.read can be called.
JenaSystem.init() ;
}
/**
make a model based on the specified graph
*/
public ModelCom( Graph base )
{ this( base, BuiltinPersonalities.model ); }
public ModelCom( Graph base, Personality<RDFNode> personality )
{ super( base, personality );
withDefaultMappings( defaultPrefixMapping ); }
public static PrefixMapping getDefaultModelPrefixes()
{ return defaultPrefixMapping; }
public static PrefixMapping setDefaultModelPrefixes(PrefixMapping pm)
{
PrefixMapping result = defaultPrefixMapping ;
defaultPrefixMapping = pm ;
return result ;
}
@Override
public Graph getGraph()
{ return graph; }
protected static Model createWorkModel()
{ return ModelFactory.createDefaultModel(); }
@Override
public RDFNode asRDFNode( Node n )
{
return n.isLiteral()
? (RDFNode) this.getNodeAs( n, Literal.class )
: (RDFNode) this.getNodeAs( n, Resource.class );
}
@Override
public Resource wrapAsResource( Node n )
{
if (n.isLiteral())
throw new UnsupportedOperationException( "literal cannot be converted to Resource" );
return this.getNodeAs( n, Resource.class );
}
/**
the ModelReifier does everything to do with reification.
*/
protected ModelReifier modelReifier = new ModelReifier( this );
@Override
@Deprecated public Resource getResource(String uri, ResourceF f) {
try {
return f.createResource(getResource(uri));
} catch (Exception e) {
throw new JenaException(e);
}
}
@Override
public Model addLiteral( Resource s, Property p, boolean o )
{ return add(s, p, createTypedLiteral( o ) ); }
@Override
public Model addLiteral( Resource s, Property p, long o )
{ return add(s, p, createTypedLiteral( o ) ); }
@Override
public Model addLiteral( Resource s, Property p, int o )
{ return add(s, p, createTypedLiteral( o ) ); }
@Override
public Model addLiteral( Resource s, Property p, char o )
{ return add(s, p, createTypedLiteral( o ) ); }
@Override
public Model addLiteral( Resource s, Property p, float o )
{ return add( s, p, createTypedLiteral( o ) ); }
@Override
public Model addLiteral( Resource s, Property p, double o )
{ return add(s, p, createTypedLiteral( o ) ); }
@Override
public Model add(Resource s, Property p, String o) {
return add( s, p, o, "", false );
}
@Override
public Model add(Resource s, Property p, String o, boolean wellFormed)
{
add( s, p, literal( o, "", wellFormed ) );
return this;
}
public Model add( Resource s, Property p, String o, String lang,
boolean wellFormed) {
add( s, p, literal( o, lang, wellFormed ) );
return this;
}
@Override
public Model add(Resource s, Property p, String lex, RDFDatatype datatype)
{
add( s, p, literal( lex, datatype)) ;
return this;
}
private Literal literal( String s, String lang, boolean wellFormed )
{ return new LiteralImpl( NodeFactory.createLiteral( s, lang, wellFormed), this ); }
private Literal literal( String lex, RDFDatatype datatype)
{ return new LiteralImpl( NodeFactory.createLiteral( lex, datatype), this ); }
@Override
public Model add( Resource s, Property p, String o, String l )
{ return add( s, p, o, l, false ); }
@Override
@Deprecated public Model addLiteral( Resource s, Property p, Object o )
{ return add( s, p, asObject( o ) ); }
@Override
public Model addLiteral( Resource s, Property p, Literal o )
{ return add( s, p, o ); }
private RDFNode asObject( Object o )
{ return o instanceof RDFNode ? (RDFNode) o : createTypedLiteral( o ); }
@Override
public Model add( StmtIterator iter ) {
try { GraphUtil.add( getGraph(), asTriples( iter ) ); }
finally { iter.close(); }
return this;
}
@Override
public Model add(Model m) {
GraphUtil.addInto(getGraph(), m.getGraph()) ;
return this ;
}
@Override
public RDFReader getReader() {
return readerFactory.getReader();
}
@Override
public RDFReader getReader(String lang) {
return readerFactory.getReader(lang);
}
/** @deprecated Use {@code org.apache.jena.riot.RDFParserRegistry.register}
*/
@Override
@Deprecated
public String setReaderClassName(String lang, String className) {
return readerFactory.setReaderClassName(lang, className);
}
@Override
@Deprecated
public void resetRDFReaderF()
{
readerFactory.resetRDFReaderF();
}
@Override
@Deprecated
public String removeReader( String lang ) throws IllegalArgumentException
{
return readerFactory.removeReader(lang);
}
@Override
public Model read(String url) {
readerFactory .getReader() .read(this, url);
return this;
}
@Override
public Model read(Reader reader, String base) {
readerFactory .getReader() .read(this, reader, base);
return this;
}
@Override
public Model read(InputStream reader, String base) {
readerFactory .getReader() .read(this, reader, base);
return this;
}
@Override
public Model read(String url, String lang) {
readerFactory. getReader(lang) .read(this, url);
return this;
}
@Override
public Model read( String url, String base, String lang )
{
try ( InputStream is = new URL( url ) .openStream() ) {
read( is, base, lang );
}
catch (IOException e) { throw new WrappedIOException( e ); }
return this;
}
@Override
public Model read(Reader reader, String base, String lang)
{
readerFactory .getReader(lang) .read(this, reader, base);
return this;
}
@Override
public Model read(InputStream reader, String base, String lang)
{
readerFactory .getReader(lang) .read(this, reader, base);
return this;
}
/**
Get the model's writer after priming it with the model's namespace
prefixes.
*/
@Override
public RDFWriter getWriter() {
return writerFactory.getWriter();
}
/**
Get the model's writer after priming it with the model's namespace
prefixes.
*/
@Override
public RDFWriter getWriter(String lang) {
return writerFactory.getWriter(lang);
}
/** @deprecated Use {@code org.apache.jena.riot.RDFWriterRegistry.register}
*/
@Override
@Deprecated
public String setWriterClassName(String lang, String className) {
return writerFactory.setWriterClassName(lang, className);
}
@Override
@Deprecated
public void resetRDFWriterF() {
writerFactory.resetRDFWriterF();
}
@Override
@Deprecated
public String removeWriter( String lang ) throws IllegalArgumentException {
return writerFactory.removeWriter( lang );
}
@Override
public Model write(Writer writer)
{
getWriter() .write(this, writer, "");
return this;
}
@Override
public Model write(Writer writer, String lang)
{
getWriter(lang) .write(this, writer, "");
return this;
}
@Override
public Model write(Writer writer, String lang, String base)
{
getWriter(lang) .write(this, writer, base);
return this;
}
@Override
public Model write( OutputStream writer )
{
getWriter() .write(this, writer, "");
return this;
}
@Override
public Model write(OutputStream writer, String lang)
{
getWriter(lang) .write(this, writer, "");
return this;
}
@Override
public Model write(OutputStream writer, String lang, String base)
{
getWriter(lang) .write(this, writer, base);
return this;
}
@Override
public Model remove(Statement s) {
graph.delete(s.asTriple());
return this;
}
@Override
public Model remove( Resource s, Property p, RDFNode o ) {
graph.delete( Triple.create( s.asNode(), p.asNode(), o.asNode() ) );
return this;
}
@Override
public Model remove( StmtIterator iter )
{
GraphUtil.delete( getGraph(), asTriples( iter ) );
return this;
}
@Override
public Model remove( Model m )
{
GraphUtil.deleteFrom( getGraph(), m.getGraph());
return this;
}
@Override
public Model removeAll()
{
getGraph().clear();
return this;
}
@Override
public Model removeAll( Resource s, Property p, RDFNode o )
{
getGraph().remove( asNode( s ), asNode( p ), asNode( o ) );
return this;
}
@Override
public boolean containsLiteral( Resource s, Property p, boolean o )
{ return contains(s, p, createTypedLiteral( o ) ); }
@Override
public boolean containsLiteral( Resource s, Property p, long o )
{ return contains(s, p, createTypedLiteral( o ) ); }
@Override
public boolean containsLiteral( Resource s, Property p, int o )
{ return contains(s, p, createTypedLiteral( o ) ); }
@Override
public boolean containsLiteral( Resource s, Property p, char o )
{ return contains(s, p, createTypedLiteral( o ) ); }
@Override
public boolean containsLiteral( Resource s, Property p, float o )
{ return contains(s, p, createTypedLiteral( o ) ); }
@Override
public boolean containsLiteral( Resource s, Property p, double o )
{ return contains(s, p, createTypedLiteral( o ) ); }
@Override
public boolean contains( Resource s, Property p, String o )
{ return contains( s, p, o, "" ); }
@Override
public boolean contains( Resource s, Property p, String o, String l )
{ return contains( s, p, literal( o, l, false ) ); }
@Override
public boolean containsLiteral(Resource s, Property p, Object o)
{ return contains( s, p, asObject( o ) ); }
@Override
public boolean containsAny( Model model )
{ return containsAnyThenClose( model.listStatements() ); }
@Override
public boolean containsAll( Model model )
{ return containsAllThenClose( model.listStatements() ); }
protected boolean containsAnyThenClose( StmtIterator iter )
{ try { return containsAny( iter ); } finally { iter.close(); } }
protected boolean containsAllThenClose( StmtIterator iter )
{ try { return containsAll( iter ); } finally { iter.close(); } }
@Override
public boolean containsAny( StmtIterator iter )
{
while (iter.hasNext()) if (contains(iter.nextStatement())) return true;
return false;
}
@Override
public boolean containsAll( StmtIterator iter )
{
while (iter.hasNext()) if (!contains(iter.nextStatement())) return false;
return true;
}
protected StmtIterator listStatements( Resource S, Property P, Node O )
{
return IteratorFactory.asStmtIterator
( graph.find( asNode( S ), asNode( P ), O ), this );
}
@Override
public StmtIterator listStatements( Resource S, Property P, RDFNode O )
{ return listStatements( S, P, asNode( O ) ); }
@Override
public StmtIterator listStatements( Resource S, Property P, String O ) {
return O == null ? listStatements(S, P, Node.ANY)
: listStatements( S, P, NodeFactory.createLiteral( O ) );
}
@Override
public StmtIterator listStatements( Resource S, Property P, String O, String L ) {
if (O != null) {
// this is not OK when L is null: returns only the statements whose lang is ""
// return listStatements( S, P, Node.createLiteral( O, L, false ) );
if (L != null) return listStatements( S, P, NodeFactory.createLiteral( O, L ) );
// there's maybe a better way
return new StringFilteredStmtIterator(O, listStatements(S, P, Node.ANY));
} else {
return new LangFilteredStmtIterator(L, listStatements(S, P, Node.ANY));
}
}
private class StringFilteredStmtIterator extends FilterIterator<Statement>
implements StmtIterator {
public StringFilteredStmtIterator(final String str, Iterator<Statement> it) {
super(s -> {
RDFNode o = s.getObject();
if (o instanceof Literal) {
if (str == null)
return true; // should not happen
return (str.equals(o.asLiteral().getString()));
}
return false;
}, it);
}
@Override public Statement nextStatement() { return next(); }
}
private class LangFilteredStmtIterator extends FilterIterator<Statement> implements StmtIterator {
public LangFilteredStmtIterator(final String l, Iterator<Statement> it) {
super(s -> {
RDFNode o = s.getObject();
if (o instanceof Literal) {
if (l == null)
return true;
return (l.equals(o.asLiteral().getLanguage()));
}
return false;
}, it);
}
@Override public Statement nextStatement() { return next(); }
}
@Override
public StmtIterator listLiteralStatements( Resource S, Property P, boolean O )
{ return listStatements( S, P, createTypedLiteral( O ) ); }
@Override
public StmtIterator listLiteralStatements( Resource S, Property P, long O )
{ return listStatements( S, P, createTypedLiteral( O ) ); }
@Override
public StmtIterator listLiteralStatements( Resource S, Property P, int O )
{ return listStatements( S, P, createTypedLiteral( O ) ); }
@Override
public StmtIterator listLiteralStatements( Resource S, Property P, char O )
{ return listStatements( S, P, createTypedLiteral( O ) ); }
@Override
public StmtIterator listLiteralStatements( Resource S, Property P, float O )
{ return listStatements( S, P, createTypedLiteral( O ) ); }
@Override
public StmtIterator listLiteralStatements( Resource S, Property P, double O )
{ return listStatements( S, P, createTypedLiteral( O ) ); }
/*
list resources with property [was: list subjects with property]
*/
@Override
public ResIterator listResourcesWithProperty( Property p, boolean o )
{ return listResourcesWithProperty(p, createTypedLiteral( o ) ); }
@Override
public ResIterator listResourcesWithProperty( Property p, char o )
{ return listResourcesWithProperty(p, createTypedLiteral( o ) ); }
@Override
public ResIterator listResourcesWithProperty( Property p, long o )
{ return listResourcesWithProperty(p, createTypedLiteral( o ) ); }
@Override
public ResIterator listResourcesWithProperty( Property p, float o )
{ return listResourcesWithProperty(p, createTypedLiteral( o ) ); }
@Override
public ResIterator listResourcesWithProperty( Property p, double o )
{ return listResourcesWithProperty(p, createTypedLiteral( o ) ); }
@Override
public ResIterator listResourcesWithProperty( Property p, Object o )
{ return listResourcesWithProperty( p, createTypedLiteral( o ) ); }
@Override
public ResIterator listSubjectsWithProperty( Property p, RDFNode o )
{ return listResourcesWithProperty( p, o ); }
@Override
public ResIterator listSubjectsWithProperty( Property p, String o )
{ return listSubjectsWithProperty( p, o, "" ); }
@Override
public ResIterator listSubjectsWithProperty( Property p, String o, String l )
{ return listResourcesWithProperty(p, literal( o, l, false ) ); }
@Override
public Resource createResource( Resource type )
{ return createResource().addProperty( RDF.type, type ); }
@Override
public Resource createResource( String uri,Resource type )
{ return getResource( uri ).addProperty( RDF.type, type ); }
@Override
@Deprecated public Resource createResource( ResourceF f )
{ return createResource( null, f ); }
@Override
public Resource createResource( AnonId id )
{ return new ResourceImpl( id, this ); }
@Override
@Deprecated public Resource createResource( String uri, ResourceF f )
{ return f.createResource( createResource( uri ) ); }
/** create a type literal from a boolean value.
*
* <p> The value is converted to a string using its <CODE>toString</CODE>
* method. </p>
* @param v the value of the literal
*
* @return a new literal representing the value v
*/
@Override
public Literal createTypedLiteral( boolean v ) {
return createTypedLiteral( new Boolean( v ) );
}
/** create a typed literal from an integer value.
*
* @param v the value of the literal
*
* @return a new literal representing the value v
*/
@Override
public Literal createTypedLiteral(int v) {
return createTypedLiteral(new Integer(v));
}
/** create a typed literal from a long integer value.
*
* @param v the value of the literal
*
* @return a new literal representing the value v
*/
@Override
public Literal createTypedLiteral(long v) {
return createTypedLiteral(new Long(v));
}
/** create a typed literal from a char value.
*
* @param v the value of the literal
*
* @return a new literal representing the value v
*/
@Override
public Literal createTypedLiteral(char v) {
return createTypedLiteral(new Character(v));
}
/** create a typed literal from a float value.
*
* @param v the value of the literal
*
* @return a new literal representing the value v
*/
@Override
public Literal createTypedLiteral(float v) {
return createTypedLiteral(new Float(v));
}
/** create a typed literal from a double value.
*
* @param v the value of the literal
*
* @return a new literal representing the value v
*/
@Override
public Literal createTypedLiteral(double v) {
return createTypedLiteral(new Double(v));
}
/** create a typed literal from a String value.
*
* @param v the value of the literal
*
* @return a new literal representing the value v
*/
@Override
public Literal createTypedLiteral(String v) {
LiteralLabel ll = LiteralLabelFactory.createTypedLiteral(v);
return new LiteralImpl(NodeFactory.createLiteral(ll), this);
}
/**
* Create a typed literal xsd:dateTime from a Calendar object.
*/
@Override
public Literal createTypedLiteral(Calendar cal) {
Object value = new XSDDateTime(cal);
LiteralLabel ll = LiteralLabelFactory.createByValue(value, "", XSDDatatype.XSDdateTime);
return new LiteralImpl(NodeFactory.createLiteral(ll), this);
}
/**
* Build a typed literal from its lexical form. The
* lexical form will be parsed now and the value stored. If
* the form is not legal this will throw an exception.
*
* @param lex the lexical form of the literal
* @param dtype the type of the literal, null for old style "plain" literals
* @throws DatatypeFormatException if lex is not a legal form of dtype
*/
@Override
public Literal createTypedLiteral(String lex, RDFDatatype dtype)
throws DatatypeFormatException {
return new LiteralImpl( NodeFactory.createLiteral( lex, dtype ), this);
}
/**
* Build a typed literal from its value form.
*
* @param value the value of the literal
* @param dtype the type of the literal, null for old style "plain" literals
*/
@Override
public Literal createTypedLiteral(Object value, RDFDatatype dtype) {
LiteralLabel ll = LiteralLabelFactory.createByValue(value, "", dtype);
return new LiteralImpl( NodeFactory.createLiteral(ll), this );
}
/**
* Build a typed literal from its lexical form. The
* lexical form will be parsed now and the value stored. If
* the form is not legal this will throw an exception.
*
* @param lex the lexical form of the literal
* @param typeURI the uri of the type of the literal, null for old style "plain" literals
* @throws DatatypeFormatException if lex is not a legal form of dtype
*/
@Override
public Literal createTypedLiteral(String lex, String typeURI) {
RDFDatatype dt = TypeMapper.getInstance().getSafeTypeByName(typeURI);
LiteralLabel ll = LiteralLabelFactory.create( lex, dt );
return new LiteralImpl( NodeFactory.createLiteral(ll), this );
}
/**
* Build a typed literal from its value form.
*
* @param value the value of the literal
* @param typeURI the URI of the type of the literal, null for old style "plain" literals
*/
@Override
public Literal createTypedLiteral(Object value, String typeURI) {
RDFDatatype dt = TypeMapper.getInstance().getSafeTypeByName(typeURI);
LiteralLabel ll = LiteralLabelFactory.createByValue(value, "", dt);
return new LiteralImpl(NodeFactory.createLiteral(ll), this);
}
/**
* Build a typed literal label from its value form using
* whatever datatype is currently registered as the the default
* representation for this java class. No language tag is supplied.
* @param value the literal value to encapsulate
*/
@Override
public Literal createTypedLiteral( Object value )
{
// Catch special case of a Calendar which we want to act as if it were an XSDDateTime
if (value instanceof Calendar)
return createTypedLiteral( (Calendar)value );
LiteralLabel ll = LiteralLabelFactory.createTypedLiteral( value );
return new LiteralImpl( NodeFactory.createLiteral( ll ), this);
}
@Override
public Literal createLiteral( String v )
{ return createLiteral( v, "" ); }
@Override
public Literal createLiteral( String v, String l )
{ return literal( v, l, false ); }
@Override
public Literal createLiteral( String v, boolean wellFormed )
{ return literal( v, "", wellFormed ); }
public Literal createLiteral(String v, String l, boolean wellFormed)
{ return literal( v, l, wellFormed ); }
@Override
public Statement createLiteralStatement( Resource r, Property p, boolean o )
{ return createStatement( r, p, createTypedLiteral( o ) ); }
@Override
public Statement createLiteralStatement( Resource r, Property p, long o )
{ return createStatement( r, p, createTypedLiteral( o ) ); }
@Override
public Statement createLiteralStatement( Resource r, Property p, int o )
{ return createStatement( r, p, createTypedLiteral( o ) ); }
@Override
public Statement createLiteralStatement( Resource r, Property p, char o )
{ return createStatement( r, p, createTypedLiteral( o ) ); }
@Override
public Statement createLiteralStatement( Resource r, Property p, float o )
{ return createStatement( r, p, createTypedLiteral( o ) ); }
@Override
public Statement createLiteralStatement( Resource r, Property p, double o )
{ return createStatement( r, p, createTypedLiteral( o ) ); }
@Override
public Statement createStatement( Resource r, Property p, String o )
{ return createStatement( r, p, createLiteral( o ) ); }
@Override
public Statement createLiteralStatement( Resource r, Property p, Object o )
{ return createStatement( r, p, asObject( o ) ); }
@Override
public Statement createStatement
( Resource r, Property p, String o, boolean wellFormed )
{ return createStatement( r, p, o, "", wellFormed ); }
@Override
public Statement createStatement(Resource r, Property p, String o, String l)
{ return createStatement( r, p, o, l, false ); }
@Override
public Statement createStatement
( Resource r, Property p, String o, String l, boolean wellFormed )
{ return createStatement( r, p, literal( o, l, wellFormed ) ); }
@Override
public Bag createBag()
{ return createBag( null ); }
@Override
public Alt createAlt()
{ return createAlt( null ); }
@Override
public Seq createSeq()
{ return createSeq( null ); }
/**
Answer a (the) new empty list
@return An RDF-encoded list of no elements (ie nil)
*/
@Override
public RDFList createList()
{ return getResource( RDF.nil.getURI() ).as( RDFList.class ); }
/**
* <p>Answer a new list containing the resources from the given iterator, in order.</p>
* @param members An iterator, each value of which is expected to be an RDFNode.
* @return An RDF-encoded list of the elements of the iterator
*/
@Override
public RDFList createList( Iterator<? extends RDFNode> members )
{
RDFList list = createList();
while (members != null && members.hasNext()) list = list.with( members.next() );
return list;
}
/**
* <p>Answer a new list containing the RDF nodes from the given array, in order</p>
* @param members An array of RDFNodes that will be the members of the list
* @return An RDF-encoded list
*/
@Override
public RDFList createList( RDFNode[] members ) {
return createList( Arrays.asList( members ).iterator() );
}
@Override
public RDFNode getRDFNode( Node n )
{ return asRDFNode( n ); }
@Override
public Resource getResource( String uri )
{ return IteratorFactory.asResource(makeURI(uri),this); }
@Override
public Property getProperty( String uri )
{
if (uri == null) throw new InvalidPropertyURIException( null );
return IteratorFactory.asProperty( makeURI(uri), this );
}
@Override
public Property getProperty( String nameSpace,String localName )
{ return getProperty( nameSpace + localName ); }
@Override
public Seq getSeq( String uri )
{ return (Seq) IteratorFactory.asResource( makeURI( uri ),Seq.class, this); }
@Override
public Seq getSeq( Resource r )
{ return r.inModel( this ).as( Seq.class ); }
@Override
public Bag getBag( String uri )
{ return (Bag) IteratorFactory.asResource( makeURI( uri ),Bag.class, this ); }
@Override
public Bag getBag( Resource r )
{ return r.inModel( this ).as( Bag.class ); }
static private Node makeURI(String uri)
{ return uri == null ? NodeFactory.createBlankNode() : NodeFactory.createURI( uri ); }
@Override
public Alt getAlt( String uri )
{ return (Alt) IteratorFactory.asResource( makeURI(uri) ,Alt.class, this ); }
@Override
public Alt getAlt( Resource r )
{ return r.inModel( this ).as( Alt.class ); }
@Override
public long size()
{ return graph.size(); }
@Override
public boolean isEmpty()
{ return graph.isEmpty(); }
private void updateNamespace( Set<String> set, Iterator<Node> it )
{
while (it.hasNext())
{
Node node = it.next();
if (node.isURI())
{
String uri = node.getURI();
String ns = uri.substring( 0, Util.splitNamespaceXML( uri ) );
// String ns = IteratorFactory.asResource( node, this ).getNameSpace();
set.add( ns );
}
}
}
private ExtendedIterator<Node> listPredicates()
{ return GraphUtil.listPredicates(graph, Node.ANY, Node.ANY ); }
private Iterator<Node> listTypes()
{
Set<Node> types = CollectionFactory.createHashedSet();
ClosableIterator<Triple> it = graph.find( null, RDF.type.asNode(), null );
while (it.hasNext()) types.add( it.next().getObject() );
return types.iterator();
}
@Override
public NsIterator listNameSpaces() {
Set<String> nameSpaces = CollectionFactory.createHashedSet();
updateNamespace( nameSpaces, listPredicates() );
updateNamespace( nameSpaces, listTypes() );
return new NsIteratorImpl(nameSpaces.iterator(), nameSpaces);
}
private PrefixMapping getPrefixMapping()
{ return getGraph().getPrefixMapping(); }
@Override
public boolean samePrefixMappingAs( PrefixMapping other )
{ return getPrefixMapping().samePrefixMappingAs( other ); }
@Override
public PrefixMapping lock()
{
getPrefixMapping().lock();
return this;
}
@Override
public PrefixMapping setNsPrefix( String prefix, String uri )
{
getPrefixMapping().setNsPrefix( prefix, uri );
return this;
}
@Override
public PrefixMapping removeNsPrefix( String prefix )
{
getPrefixMapping().removeNsPrefix( prefix );
return this;
}
@Override
public PrefixMapping clearNsPrefixMap()
{
getPrefixMapping().clearNsPrefixMap();
return this ;
}
@Override
public PrefixMapping setNsPrefixes( PrefixMapping pm )
{
getPrefixMapping().setNsPrefixes( pm );
return this;
}
@Override
public PrefixMapping setNsPrefixes( Map<String, String> map )
{
getPrefixMapping().setNsPrefixes( map );
return this;
}
@Override
public PrefixMapping withDefaultMappings( PrefixMapping other )
{
getPrefixMapping().withDefaultMappings( other );
return this;
}
@Override
public String getNsPrefixURI( String prefix )
{ return getPrefixMapping().getNsPrefixURI( prefix ); }
@Override
public String getNsURIPrefix( String uri )
{ return getPrefixMapping().getNsURIPrefix( uri ); }
@Override
public Map<String, String> getNsPrefixMap()
{ return getPrefixMapping().getNsPrefixMap(); }
@Override
public String expandPrefix( String prefixed )
{ return getPrefixMapping().expandPrefix( prefixed ); }
@Override
public String qnameFor( String uri )
{ return getPrefixMapping().qnameFor( uri ); }
@Override
public String shortForm( String uri )
{ return getPrefixMapping().shortForm( uri ); }
/**
Service method to update the namespaces of a Model given the
mappings from prefix names to sets of URIs.
If the prefix maps to multiple URIs, then we discard it completely.
@param m Model who's namespace is to be updated
@param ns the namespace map to add to the Model
*/
public static void addNamespaces( Model m, Map<String, Set<String>> ns )
{
PrefixMapping pm = m;
for ( Map.Entry<String, Set<String>> e : ns.entrySet() )
{
String key = e.getKey();
Set<String> values = e.getValue();
Set<String> niceValues = CollectionFactory.createHashedSet();
for ( String uri : values )
{
if ( PrefixMappingImpl.isNiceURI( uri ) )
{
niceValues.add( uri );
}
}
if ( niceValues.size() == 1 )
{
pm.setNsPrefix( key, niceValues.iterator().next() );
}
}
}
@Override
public StmtIterator listStatements()
{ return IteratorFactory.asStmtIterator( GraphUtil.findAll( graph ), this); }
/**
add a Statement to this Model by adding its SPO components.
*/
@Override
public Model add( Statement s )
{
add( s.getSubject(), s.getPredicate(), s.getObject() );
return this;
}
/**
Add all the statements to the model by converting them to an array of corresponding
triples and removing those from the underlying graph.
*/
@Override
public Model add( Statement [] statements )
{
GraphUtil.add(getGraph(), StatementImpl.asTriples( statements ) );
return this;
}
/**
Add all the statements to the model by converting the list to an array of
Statement and removing that.
*/
@Override
public Model add( List<Statement> statements )
{
GraphUtil.add(getGraph(), asTriples( statements ) );
return this;
}
private List<Triple> asTriples( List<Statement> statements )
{
List<Triple> L = new ArrayList<>( statements.size() );
for ( Statement statement : statements )
{
L.add( statement.asTriple() );
}
return L;
}
private Iterator<Triple> asTriples( StmtIterator it )
{ return it.mapWith( s -> s.asTriple() ); }
/**
remove all the Statements from the model by converting them to triples and
removing those triples from the underlying graph.
*/
@Override
public Model remove( Statement [] statements )
{
GraphUtil.delete( getGraph(), StatementImpl.asTriples( statements ) );
return this;
}
/**
Remove all the Statements from the model by converting the List to a
List(Statement) and removing that.
*/
@Override
public Model remove( List<Statement> statements )
{
GraphUtil.delete( getGraph(), asTriples( statements ) );
return this;
}
@Override
public Model add( Resource s, Property p, RDFNode o ) {
modelReifier.noteIfReified( s, p, o );
graph.add( Triple.create( s.asNode(), p.asNode(), o.asNode() ) );
return this;
}
/**
@return an iterator which delivers all the ReifiedStatements in this model
*/
@Override
public RSIterator listReifiedStatements()
{ return modelReifier.listReifiedStatements(); }
/**
@return an iterator each of whose elements is a ReifiedStatement in this
model such that it's getStatement().equals( st )
*/
@Override
public RSIterator listReifiedStatements( Statement st )
{ return modelReifier.listReifiedStatements( st ); }
/**
@return true iff this model has a reification of _s_ in some Statement
*/
@Override
public boolean isReified( Statement s )
{ return modelReifier.isReified( s ); }
/**
get any reification of the given statement in this model; make
one if necessary.
@param s for which a reification is sought
@return a ReifiedStatement that reifies _s_
*/
@Override
public Resource getAnyReifiedStatement(Statement s)
{ return modelReifier.getAnyReifiedStatement( s ); }
/**
remove any ReifiedStatements reifying the given statement
@param s the statement who's reifications are to be discarded
*/
@Override
public void removeAllReifications( Statement s )
{ modelReifier.removeAllReifications( s ); }
@Override
public void removeReification( ReifiedStatement rs )
{ modelReifier.removeReification( rs ); }
/**
create a ReifiedStatement that encodes _s_ and belongs to this Model.
*/
@Override
public ReifiedStatement createReifiedStatement( Statement s )
{ return modelReifier.createReifiedStatement( s ); }
@Override
public ReifiedStatement createReifiedStatement( String uri, Statement s )
{ return modelReifier.createReifiedStatement( uri, s ); }
@Override
public boolean contains( Statement s )
{ return graph.contains( s.asTriple() ); }
@Override
public boolean containsResource( RDFNode r )
{ return GraphUtil.containsNode( graph, r.asNode() ); }
@Override
public boolean contains( Resource s, Property p )
{ return contains( s, p, (RDFNode) null ); }
@Override
public boolean contains( Resource s, Property p, RDFNode o )
{ return graph.contains( asNode( s ), asNode( p ), asNode( o ) ); }
@Override
public Statement getRequiredProperty(Resource s, Property p) {
Statement st = getProperty( s, p );
if (st == null) throw new PropertyNotFoundException( p );
return st;
}
@Override
public Statement getRequiredProperty(Resource s, Property p, String lang) {
Statement st = getProperty( s, p , lang );
if (st == null) throw new PropertyNotFoundException( p );
return st;
}
@Override
public Statement getProperty( Resource s, Property p ) {
StmtIterator iter = listStatements( s, p, (RDFNode) null );
try { return iter.hasNext() ? iter.nextStatement() : null; }
finally { iter.close(); }
}
@Override
public Statement getProperty( Resource s, Property p, String lang) {
StmtIterator iter = listStatements( s, p, null, lang );
try { return iter.hasNext() ? iter.nextStatement() : null; }
finally { iter.close(); }
}
public static Node asNode( RDFNode x )
{ return x == null ? Node.ANY : x.asNode(); }
private NodeIterator listObjectsFor( RDFNode s, RDFNode p ) {
ClosableIterator<Node> xit = GraphUtil.listObjects(graph, asNode( s ), asNode( p ) ) ;
return IteratorFactory.asRDFNodeIterator( xit, this );
}
private ResIterator listSubjectsFor( RDFNode p, RDFNode o )
{
ClosableIterator<Node> xit = GraphUtil.listSubjects( graph, asNode( p ), asNode( o ) );
return IteratorFactory.asResIterator( xit, this );
}
@Override
public ResIterator listSubjects()
{ return listSubjectsFor( null, null ); }
@Override
public ResIterator listResourcesWithProperty(Property p)
{ return listSubjectsFor( p, null ); }
@Override
public ResIterator listSubjectsWithProperty(Property p)
{ return listResourcesWithProperty( p ); }
@Override
public ResIterator listResourcesWithProperty(Property p, RDFNode o)
{ return listSubjectsFor( p, o ); }
@Override
public NodeIterator listObjects()
{ return listObjectsFor( null, null ); }
@Override
public NodeIterator listObjectsOfProperty(Property p)
{ return listObjectsFor( null, p ); }
@Override
public NodeIterator listObjectsOfProperty(Resource s, Property p)
{ return listObjectsFor( s, p ); }
@Override
public StmtIterator listStatements( final Selector selector )
{
StmtIterator sts = IteratorFactory.asStmtIterator( findTriplesFrom( selector ), this );
return selector.isSimple()
? sts
: new StmtIteratorImpl( sts .filterKeep ( selector ) )
;
}
/**
Answer an [extended] iterator which returns the triples in this graph which
are selected by the (S, P, O) triple in the selector, ignoring any special
tests it may do.
@param s a Selector used to supply subject, predicate, and object
@return an extended iterator over the matching (S, P, O) triples
*/
public ExtendedIterator<Triple> findTriplesFrom( Selector s )
{
return graph.find
( asNode( s.getSubject() ), asNode( s.getPredicate() ), asNode( s.getObject() ) );
}
@Override
public boolean supportsTransactions()
{ return getTransactionHandler().transactionsSupported(); }
@Override
public Model begin()
{ getTransactionHandler().begin(); return this; }
@Override
public Model abort()
{ getTransactionHandler().abort(); return this; }
@Override
public Model commit()
{ getTransactionHandler().commit(); return this; }
@SuppressWarnings("deprecation")
@Override
public Object executeInTransaction( Command cmd )
{ return getTransactionHandler().executeInTransaction( cmd ); }
private TransactionHandler getTransactionHandler()
{ return getGraph().getTransactionHandler(); }
@Override
public void executeInTxn( Runnable action ) {
getTransactionHandler().execute( action );
}
/**
* Execute the supplier <code>action</code> within a transaction. If it completes normally,
* commit the transaction and return the result, otherwise abort the transaction.
*/
@Override
public <T> T calculateInTxn( Supplier<T> action ) {
return getTransactionHandler().calculate( action );
}
@Override
public boolean independent()
{ return true; }
@Override
public Resource createResource()
{ return IteratorFactory.asResource( NodeFactory.createBlankNode(),this ); }
@Override
public Resource createResource( String uri )
{ return getResource( uri ); }
@Override
public Property createProperty( String uri )
{ return getProperty( uri ); }
@Override
public Property createProperty(String nameSpace, String localName)
{ return getProperty(nameSpace, localName); }
/**
create a Statement from the given r, p, and o.
*/
@Override
public Statement createStatement(Resource r, Property p, RDFNode o)
{ return new StatementImpl( r, p, o, this ); }
@Override
public Bag createBag(String uri)
{ return (Bag) getBag(uri).addProperty( RDF.type, RDF.Bag ); }
@Override
public Alt createAlt( String uri )
{ return (Alt) getAlt(uri).addProperty( RDF.type, RDF.Alt ); }
@Override
public Seq createSeq(String uri)
{ return (Seq) getSeq(uri).addProperty( RDF.type, RDF.Seq ); }
/**
Answer a Statement in this Model whcih encodes the given Triple.
@param t a triple to wrap as a statement
@return a statement wrapping the triple and in this model
*/
@Override
public Statement asStatement( Triple t )
{ return StatementImpl.toStatement( t, this ); }
public Statement [] asStatements( Triple [] triples )
{
Statement [] result = new Statement [triples.length];
for (int i = 0; i < triples.length; i += 1) result[i] = asStatement( triples[i] );
return result;
}
public List<Statement> asStatements( List<Triple> triples )
{
List<Statement> L = new ArrayList<>( triples.size() );
for ( Triple triple : triples )
{
L.add( asStatement( triple ) );
}
return L;
}
public Model asModel( Graph g )
{ return new ModelCom( g ); }
public StmtIterator asStatements( final Iterator<Triple> it )
{ return new StmtIteratorImpl( new Map1Iterator<>( t -> asStatement( t ), it ) ); }
public StmtIterator listBySubject( Container cont )
{ return listStatements( cont, null, (RDFNode) null ); }
@Override
public void close()
{ graph.close(); }
@Override
public boolean isClosed()
{ return graph.isClosed(); }
@Override
public boolean supportsSetOperations()
{return true;}
@Override
public Model query( Selector selector )
{ return createWorkModel() .add( listStatements( selector ) ); }
@Override
public Model union( Model model )
{ return createWorkModel() .add(this) .add( model ); }
/**
Intersect this with another model. As an attempt at optimisation, we try and ensure
we iterate over the smaller model first. Nowadays it's not clear that this is a good
idea, since <code>size()</code> can be expensive on database and inference
models.
@see org.apache.jena.rdf.model.Model#intersection(org.apache.jena.rdf.model.Model)
*/
@Override
public Model intersection( Model other )
{ return this.size() < other.size() ? intersect( this, other ) : intersect( other, this ); }
/**
Answer a Model that is the intersection of the two argument models. The first
argument is the model iterated over, and the second argument is the one used
to check for membership. [So the first one should be "small" and the second one
"membership cheap".]
*/
public static Model intersect( Model smaller, Model larger )
{
Model result = createWorkModel();
StmtIterator it = smaller.listStatements();
try { return addCommon( result, it, larger ); }
finally { it.close(); }
}
/**
Answer the argument result with all the statements from the statement iterator that
are in the other model added to it.
@param result the Model to add statements to and return
@param it an iterator over the candidate statements
@param other the model that must contain the statements to be added
@return result, after the suitable statements have been added to it
*/
protected static Model addCommon( Model result, StmtIterator it, Model other )
{
while (it.hasNext())
{
Statement s = it.nextStatement();
if (other.contains( s )) result.add( s );
}
return result;
}
@Override
public Model difference(Model model) {
Model resultModel = createWorkModel();
StmtIterator iter = null;
Statement stmt;
try {
iter = listStatements();
while (iter.hasNext()) {
stmt = iter.nextStatement();
if (! model.contains(stmt)) {
resultModel.add(stmt);
}
}
return resultModel;
} finally {
if (null != iter) {
iter.close();
}
}
}
@Override
public String toString()
{ return "<ModelCom " + getGraph() + " | " + reifiedToString() + ">"; }
public String reifiedToString()
{ return statementsToString( listStatements() ); }
protected String statementsToString( StmtIterator it )
{
StringBuilder b = new StringBuilder();
while (it.hasNext()) b.append( " " ).append( it.nextStatement() );
return b.toString();
}
/**
Answer whether or not these two graphs are isomorphic.
*/
@Override
public boolean isIsomorphicWith( Model m )
{
Graph L = this.getGraph();
Graph R = m.getGraph();
return L.isIsomorphicWith( R );
}
public synchronized Lock getModelLock()
{
if ( modelLock == null )
modelLock = new LockMRSW() ;
return modelLock ;
}
@Override
public synchronized Lock getLock()
{
return getModelLock() ;
}
@Override
public void enterCriticalSection(boolean requestReadLock)
{
this.getModelLock().enterCriticalSection(requestReadLock) ;
}
@Override
public void leaveCriticalSection()
{
this.getModelLock().leaveCriticalSection() ;
}
/**
Register the listener with this model by registering its GraphListener
adaption with the underlying Graph.
@param listener A ModelChangedListener to register for model events
@return this model, for cascading
*/
@Override
public Model register( ModelChangedListener listener )
{
getGraph().getEventManager().register( adapt( listener ) );
return this;
}
/**
Unregister the listener from this model by unregistering its GraphListener
adaption from the underlying Graph.
@param listener A ModelChangedListener to unregister from model events
@return this model, for cascading
*/
@Override
public Model unregister( ModelChangedListener listener )
{
getGraph().getEventManager().unregister( adapt( listener ) );
return this;
}
/**
Answer a GraphListener that, when fed graph-level update events,
fires the corresponding model-level event handlers in <code>L</code>.
@see ModelListenerAdapter
@param L a model listener to be wrapped as a graph listener
@return a graph listener wrapping L
*/
public GraphListener adapt( final ModelChangedListener L )
{ return new ModelListenerAdapter( this, L ); }
@Override
public Model notifyEvent( Object e )
{
getGraph().getEventManager().notifyEvent( getGraph(), e );
return this;
}
}