All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.bigdata.rdf.model.BigdataValueFactoryImpl 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 Apr 21, 2008
 */

package com.bigdata.rdf.model;

import java.util.Date;
import java.util.GregorianCalendar;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TimeZone;
import java.util.UUID;

import javax.xml.datatype.XMLGregorianCalendar;

import org.openrdf.model.BNode;
import org.openrdf.model.Literal;
import org.openrdf.model.Resource;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import org.openrdf.model.datatypes.XMLDatatypeUtil;
import org.openrdf.model.impl.BooleanLiteralImpl;

import com.bigdata.cache.WeakValueCache;
import com.bigdata.rdf.internal.IV;
import com.bigdata.rdf.internal.impl.extensions.DateTimeExtension;
import com.bigdata.rdf.internal.impl.literal.XSDUnsignedByteIV;
import com.bigdata.rdf.internal.impl.literal.XSDUnsignedIntIV;
import com.bigdata.rdf.internal.impl.literal.XSDUnsignedLongIV;
import com.bigdata.rdf.internal.impl.literal.XSDUnsignedShortIV;
import com.bigdata.rdf.lexicon.LexiconRelation;
import com.bigdata.util.concurrent.CanonicalFactory;

/**
 * An implementation using {@link BigdataValue}s and {@link BigdataStatement}s.
 * Values constructed using this factory do NOT have term identifiers assigned.
 * Statements constructed using this factory do NOT have statement identifiers
 * assigned. Those metadata can be resolved against the various indices and then
 * set on the returned values and statements.
 * 
 * @todo Consider a {@link WeakValueCache} on this factory to avoid duplicate
 *       values.
 * 
 * @todo Consider a {@link WeakValueCache} to shortcut recently used statements?
 * 
 * @author Bryan Thompson
 */
public class BigdataValueFactoryImpl implements BigdataValueFactory {

	private final String namespace;
	
	@Override
	public String getNamespace() {
		
	    if (namespace != null) {
	        
	        return namespace;
	        
	    } else {
	        
	        throw new RuntimeException("Headless value factory should not be asked for its namespace");
	        
	    }
		
	}
	
