org.apache.jena.propertytable.graph.GraphPropertyTable Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jena-csv Show documentation
Show all versions of jena-csv Show documentation
jena-csv is for getting CSVs into a form that is amenable to Jena SPARQL processing, and doing so in a way that is not specific to CSV files. It includes getting the right architecture in place for regular table shaped data, using the core abstraction of PropertyTable.
/*
* 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.propertytable.graph;
import java.util.ArrayList ;
import java.util.Locale ;
import java.util.function.Predicate;
import org.apache.jena.graph.Node ;
import org.apache.jena.graph.NodeFactory ;
import org.apache.jena.graph.Triple ;
import org.apache.jena.graph.impl.GraphBase ;
import org.apache.jena.propertytable.Column ;
import org.apache.jena.propertytable.PropertyTable ;
import org.apache.jena.propertytable.Row ;
import org.apache.jena.sparql.core.BasicPattern ;
import org.apache.jena.util.iterator.ExtendedIterator ;
import org.apache.jena.util.iterator.NullIterator ;
import org.apache.jena.util.iterator.WrappedIterator ;
/**
* GraphPropertyTable implements the Graph interface (read-only) over a PropertyTable.
* This is subclass from GraphBase and implements find().
* The graphBaseFind()(for matching a Triple) and propertyTableBaseFind()(for matching a whole Row) methods can choose the access route based on the find arguments.
* GraphPropertyTable holds/wraps an reference of the PropertyTable instance, so that such a Graph can be treated in a more table-like fashion.
*
*/
public class GraphPropertyTable extends GraphBase {
private PropertyTable pt;
public GraphPropertyTable(PropertyTable pt) {
this.pt = pt;
}
public PropertyTable getPropertyTable() {
return pt;
}
@Override
protected ExtendedIterator graphBaseFind(Triple triple) {
//System.out.println(m);
if (this.pt == null) {
return NullIterator.instance();
}
ExtendedIterator iter = null;
Node s = triple.getMatchSubject();
Node p = triple.getMatchPredicate();
Node o = triple.getMatchObject();
if (isConcrete(p) && isConcrete(o)) {
//System.out.println("1");
iter = pt.getTripleIterator(pt.getColumn(p), o);
} else if (isConcrete(p)) {
//System.out.println("2");
Column column = this.pt.getColumn(p);
if (column != null) {
iter = pt.getTripleIterator(column);
} else {
return NullIterator.instance();
}
} else if (isConcrete(o)) {
//System.out.println("3");
iter = pt.getTripleIterator(o);
} else{
//System.out.println("4");
iter = pt.getTripleIterator();
}
return iter.filterKeep(new TripleMatchFilterEquality(triple));
}
protected ExtendedIterator propertyTableBaseFind(RowMatch m) {
if (this.pt == null) {
return NullIterator.instance();
}
ExtendedIterator iter = null;
Node s = m.getMatchSubject();
if ( isConcrete(s) ){
Row row= pt.getRow(s);
if (row == null){
return NullIterator.instance();
} else {
ArrayList rows = new ArrayList<>();
rows.add(row);
return WrappedIterator.create(rows.iterator());
}
} else {
iter = WrappedIterator.create(pt.getAllRows().iterator());
}
return iter.filterKeep(new RowMatchFilterEquality( m ));
}
static class RowMatchFilterEquality implements Predicate {
final protected RowMatch rMatch;
public RowMatchFilterEquality(RowMatch rMatch) {
this.rMatch = rMatch;
}
@Override
public boolean test(Row r) {
return rowContained(rMatch, r);
}
}
static boolean rowContained(RowMatch rMatch, Row row) {
boolean contained = equalNode(rMatch.getSubject(), row.getRowKey());
if(contained){
BasicPattern pattern =rMatch.getBasicPattern();
for(Triple triple: pattern ){
contained = equalNode(triple.getObject(), row.getValue( triple.getPredicate()) );
if (! contained){
break;
}
}
}
return contained;
}
static class TripleMatchFilterEquality implements Predicate {
final protected Triple tMatch;
/** Creates new TripleMatchFilter */
public TripleMatchFilterEquality(Triple tMatch) {
this.tMatch = tMatch;
}
@Override
public boolean test(Triple t) {
return tripleContained(tMatch, t);
}
}
static boolean tripleContained(Triple patternTriple, Triple dataTriple) {
return equalNode(patternTriple.getSubject(), dataTriple.getSubject())
&& equalNode(patternTriple.getPredicate(),
dataTriple.getPredicate())
&& equalNode(patternTriple.getObject(), dataTriple.getObject());
}
private static boolean equalNode(Node m, Node n) {
// m should not be null unless .getMatchXXXX used to get the node.
// Language tag canonicalization
n = fixupNode(n);
m = fixupNode(m);
return (m == null) || (m == Node.ANY) || m.equals(n);
}
private static Node fixupNode(Node node) {
if (node == null || node == Node.ANY)
return node;
// RDF says ... language tags should be canonicalized to lower case.
if (node.isLiteral()) {
String lang = node.getLiteralLanguage();
if (lang != null && !lang.equals(""))
node = NodeFactory.createLiteral(node.getLiteralLexicalForm(),
lang.toLowerCase(Locale.ROOT),
node.getLiteralDatatype());
}
return node;
}
private boolean isConcrete(Node node) {
boolean wild = (node == null || node == Node.ANY);
return !wild;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy