blob: 8a9b9a1d111143e33835b1ded3b28f636f8d2fa8 [file] [log] [blame]
/*
* 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.rya.rdftriplestore.utils;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.rdf4j.OpenRDFUtil;
import org.eclipse.rdf4j.model.BNode;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Resource;
import org.eclipse.rdf4j.model.Statement;
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.repository.RepositoryConnection;
import org.eclipse.rdf4j.repository.RepositoryException;
import org.eclipse.rdf4j.rio.RDFHandlerException;
import org.eclipse.rdf4j.rio.helpers.AbstractRDFHandler;
/**
* Created by IntelliJ IDEA.
* User: RoshanP
* Date: 3/23/12
* Time: 9:50 AM
* To change this template use File | Settings | File Templates.
*/
public class CombineContextsRdfInserter extends AbstractRDFHandler {
private final RepositoryConnection con;
private Resource[] contexts = new Resource[0];
private boolean preserveBNodeIDs;
private final Map<String, String> namespaceMap;
private final Map<String, BNode> bNodesMap;
public CombineContextsRdfInserter(RepositoryConnection con) {
this.con = con;
preserveBNodeIDs = true;
namespaceMap = new HashMap<String, String>();
bNodesMap = new HashMap<String, BNode>();
}
public void setPreserveBNodeIDs(boolean preserveBNodeIDs) {
this.preserveBNodeIDs = preserveBNodeIDs;
}
public boolean preservesBNodeIDs() {
return preserveBNodeIDs;
}
public void enforceContext(Resource... contexts) {
OpenRDFUtil.verifyContextNotNull(contexts);
this.contexts = contexts;
}
public boolean enforcesContext() {
return contexts.length != 0;
}
public Resource[] getContexts() {
return contexts;
}
@Override
public void endRDF()
throws RDFHandlerException {
for (Map.Entry<String, String> entry : namespaceMap.entrySet()) {
String prefix = entry.getKey();
String name = entry.getValue();
try {
if (con.getNamespace(prefix) == null) {
con.setNamespace(prefix, name);
}
} catch (RepositoryException e) {
throw new RDFHandlerException(e);
}
}
namespaceMap.clear();
bNodesMap.clear();
}
@Override
public void handleNamespace(String prefix, String name) {
// FIXME: set namespaces directly when they are properly handled wrt
// rollback
// don't replace earlier declarations
if (prefix != null && !namespaceMap.containsKey(prefix)) {
namespaceMap.put(prefix, name);
}
}
@Override
public void handleStatement(Statement st)
throws RDFHandlerException {
Resource subj = st.getSubject();
IRI pred = st.getPredicate();
Value obj = st.getObject();
Resource ctxt = st.getContext();
if (!preserveBNodeIDs) {
if (subj instanceof BNode) {
subj = mapBNode((BNode) subj);
}
if (obj instanceof BNode) {
obj = mapBNode((BNode) obj);
}
if (!enforcesContext() && ctxt instanceof BNode) {
ctxt = mapBNode((BNode) ctxt);
}
}
try {
if (enforcesContext()) {
Resource[] ctxts = contexts;
if (ctxt != null) {
ctxts = combineContexts(contexts, ctxt);
}
con.add(subj, pred, obj, ctxts);
} else {
con.add(subj, pred, obj, ctxt);
}
} catch (RepositoryException e) {
throw new RDFHandlerException(e);
}
}
private BNode mapBNode(BNode bNode) {
BNode result = bNodesMap.get(bNode.getID());
if (result == null) {
result = con.getRepository().getValueFactory().createBNode();
bNodesMap.put(bNode.getID(), result);
}
return result;
}
public static Resource[] combineContexts(Resource[] contexts, Resource ctxt) {
if (contexts == null || ctxt == null) {
throw new IllegalArgumentException("Contexts cannot be null");
}
int length = contexts.length;
Resource[] ret = new Resource[length + 1];
System.arraycopy(contexts, 0, ret, 0, length);
ret[length] = ctxt;
return ret;
}
}