    /**
     * WARNING: Use {@link #getInstance(String)} NOT this constructor.
     * 

* WARNING: This constructor provides 'headless' (not associated with any * namespace) instance of the {@link BigdataValueFactory}, which is used for * query/update parsing. It SHOULD NOT be used in code working with * triple-store. * * @see BLZG-1678 (remove "headless" BigdataValueFactory impl class) * @see BLZG-1176 (SPARQL Query/Update parser should not use db connection) */ public BigdataValueFactoryImpl() { this(null); } /** * WARNING: Use {@link #getInstance(String)} NOT this constructor. */ private BigdataValueFactoryImpl(final String namespace) { this.namespace = namespace; xsdMap = getXSDMap(); // @see Concurrent insert data with boolean object causes IllegalArgumentException // @see Object position query hint is not a Literal // /** // * Cache the IV on the BigdataValue for these boolean constants. // * // * @see Concurrent insert // * data with boolean object causes IllegalArgumentException // */ // TRUE.setIV(XSDBooleanIV.TRUE); // FALSE.setIV(XSDBooleanIV.FALSE); } /** * Canonicalizing mapping for {@link BigdataValueFactoryImpl}s based on the * namespace of the {@link LexiconRelation}. *

* Note: The backing LRU should be small (and can be zero) since instances * SHOULD be finalized quickly once they are no longer strongly reachable * (which would imply that there was no {@link LexiconRelation} for that * instance and that all {@link BigdataValueImpl}s for that instance had * become weakly reachable or been swept). */ private static CanonicalFactory cache = new CanonicalFactory( 1/* capacity */) { @Override protected BigdataValueFactoryImpl newInstance( final String key, final String namespace) { return new BigdataValueFactoryImpl(namespace); } }; // private static WeakValueCache cache = new WeakValueCache( // new LRUCache(1/* capacity */)); /** * Return the instance associated with the namespace. *

* Note: This canonicalizing mapping for {@link BigdataValueFactoryImpl}s is * based on the namespace of the {@link LexiconRelation}. This makes the * instances canonical within a JVM instance, which is all that we care * about. The actual assignments of term identifiers to {@link BigdataValue} * s is performed by the {@link LexiconRelation} itself and is globally * consistent for a given lexicon. * * @param namespace * The namespace of the {@link LexiconRelation}. * * TODO This method introduces the possibility that two journals * in the same JVM would share the same * {@link BigdataValueFactory} for a kb with the same namespace. * This is doubtless not desired. A workaround is to use the * {@link UUID} of the Journal as part of the namespace of the * KB, which would serve to make sure that all KB instances have * distinct namespaces. */ public static BigdataValueFactory/* Impl */getInstance(final String namespace) { return cache.getInstance(namespace, namespace/*state*/); } // /** // * Return the instance associated with the namespace. // *

// * Note: This canonicalizing mapping for {@link BigdataValueFactoryImpl}s is // * based on the namespace of the {@link LexiconRelation}. This makes the // * instances canonical within a JVM instance, which is all that we care // * about. The actual assignments of term identifiers to {@link BigdataValue}s // * is performed by the {@link LexiconRelation} itself and is globally // * consistent for a given lexicon. // * // * @param namespace // * The namespace of the {@link LexiconRelation}. // */ // public static BigdataValueFactory/*Impl*/ getInstance(final String namespace) { // // if (namespace == null) // throw new IllegalArgumentException(); // // synchronized(cache) { // // BigdataValueFactoryImpl a = cache.get(namespace); // // if (a == null) { // // a = new BigdataValueFactoryImpl(); // // cache.put(namespace, a, true/* dirty */); // // } // // return a; // // } // // } /** * Remove a {@link BigdataValueFactoryImpl} from the canonicalizing mapping. *

* Entries in this canonicalizing mapping for a {@link LexiconRelation} MUST * be {@link #remove(String)}ed if the {@link LexiconRelation} is destroyed * in case a distinct lexicon is subsequently creating with the same * namespace. There is no need to discard an entry during abort processing. * */ // * @param namespace // * The namespace of the {@link LexiconRelation}. @Override public void remove(/*final String namespace*/) { // if (namespace == null) // throw new IllegalArgumentException(); // // synchronized(cache) { // // cache.remove(namespace); // // } cache.remove(namespace); } @Override public BNodeContextFactory newBNodeContext() { return new BNodeContextFactory(this); } /** * Returns a new blank node with a globally unique blank node ID based on a * {@link UUID}. *

* Note: Since the blank node IDs are random, they tend to be uniformly * distributed across the index partition(s). More efficient ordered writes * may be realized using {@link #newBNodeContext()} to obtain a derived * {@link BigdataValueFactory} instance that is specific to a document that * is being loaded into the RDF DB. * * @see #newBNodeContext() */ @Override public BigdataBNodeImpl createBNode() { return createBNode(nextID()); } /** * Returns a blank node identifier (ID) based on a random {@link UUID}. */ protected String nextID() { return "u"+UUID.randomUUID(); } @Override public BigdataBNodeImpl createBNode(final String id) { return new BigdataBNodeImpl(this, id); } @Override public BigdataBNodeImpl createBNode(final BigdataStatement stmt) { return new BigdataBNodeImpl(this, nextID(), stmt); } @Override public BigdataLiteralImpl createLiteral(final String label) { return new BigdataLiteralImpl(this, label, null, null); } /* * XSD support. */ public static final transient String NAMESPACE_XSD = "http://www.w3.org/2001/XMLSchema"; public static final transient String xsd = NAMESPACE_XSD + "#"; private final BigdataURIImpl xsd_string = new BigdataURIImpl(this, xsd + "string"); private final BigdataURIImpl xsd_dateTime = new BigdataURIImpl(this, xsd + "dateTime"); private final BigdataURIImpl xsd_date = new BigdataURIImpl(this, xsd + "date"); private final BigdataURIImpl xsd_long = new BigdataURIImpl(this, xsd + "long"); private final BigdataURIImpl xsd_int = new BigdataURIImpl(this, xsd + "int"); private final BigdataURIImpl xsd_byte = new BigdataURIImpl(this, xsd + "byte"); private final BigdataURIImpl xsd_short = new BigdataURIImpl(this, xsd + "short"); private final BigdataURIImpl xsd_ulong = new BigdataURIImpl(this, xsd + "unsignedLong"); private final BigdataURIImpl xsd_uint = new BigdataURIImpl(this, xsd + "unsignedInt"); private final BigdataURIImpl xsd_ubyte = new BigdataURIImpl(this, xsd + "unsignedByte"); private final BigdataURIImpl xsd_ushort = new BigdataURIImpl(this, xsd + "unsignedShort"); private final BigdataURIImpl xsd_double = new BigdataURIImpl(this, xsd + "double"); private final BigdataURIImpl xsd_float = new BigdataURIImpl(this, xsd + "float"); private final BigdataURIImpl xsd_boolean = new BigdataURIImpl(this, xsd + "boolean"); // private final BigdataLiteralImpl TRUE = new BigdataLiteralImpl(this, "true", null, // xsd_boolean); // // private final BigdataLiteralImpl FALSE = new BigdataLiteralImpl(this, "false", null, // xsd_boolean); /** * Map for fast resolution of XSD URIs. The keys are the string values of * the URIs. The values are the URIs. */ private final Map xsdMap; /** * Populate and return a map for fast resolution of XSD URIs. */ private Map getXSDMap() { final Map map = new LinkedHashMap(); final BigdataURIImpl[] a = new BigdataURIImpl[] { xsd_string, xsd_dateTime, xsd_date, xsd_long, xsd_int, xsd_byte, xsd_short, xsd_double, xsd_float, xsd_boolean }; for (BigdataURIImpl x : a) { // stringValue of URI => URI map.put(x.stringValue(), x); } return map; } /** * {@inheritDoc} * * @see Concurrent insert data * with boolean object causes IllegalArgumentException * @see Object position of * query hint is not a Literal */ @Override public BigdataLiteralImpl createLiteral(final boolean arg0) { return (arg0 // ? new BigdataLiteralImpl(this, "true", null, xsd_boolean) : new BigdataLiteralImpl(this, "false", null, xsd_boolean) ); } @Override public BigdataLiteralImpl createLiteral(byte arg0) { return new BigdataLiteralImpl(this, "" + arg0, null, xsd_byte); } @Override public BigdataLiteralImpl createLiteral(byte arg0, final boolean unsigned) { return new BigdataLiteralImpl(this, "" + (unsigned ? XSDUnsignedByteIV.promote(arg0) : arg0), null, unsigned ? xsd_ubyte : xsd_byte); } @Override public BigdataLiteralImpl createLiteral(short arg0) { return new BigdataLiteralImpl(this, "" + arg0, null, xsd_short); } @Override public BigdataLiteralImpl createLiteral(short arg0, final boolean unsigned) { return new BigdataLiteralImpl(this, "" + (unsigned ? XSDUnsignedShortIV.promote(arg0) : arg0), null, unsigned ? xsd_ushort :xsd_short); } @Override public BigdataLiteralImpl createLiteral(int arg0) { return new BigdataLiteralImpl(this, "" + arg0, null, xsd_int); } @Override public BigdataLiteralImpl createLiteral(int arg0, final boolean unsigned) { return new BigdataLiteralImpl(this, "" + (unsigned ? XSDUnsignedIntIV.promote(arg0) : arg0), null, unsigned ? xsd_uint :xsd_int); } @Override public BigdataLiteralImpl createLiteral(long arg0) { return new BigdataLiteralImpl(this, "" + arg0, null, xsd_long); } @Override public BigdataLiteralImpl createLiteral(long arg0, final boolean unsigned) { return new BigdataLiteralImpl(this, "" + (unsigned ? XSDUnsignedLongIV.promote(arg0) : arg0), null, unsigned ? xsd_ulong : xsd_long); } @Override public BigdataLiteralImpl createLiteral(float arg0) { return new BigdataLiteralImpl(this, "" + arg0, null, xsd_float); } @Override public BigdataLiteralImpl createLiteral(double arg0) { return new BigdataLiteralImpl(this, "" + arg0, null, xsd_double); } public BigdataLiteralImpl createLiteral(final Date date) { GregorianCalendar c = new GregorianCalendar(); c.setTime(date); XMLGregorianCalendar xmlGC = DateTimeExtension.datatypeFactorySingleton.newXMLGregorianCalendar(c); return createLiteral(xmlGC); } @Override public BigdataLiteralImpl createLiteral(final XMLGregorianCalendar arg0) { /* * Note: QName#toString() does not produce the right representation, * which is why we need to go through XMLDatatypeUtil. * * @see https://sourceforge.net/apps/trac/bigdata/ticket/117 */ return new BigdataLiteralImpl(this, arg0.toString(), null/* languageCode */, createURI(XMLDatatypeUtil.qnameToURI( arg0.getXMLSchemaType()).stringValue())); } @Override public BigdataLiteralImpl createXSDDateTime(final long timestamp) { final TimeZone tz = TimeZone.getDefault()/*getTimeZone("GMT")*/; final GregorianCalendar c = new GregorianCalendar(tz); c.setGregorianChange(new Date(Long.MIN_VALUE)); c.setTimeInMillis(timestamp); final XMLGregorianCalendar xmlGC = DateTimeExtension.datatypeFactorySingleton.newXMLGregorianCalendar(c); return createLiteral(xmlGC); } @Override public BigdataLiteralImpl createLiteral(final String label, final String language) { return new BigdataLiteralImpl(this, label, language, null/* datatype */); } @Override public BigdataLiteralImpl createLiteral(final String label, URI datatype) { return createLiteral(label, datatype, null); } @Override public BigdataLiteralImpl createLiteral(String label, URI datatype, String language) { /* * Note: The datatype parameter may be null per the Sesame API. * * See https://sourceforge.net/apps/trac/bigdata/ticket/226 */ if (datatype != null && !(datatype instanceof BigdataURIImpl)) { datatype = createURI(datatype.stringValue()); } return new BigdataLiteralImpl(this, label, language, (BigdataURIImpl) datatype); } @Override public BigdataURIImpl createURI(final String uriString) { final String str = uriString; // if (str.startsWith(NAMESPACE_XSD)) { final BigdataURIImpl tmp = xsdMap.get(str); if(tmp != null) { // found in canonicalizing map. return tmp; } // } return new BigdataURIImpl(this, uriString); } @Override public BigdataURIImpl createURI(final String namespace, final String localName) { return new BigdataURIImpl(this, namespace + localName); } @Override public BigdataStatementImpl createStatement(Resource s, URI p, Value o) { return createStatement(s, p, o, null/* c */, null/* type */); } @Override public BigdataStatementImpl createStatement(Resource s, URI p, Value o, Resource c) { return createStatement(s, p, o, c, null/* type */); } @Override public BigdataStatementImpl createStatement(Resource s, URI p, Value o, Resource c, StatementEnum type) { return createStatement(s, p, o, c, type, false/* userFlag */); } @Override public BigdataStatementImpl createStatement(Resource s, URI p, Value o, Resource c, StatementEnum type, final boolean userFlag) { return new BigdataStatementImpl(// (BigdataResource) asValue(s),// (BigdataURI) asValue(p),// (BigdataValue) asValue(o),// (BigdataResource) asValue(c),// optional type, // the statement type (optional). userFlag // the user flag (optional) ); } @Override final public BigdataValue asValue(final Value v) { if (v == null) return null; if (v instanceof BigdataValueImpl && ((BigdataValueImpl) v).getValueFactory() == this) { final BigdataValueImpl v1 = (BigdataValueImpl) v; final IV iv = v1.getIV(); if (iv == null || !iv.isNullIV()) { /* * A value from the same value factory whose IV is either * unknown or defined (but not a NullIV or DummyIV). */ return (BigdataValue) v; } } if (v instanceof BooleanLiteralImpl) { final BooleanLiteralImpl bl = (BooleanLiteralImpl) v; return createLiteral(bl.booleanValue()); } else if (v instanceof URI) { return createURI(((URI) v).stringValue()); } else if (v instanceof BigdataBNode && ((BigdataBNode)v).isStatementIdentifier()) { return createBNode(((BigdataBNode) v).getStatement()); } else if (v instanceof BNode) { return createBNode(((BNode) v).stringValue()); } else if (v instanceof Literal) { final Literal tmp = ((Literal) v); final String label = tmp.getLabel(); final String language = tmp.getLanguage(); final URI datatype = tmp.getDatatype(); return new BigdataLiteralImpl(// this,// Note: Passing in this factory! label,// language,// (BigdataURI)asValue(datatype)// ); } else { throw new AssertionError(); } } /** * (De-)serializer paired with this {@link BigdataValueFactoryImpl}. */ private final transient BigdataValueSerializer valueSer = new BigdataValueSerializer( this); @Override public BigdataValueSerializer getValueSerializer() { return valueSer; } @Override public BigdataResource asValue(Resource v) { return (BigdataResource) asValue((Value) v); } @Override public BigdataURI asValue(URI v) { return (BigdataURI)asValue((Value)v); } @Override public BigdataLiteral asValue(Literal v) { return (BigdataLiteral)asValue((Value)v); } @Override public BigdataBNode asValue(BNode v) { return (BigdataBNode)asValue((Value)v); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy