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

com.franz.agraph.repository.AGValueFactory Maven / Gradle / Ivy

There is a newer version: 5.0.2
Show newest version
/******************************************************************************
** Copyright (c) 2008-2016 Franz Inc.
** All rights reserved. This program and the accompanying materials
** are made available under the terms of the Eclipse Public License v1.0
** which accompanies this distribution, and is available at
** http://www.eclipse.org/legal/epl-v10.html
******************************************************************************/

package com.franz.agraph.repository;

import org.openrdf.model.BNode;
import org.openrdf.model.Resource;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import org.openrdf.model.impl.ValueFactoryImpl;
import org.openrdf.repository.RepositoryException;
import org.openrdf.rio.ntriples.NTriplesUtil;

import com.franz.agraph.http.AGHTTPClient;
import com.franz.agraph.http.AGHttpRepoClient;
import com.franz.agraph.http.exception.AGHttpException;
import com.hp.hpl.jena.graph.Node;

import java.util.regex.Pattern;

/**
 * Implements the Sesame ValueFactory interface for AllegroGraph.
 * 
 */
public class AGValueFactory extends ValueFactoryImpl {
	private static final Pattern AG_BNODE_ID_PATTERN = Pattern.compile("\\Ab[0-9A-Fa-f]{8}x\\d+\\z");

	private final AGRepository repository;
	private final AGRepositoryConnection conn;
	
	private int blankNodesPerRequest = Integer.parseInt(System.getProperty("com.franz.agraph.repository.blankNodesPerRequest", "100"));
	private String[] blankNodeIds;
	private int index = -1;
	
	public String PREFIX_FOR_EXTERNAL_BNODES = "urn:x-bnode:";

	public AGValueFactory(AGRepository repository) {
		super();
		this.repository = repository;
		this.conn = null;
	}
	
	public AGValueFactory(AGRepository repository, AGRepositoryConnection conn) {
		super();
		this.repository = repository;
		this.conn = conn;
	}
	
	public AGRepository getRepository() {
		return repository;
	}
	
	public AGHTTPClient getHTTPClient() {
		return getRepository().getHTTPClient();
	}
	
	private void requestBlankNodeIds() {
		try {
			if (conn == null) {
				blankNodeIds = getHTTPClient().getBlankNodes(getRepository().getRepositoryURL(), blankNodesPerRequest);
			} else {
				blankNodeIds = conn.getHttpRepoClient().getBlankNodes(blankNodesPerRequest);
			}
			index = blankNodeIds.length - 1;
		} catch (AGHttpException e) {
			// TODO: server's out of blank nodes?
			throw new RuntimeException(e);
		}		
	}
	
	/**
	 * Sets the number of blank nodes to fetch per request.
	 * 

* This can be used to control the number and frequency of * HTTP requests made when automatically obtaining new sets * of blank node ids from the server. *

* Defaults to the value of System property * com.franz.agraph.repository.blankNodesPerRequest * or to 100 if that property has not been set. * * @param amount */ public void setBlankNodesPerRequest(int amount) { blankNodesPerRequest=amount; } /** * Gets the number of blank nodes fetched per request. * * @return the number of blank nodes fetched per request. */ public int getBlankNodesPerRequest() { return blankNodesPerRequest; } /** * Returns the array of fetched blank node ids * * Primarily for testing purposes, not for use in apps. * * @return the array of fetched blank node ids */ public String[] getBlankNodeIds() { return blankNodeIds; } String getNextBNodeId() { if (index==-1) { requestBlankNodeIds(); } String id = blankNodeIds[index]; index--; // TODO: parse using NTriplesUtil here to create BNode? return id.substring(2); // strip off leading '_:'; } /** * Returns a new blank node with the given id. * * Consider using createBNode() instead to get an AG-allocated id, * it is safer (avoids unintended blank node conflicts) and can be * stored more efficiently. * * If id is null or empty, returns a unique BNode with AG-allocated * id; otherwise, returns a BNode with the given (a.k.a. "external") * id (careful to avoid blank node conflicts). See the javadoc for * allowing external blank nodes for more discussion. * * @see AGHttpRepoClient#setAllowExternalBlankNodeIds(boolean) * @see AGRepositoryConnection#getHttpRepoClient() */ @Override public BNode createBNode(String nodeID) { if (nodeID == null || "".equals(nodeID)) nodeID = getNextBNodeId(); return super.createBNode(nodeID); } /** * Returns a new blank node. * * If this value factory is for an AGRepository, returns a new BNode * with an AG-allocated id; otherwise, returns a new BNode with an * "external" id (using ValueFactoryImpl). See also the javadoc for * allowing external blank nodes for more discussion. * * @see AGHttpRepoClient#setAllowExternalBlankNodeIds(boolean) * @see AGRepositoryConnection#getHttpRepoClient() */ @Override public BNode createBNode() { if (repository != null) { return createBNode(null); } else { return super.createBNode(); } } /** * Creates an OpenRDF Value from a concrete Jena Node. * * @param node a concrete Jena node. * @return the corresponding Value. */ public Value asValue(Node node) { Value val; if (node==null || node==Node.ANY) { val = null; } else if (node.isURI()) { val = createURI(node.getURI()); } else if (node.isBlank()) { String id = node.getBlankNodeLabel(); val = createBNode(id); } else if (node.isLiteral()) { String lang = node.getLiteralLanguage(); if (node.getLiteralDatatypeURI()!=null) { URI datatype = createURI(node.getLiteralDatatypeURI()); val = createLiteral(node.getLiteralLexicalForm(), datatype); } else if (lang!=null && !lang.equals("")) { val = createLiteral(node.getLiteralLexicalForm(),lang); } else { // TODO val = createLiteral(node.getLiteralLexicalForm()); } } else { throw new IllegalArgumentException("Cannot convert Node to Value: " + node); } return val; } /** * Returns true iff id looks like an AG blank node id. * * AG blank node ids currently have the following form: * * b[store ID in hex]x[blank node number]. * * There is nothing sacrosanct about this but it is unlikely * to change. * * @param id the string to be tested * @return true iff id looks like an AG blank node id */ public boolean isAGBlankNodeId(String id) { return AG_BNODE_ID_PATTERN.matcher(id).matches(); } public boolean isURIForExternalBlankNode(Value v) { return v.stringValue().startsWith(PREFIX_FOR_EXTERNAL_BNODES); } public Resource asResource(Node node) { Resource res; if (node==null || node==Node.ANY) { res = null; } else if (node.isURI()) { res = createURI(node.getURI()); } else if (node.isBlank()) { res = createBNode(node.getBlankNodeLabel()); } else { throw new IllegalArgumentException("Cannot convert Node to Resource: " + node); } return res; } public URI asURI(Node node) { URI uri; if (node==null || node==Node.ANY) { uri = null; } else if (node.isURI()) { uri = createURI(node.getURI()); } else if (node.isBlank()) { // TODO: research this more, seems to be needed for the test // suite, as blank nodes appear in the predicate position uri = createURI("http://anon/" + node.getBlankNodeLabel()); } else { throw new IllegalArgumentException("Cannot convert Node to URI: " + node); } return uri; } /*********************** * * Encodable Namespaces * ***********************/ /** * Returns unique URIs within the specified encodable namespace. * *

The generated URIs will conform to the format that was specified * when the encodable namespace was registered, and are guaranteed * to be unique for this namespace generator. Note that this does * not prevent other parties from independently using URIs that * involve this namespace, however.

* *

If amount cannot be generated, up to amount URIs will be returned, * or an exception will be thrown if none are available.

* * @see AGRepositoryConnection#registerEncodableNamespace(String, String) * @see #generateURI(String) * * @return a unique URI within the specified namespace. */ public URI[] generateURIs(String namespace, int amount) throws RepositoryException { String[] uri_strs; URI[] uris; try { uri_strs = getHTTPClient().generateURIs(getRepository().getRepositoryURL(),namespace,amount); uris = new URI[uri_strs.length]; for (int i=0;iThe generated URI will conform to the format that was specified * when the encodable namespace was registered, and is guaranteed * to be unique for this namespace generator. Note that this does * not prevent other parties from independently using URIs that * involve this namespace, however.

* * @see AGRepositoryConnection#registerEncodableNamespace(String, String) * @see #generateURIs(String, int) * * @return a unique URI within the specified namespace. */ public URI generateURI(String registeredEncodableNamespace) throws RepositoryException { return generateURIs(registeredEncodableNamespace,1)[0]; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy