JENA-625, prepare for jena-csv 1.0 release: 1. modify dependency from SNAPSHOT to release 2. refactor the package layout 3. move LangCSV from jena-arq module to jena-csv 4. modify jena-csv version to 1.0
git-svn-id: http://svn.apache.org/repos/asf/jena/Experimental/jena-csv@1618100 13f79535-47bb-0310-9956-ffa450edef68 Project: http://git-wip-us.apache.org/repos/asf/jena/repo Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/74c4bd06 Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/74c4bd06 Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/74c4bd06 Branch: refs/heads/master Commit: 74c4bd06f1b8dbc63989887cc525a159ed4b1be3 Parents: e7e9229 Author: Ying Jiang <[email protected]> Authored: Fri Aug 15 05:37:29 2014 +0000 Committer: Ying Jiang <[email protected]> Committed: Fri Aug 15 05:37:29 2014 +0000 ---------------------------------------------------------------------- pom.xml | 29 +- .../jena/propertytable/graph/GraphCSV.java | 55 ++++ .../propertytable/graph/GraphPropertyTable.java | 196 ++++++++++++++ .../graph/QueryIterPropertyTable.java | 120 +++++++++ .../graph/QueryIterPropertyTableRow.java | 237 +++++++++++++++++ .../jena/propertytable/graph/RowMatch.java | 44 ++++ .../graph/StageGeneratorPropertyTable.java | 56 ++++ .../jena/propertytable/impl/GraphCSV.java | 54 ---- .../propertytable/impl/GraphPropertyTable.java | 196 -------------- .../impl/PropertyTableBuilder.java | 2 +- .../impl/QueryIterPropertyTable.java | 120 --------- .../impl/QueryIterPropertyTableRow.java | 237 ----------------- .../jena/propertytable/impl/RowMatch.java | 44 ---- .../impl/StageGeneratorPropertyTable.java | 55 ---- .../apache/jena/propertytable/lang/LangCSV.java | 225 ++++++++++++++++ .../apache/jena/propertytable/util/IRILib.java | 262 +++++++++++++++++++ .../jena/propertytable/TS_PropertyTable.java | 4 +- .../jena/propertytable/graph/GraphCSVTest.java | 149 +++++++++++ .../jena/propertytable/impl/GraphCSVTest.java | 142 ---------- .../jena/propertytable/lang/TestLangCSV.java | 107 ++++++++ 20 files changed, 1474 insertions(+), 860 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jena/blob/74c4bd06/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index ad246ac..457532b 100644 --- a/pom.xml +++ b/pom.xml @@ -22,21 +22,30 @@ <artifactId>jena-csv</artifactId> <packaging>jar</packaging> <name>Apache Jena - Data Tables for SPARQL</name> - <version>0.1-SNAPSHOT</version> + <version>1.0</version> <parent> <groupId>org.apache.jena</groupId> <artifactId>jena-parent</artifactId> - <version>10-SNAPSHOT</version> + <version>10</version> <relativePath>../jena-parent</relativePath> </parent> - + + <!-- Need if the parent is a snapshot --> + <repositories> + <repository> + <id>apache.snapshots</id> + <name>Apache Snapshot Repository</name> + <url>http://repository.apache.org/snapshots</url> + <releases> + <enabled>false</enabled> + </releases> + </repository> + </repositories> + + <description>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.</description> + <properties> - <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> - - <jdk.version>1.6</jdk.version> - <targetJdk>${jdk.version}</targetJdk> <!-- MPMD-86 workaround --> - <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.build.timestamp.format>yyyy-MM-dd'T'HH:mm:ssZ</maven.build.timestamp.format> <build.time.xsd>${maven.build.timestamp}</build.time.xsd> </properties> @@ -47,7 +56,7 @@ <dependency> <groupId>org.apache.jena</groupId> <artifactId>apache-jena-libs</artifactId> - <version>2.12.1-SNAPSHOT</version> + <version>2.12.0</version> <type>pom</type> </dependency> @@ -62,7 +71,7 @@ <dependency> <groupId>org.apache.jena</groupId> <artifactId>jena-arq</artifactId> - <version>2.12.1-SNAPSHOT</version> + <version>2.12.0</version> <type>jar</type> <classifier>tests</classifier> <scope>test</scope> http://git-wip-us.apache.org/repos/asf/jena/blob/74c4bd06/src/main/java/org/apache/jena/propertytable/graph/GraphCSV.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/jena/propertytable/graph/GraphCSV.java b/src/main/java/org/apache/jena/propertytable/graph/GraphCSV.java new file mode 100644 index 0000000..54ad131 --- /dev/null +++ b/src/main/java/org/apache/jena/propertytable/graph/GraphCSV.java @@ -0,0 +1,55 @@ +/* + * 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 org.apache.jena.propertytable.PropertyTable; +import org.apache.jena.propertytable.impl.PropertyTableBuilder; + + +public class GraphCSV extends GraphPropertyTable { + + public static GraphCSV createHashMapImpl( String csvFilePath ){ + return new GraphCSVHashMapImpl(csvFilePath); + } + + public static GraphCSV createArrayImpl( String csvFilePath ){ + return new GraphCSVArrayImpl(csvFilePath); + } + + protected GraphCSV (PropertyTable table) { + super(table); + } + + public GraphCSV ( String csvFilePath ){ + super(PropertyTableBuilder.buildPropetyTableArrayImplFromCsv(csvFilePath)); + } +} + + +class GraphCSVHashMapImpl extends GraphCSV{ + protected GraphCSVHashMapImpl(String csvFilePath){ + super(PropertyTableBuilder.buildPropetyTableHashMapImplFromCsv(csvFilePath)); + } +} + +class GraphCSVArrayImpl extends GraphCSV{ + protected GraphCSVArrayImpl(String csvFilePath){ + super(PropertyTableBuilder.buildPropetyTableArrayImplFromCsv(csvFilePath)); + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/74c4bd06/src/main/java/org/apache/jena/propertytable/graph/GraphPropertyTable.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/jena/propertytable/graph/GraphPropertyTable.java b/src/main/java/org/apache/jena/propertytable/graph/GraphPropertyTable.java new file mode 100644 index 0000000..8054279 --- /dev/null +++ b/src/main/java/org/apache/jena/propertytable/graph/GraphPropertyTable.java @@ -0,0 +1,196 @@ +/* + * 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 org.apache.jena.propertytable.Column; +import org.apache.jena.propertytable.PropertyTable; +import org.apache.jena.propertytable.Row; + + +import com.hp.hpl.jena.graph.Node; +import com.hp.hpl.jena.graph.NodeFactory; +import com.hp.hpl.jena.graph.Triple; +import com.hp.hpl.jena.graph.TripleMatch; +import com.hp.hpl.jena.graph.impl.GraphBase; +import com.hp.hpl.jena.sparql.core.BasicPattern; +import com.hp.hpl.jena.util.iterator.ExtendedIterator; +import com.hp.hpl.jena.util.iterator.Filter; +import com.hp.hpl.jena.util.iterator.NullIterator; +import com.hp.hpl.jena.util.iterator.WrappedIterator; + +public class GraphPropertyTable extends GraphBase { + + private PropertyTable pt; + + public GraphPropertyTable(PropertyTable pt) { + this.pt = pt; + } + + public PropertyTable getPropertyTable() { + return pt; + } + + @Override + protected ExtendedIterator<Triple> graphBaseFind(TripleMatch m) { + //System.out.println(m); + + if (this.pt == null) { + return NullIterator.instance(); + } + + ExtendedIterator<Triple> iter = null; + + Node s = m.getMatchSubject(); + Node p = m.getMatchPredicate(); + Node o = m.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(m.asTriple())); + + } + + protected ExtendedIterator<Row> propertyTableBaseFind(RowMatch m) { + + if (this.pt == null) { + return NullIterator.instance(); + } + + ExtendedIterator<Row> iter = null; + + Node s = m.getMatchSubject(); + + if ( isConcrete(s) ){ + Row row= pt.getRow(s); + if (row == null){ + return NullIterator.instance(); + } else { + ArrayList<Row> rows = new ArrayList<Row>(); + rows.add(row); + return WrappedIterator.create(rows.iterator()); + } + } else { + iter = WrappedIterator.create(pt.getAllRows().iterator()); + } + + return iter.filterKeep(new RowMatchFilterEquality( m )); + + } + + static class RowMatchFilterEquality extends Filter<Row> { + final protected RowMatch rMatch; + + public RowMatchFilterEquality(RowMatch rMatch) { + this.rMatch = rMatch; + } + + @Override + public boolean accept(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 extends Filter<Triple> { + final protected Triple tMatch; + + /** Creates new TripleMatchFilter */ + public TripleMatchFilterEquality(Triple tMatch) { + this.tMatch = tMatch; + } + + @Override + public boolean accept(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; + } + +} http://git-wip-us.apache.org/repos/asf/jena/blob/74c4bd06/src/main/java/org/apache/jena/propertytable/graph/QueryIterPropertyTable.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/jena/propertytable/graph/QueryIterPropertyTable.java b/src/main/java/org/apache/jena/propertytable/graph/QueryIterPropertyTable.java new file mode 100644 index 0000000..0d737fb --- /dev/null +++ b/src/main/java/org/apache/jena/propertytable/graph/QueryIterPropertyTable.java @@ -0,0 +1,120 @@ +/* + * 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.Collection; +import java.util.HashMap; +import java.util.List; + +import org.apache.jena.atlas.io.IndentedWriter; + +import com.hp.hpl.jena.graph.Graph; +import com.hp.hpl.jena.graph.Node; +import com.hp.hpl.jena.graph.Triple; +import com.hp.hpl.jena.sparql.core.BasicPattern; +import com.hp.hpl.jena.sparql.engine.ExecutionContext; +import com.hp.hpl.jena.sparql.engine.QueryIterator; +import com.hp.hpl.jena.sparql.engine.binding.Binding; +import com.hp.hpl.jena.sparql.engine.iterator.QueryIter1; +import com.hp.hpl.jena.sparql.serializer.SerializationContext; +import com.hp.hpl.jena.sparql.util.FmtUtils; +import com.hp.hpl.jena.sparql.util.Utils; + +public class QueryIterPropertyTable extends QueryIter1 + { + private BasicPattern pattern ; + private Graph graph ; + private QueryIterator output ; + + public static QueryIterator create(QueryIterator input, + BasicPattern pattern , + ExecutionContext execContext) + { + return new QueryIterPropertyTable(input, pattern, execContext) ; + } + + private QueryIterPropertyTable(QueryIterator input, + BasicPattern pattern , + ExecutionContext execContext) + { + super(input, execContext) ; + this.pattern = pattern ; + graph = execContext.getActiveGraph() ; + // Create a chain of triple iterators. + QueryIterator chain = getInput() ; + Collection<BasicPattern> patterns = sort(pattern); + for (BasicPattern p : patterns) + chain = new QueryIterPropertyTableRow(chain, p, execContext) ; + output = chain ; + } + + private Collection<BasicPattern> sort(BasicPattern pattern){ + HashMap<Node, BasicPattern> map= new HashMap<Node, BasicPattern>(); + for(Triple triple: pattern.getList()){ + Node subject = triple.getSubject(); + if(! map.containsKey(subject)){ + List<Triple> triples = new ArrayList<Triple>(); + BasicPattern p = BasicPattern.wrap(triples); + map.put(subject, p); + p.add(triple); + }else { + map.get(subject).add(triple); + } + } + return map.values(); + } + + @Override + protected boolean hasNextBinding() + { + return output.hasNext() ; + } + + @Override + protected Binding moveToNextBinding() + { + return output.nextBinding() ; + } + + @Override + protected void closeSubIterator() + { + if ( output != null ) + output.close() ; + output = null ; + } + + @Override + protected void requestSubCancel() + { + if ( output != null ) + output.cancel(); + } + + @Override + protected void details(IndentedWriter out, SerializationContext sCxt) + { + out.print(Utils.className(this)) ; + out.println() ; + out.incIndent() ; + FmtUtils.formatPattern(out, pattern, sCxt) ; + out.decIndent() ; + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/74c4bd06/src/main/java/org/apache/jena/propertytable/graph/QueryIterPropertyTableRow.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/jena/propertytable/graph/QueryIterPropertyTableRow.java b/src/main/java/org/apache/jena/propertytable/graph/QueryIterPropertyTableRow.java new file mode 100644 index 0000000..16f6723 --- /dev/null +++ b/src/main/java/org/apache/jena/propertytable/graph/QueryIterPropertyTableRow.java @@ -0,0 +1,237 @@ +/* + * 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.List; + +import org.apache.jena.propertytable.PropertyTable; +import org.apache.jena.propertytable.Row; + + +import com.hp.hpl.jena.graph.Node; +import com.hp.hpl.jena.graph.Triple; +import com.hp.hpl.jena.sparql.ARQInternalErrorException; +import com.hp.hpl.jena.sparql.core.BasicPattern; +import com.hp.hpl.jena.sparql.core.Var; +import com.hp.hpl.jena.sparql.engine.ExecutionContext; +import com.hp.hpl.jena.sparql.engine.QueryIterator; +import com.hp.hpl.jena.sparql.engine.binding.Binding; +import com.hp.hpl.jena.sparql.engine.binding.BindingFactory; +import com.hp.hpl.jena.sparql.engine.binding.BindingMap; +import com.hp.hpl.jena.sparql.engine.iterator.QueryIter; +import com.hp.hpl.jena.sparql.engine.iterator.QueryIterRepeatApply; +import com.hp.hpl.jena.util.iterator.ClosableIterator; +import com.hp.hpl.jena.util.iterator.ExtendedIterator; +import com.hp.hpl.jena.util.iterator.NiceIterator; +import com.hp.hpl.jena.util.iterator.WrappedIterator; + +public class QueryIterPropertyTableRow extends QueryIterRepeatApply{ + private final BasicPattern pattern ; + + public QueryIterPropertyTableRow( QueryIterator input, + BasicPattern pattern , + ExecutionContext cxt) + { + super(input, cxt) ; + this.pattern = pattern ; + } + + @Override + protected QueryIterator nextStage(Binding binding) + { + return new RowMapper(binding, pattern, getExecContext()) ; + } + + static int countMapper = 0 ; + static class RowMapper extends QueryIter + { + private PropertyTable table; + + private BasicPattern pattern; + private Binding binding ; + private ClosableIterator<Row> graphIter ; + private Binding slot = null ; + private boolean finished = false ; + private volatile boolean cancelled = false ; + + RowMapper(Binding binding, BasicPattern pattern, ExecutionContext cxt) + { + super(cxt) ; + GraphPropertyTable graph = (GraphPropertyTable)cxt.getActiveGraph() ; + + this.pattern = substitute(pattern, binding); + this.binding = binding ; + BasicPattern pattern2 = tripleNode(pattern); + + ExtendedIterator<Row> iter = graph.propertyTableBaseFind( new RowMatch( pattern2) ); + + if ( false ) + { + // Materialize the results now. Debugging only. + List<Row> x = iter.toList() ; + this.graphIter = WrappedIterator.create(x.iterator()) ; + iter.close(); + } + else + // Stream. + this.graphIter = iter ; + } + + private static Node tripleNode(Node node) + { + if ( node.isVariable() ) + return Node.ANY ; + return node ; + } + + private static BasicPattern tripleNode(BasicPattern pattern) + { + List<Triple> triples = new ArrayList<Triple>(); + for (Triple triple: pattern){ + triples.add( tripleNode(triple) ); + } + return BasicPattern.wrap(triples); + } + + private static Triple tripleNode(Triple triple){ + Node s = tripleNode(triple.getSubject()) ; + Node p = tripleNode(triple.getPredicate()) ; + Node o = tripleNode(triple.getObject()) ; + return Triple.create(s, p, o); + } + + private static Node substitute(Node node, Binding binding) + { + if ( Var.isVar(node) ) + { + Node x = binding.get(Var.alloc(node)) ; + if ( x != null ) + return x ; + } + return node ; + } + + private static Triple substitute(Triple triple, Binding binding){ + Node s = substitute(triple.getSubject(), binding) ; + Node p = substitute(triple.getPredicate(), binding) ; + Node o = substitute(triple.getObject(), binding) ; + return Triple.create(s, p, o); + } + + private static BasicPattern substitute(BasicPattern pattern , Binding binding) + { + List<Triple> triples = new ArrayList<Triple>(); + for (Triple triple: pattern){ + triples.add( substitute(triple,binding) ); + } + return BasicPattern.wrap(triples); + } + + private Binding mapper(Row r) + { + BindingMap results = BindingFactory.create(binding) ; + + if ( ! insert(pattern, r, results) ) + return null ; + return results ; + } + + private static boolean insert(BasicPattern input, Row output, BindingMap results) + { + for (Triple triple: input){ + if (! insert(triple, output, results) ){ + return false; + } + } + return true; + } + + private static boolean insert(Triple input, Row output, BindingMap results){ + if ( ! insert(input.getSubject(), output.getRowKey(), results) ) + return false ; +// if ( ! insert(input.getPredicate(), output.get, results) ) +// return false ; + if ( ! insert(input.getObject(), output.getValue( input.getPredicate() ), results) ) + return false ; + return true; + } + + private static boolean insert(Node inputNode, Node outputNode, BindingMap results) + { + if ( ! Var.isVar(inputNode) ) + return true ; + + Var v = Var.alloc(inputNode) ; + Node x = results.get(v) ; + if ( x != null ) + return outputNode.equals(x) ; + + results.add(v, outputNode) ; + return true ; + } + + @Override + protected boolean hasNextBinding() + { + if ( finished ) return false ; + if ( slot != null ) return true ; + if ( cancelled ) + { + graphIter.close() ; + finished = true ; + return false ; + } + + while(graphIter.hasNext() && slot == null ) + { + Row r = graphIter.next() ; + slot = mapper(r) ; + } + if ( slot == null ) + finished = true ; + return slot != null ; + } + + @Override + protected Binding moveToNextBinding() + { + if ( ! hasNextBinding() ) + throw new ARQInternalErrorException() ; + Binding r = slot ; + slot = null ; + return r ; + } + + @Override + protected void closeIterator() + { + if ( graphIter != null ) + NiceIterator.close(graphIter) ; + graphIter = null ; + } + + @Override + protected void requestCancel() + { + // The QueryIteratorBase machinary will do the real work. + cancelled = true ; + } + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/74c4bd06/src/main/java/org/apache/jena/propertytable/graph/RowMatch.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/jena/propertytable/graph/RowMatch.java b/src/main/java/org/apache/jena/propertytable/graph/RowMatch.java new file mode 100644 index 0000000..3310807 --- /dev/null +++ b/src/main/java/org/apache/jena/propertytable/graph/RowMatch.java @@ -0,0 +1,44 @@ +/* + * 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 com.hp.hpl.jena.graph.Node; +import com.hp.hpl.jena.sparql.core.BasicPattern; + +public class RowMatch { + + private BasicPattern pattern; + + public RowMatch( BasicPattern pattern ){ + this.pattern=pattern; + } + + public Node getMatchSubject(){ + return pattern.get(0).getMatchSubject(); + } + + public Node getSubject(){ + return pattern.get(0).getSubject(); + } + + public BasicPattern getBasicPattern(){ + return pattern; + } + +} http://git-wip-us.apache.org/repos/asf/jena/blob/74c4bd06/src/main/java/org/apache/jena/propertytable/graph/StageGeneratorPropertyTable.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/jena/propertytable/graph/StageGeneratorPropertyTable.java b/src/main/java/org/apache/jena/propertytable/graph/StageGeneratorPropertyTable.java new file mode 100644 index 0000000..c601000 --- /dev/null +++ b/src/main/java/org/apache/jena/propertytable/graph/StageGeneratorPropertyTable.java @@ -0,0 +1,56 @@ +/* + * 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 com.hp.hpl.jena.graph.Graph; +import com.hp.hpl.jena.sparql.core.BasicPattern; +import com.hp.hpl.jena.sparql.engine.ExecutionContext; +import com.hp.hpl.jena.sparql.engine.QueryIterator; +import com.hp.hpl.jena.sparql.engine.main.StageGenerator; + +public class StageGeneratorPropertyTable implements StageGenerator { + + // Using OpExecutor is preferred. + StageGenerator above = null ; + + public StageGeneratorPropertyTable(StageGenerator original) + { + above = original ; + } + + @Override + public QueryIterator execute(BasicPattern pattern, QueryIterator input, ExecutionContext execCxt) + { + // --- In case this isn't for GraphPropertyTable + Graph g = execCxt.getActiveGraph() ; + + if ( ! ( g instanceof GraphPropertyTable ) ) + // Not us - bounce up the StageGenerator chain + return above.execute(pattern, input, execCxt) ; + if (pattern.size() <= 1){ +// System.out.println( "<=1 "+ pattern); + return above.execute(pattern, input, execCxt) ; + } +// System.out.println( ">1" + pattern); + return QueryIterPropertyTable.create(input, pattern, execCxt); + } + + +} http://git-wip-us.apache.org/repos/asf/jena/blob/74c4bd06/src/main/java/org/apache/jena/propertytable/impl/GraphCSV.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/jena/propertytable/impl/GraphCSV.java b/src/main/java/org/apache/jena/propertytable/impl/GraphCSV.java deleted file mode 100644 index 6ae4514..0000000 --- a/src/main/java/org/apache/jena/propertytable/impl/GraphCSV.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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.impl; - -import org.apache.jena.propertytable.PropertyTable; - - -public class GraphCSV extends GraphPropertyTable { - - public static GraphCSV createHashMapImpl( String csvFilePath ){ - return new GraphCSVHashMapImpl(csvFilePath); - } - - public static GraphCSV createArrayImpl( String csvFilePath ){ - return new GraphCSVArrayImpl(csvFilePath); - } - - protected GraphCSV (PropertyTable table) { - super(table); - } - - public GraphCSV ( String csvFilePath ){ - super(PropertyTableBuilder.buildPropetyTableArrayImplFromCsv(csvFilePath)); - } -} - - -class GraphCSVHashMapImpl extends GraphCSV{ - protected GraphCSVHashMapImpl(String csvFilePath){ - super(PropertyTableBuilder.buildPropetyTableHashMapImplFromCsv(csvFilePath)); - } -} - -class GraphCSVArrayImpl extends GraphCSV{ - protected GraphCSVArrayImpl(String csvFilePath){ - super(PropertyTableBuilder.buildPropetyTableArrayImplFromCsv(csvFilePath)); - } -} http://git-wip-us.apache.org/repos/asf/jena/blob/74c4bd06/src/main/java/org/apache/jena/propertytable/impl/GraphPropertyTable.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/jena/propertytable/impl/GraphPropertyTable.java b/src/main/java/org/apache/jena/propertytable/impl/GraphPropertyTable.java deleted file mode 100644 index 3188bcb..0000000 --- a/src/main/java/org/apache/jena/propertytable/impl/GraphPropertyTable.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * 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.impl; - -import java.util.ArrayList; -import java.util.Locale; - -import org.apache.jena.propertytable.Column; -import org.apache.jena.propertytable.PropertyTable; -import org.apache.jena.propertytable.Row; - - -import com.hp.hpl.jena.graph.Node; -import com.hp.hpl.jena.graph.NodeFactory; -import com.hp.hpl.jena.graph.Triple; -import com.hp.hpl.jena.graph.TripleMatch; -import com.hp.hpl.jena.graph.impl.GraphBase; -import com.hp.hpl.jena.sparql.core.BasicPattern; -import com.hp.hpl.jena.util.iterator.ExtendedIterator; -import com.hp.hpl.jena.util.iterator.Filter; -import com.hp.hpl.jena.util.iterator.NullIterator; -import com.hp.hpl.jena.util.iterator.WrappedIterator; - -public class GraphPropertyTable extends GraphBase { - - private PropertyTable pt; - - public GraphPropertyTable(PropertyTable pt) { - this.pt = pt; - } - - public PropertyTable getPropertyTable() { - return pt; - } - - @Override - protected ExtendedIterator<Triple> graphBaseFind(TripleMatch m) { - //System.out.println(m); - - if (this.pt == null) { - return NullIterator.instance(); - } - - ExtendedIterator<Triple> iter = null; - - Node s = m.getMatchSubject(); - Node p = m.getMatchPredicate(); - Node o = m.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(m.asTriple())); - - } - - protected ExtendedIterator<Row> propertyTableBaseFind(RowMatch m) { - - if (this.pt == null) { - return NullIterator.instance(); - } - - ExtendedIterator<Row> iter = null; - - Node s = m.getMatchSubject(); - - if ( isConcrete(s) ){ - Row row= pt.getRow(s); - if (row == null){ - return NullIterator.instance(); - } else { - ArrayList<Row> rows = new ArrayList<Row>(); - rows.add(row); - return WrappedIterator.create(rows.iterator()); - } - } else { - iter = WrappedIterator.create(pt.getAllRows().iterator()); - } - - return iter.filterKeep(new RowMatchFilterEquality( m )); - - } - - static class RowMatchFilterEquality extends Filter<Row> { - final protected RowMatch rMatch; - - public RowMatchFilterEquality(RowMatch rMatch) { - this.rMatch = rMatch; - } - - @Override - public boolean accept(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 extends Filter<Triple> { - final protected Triple tMatch; - - /** Creates new TripleMatchFilter */ - public TripleMatchFilterEquality(Triple tMatch) { - this.tMatch = tMatch; - } - - @Override - public boolean accept(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; - } - -} http://git-wip-us.apache.org/repos/asf/jena/blob/74c4bd06/src/main/java/org/apache/jena/propertytable/impl/PropertyTableBuilder.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/jena/propertytable/impl/PropertyTableBuilder.java b/src/main/java/org/apache/jena/propertytable/impl/PropertyTableBuilder.java index 7a2a74f..0c625f7 100644 --- a/src/main/java/org/apache/jena/propertytable/impl/PropertyTableBuilder.java +++ b/src/main/java/org/apache/jena/propertytable/impl/PropertyTableBuilder.java @@ -27,7 +27,7 @@ import org.apache.jena.atlas.csv.CSVTokenIterator; import org.apache.jena.atlas.io.IO; import org.apache.jena.propertytable.PropertyTable; import org.apache.jena.propertytable.Row; -import org.apache.jena.riot.lang.LangCSV; +import org.apache.jena.propertytable.lang.LangCSV; import org.apache.jena.riot.system.IRIResolver; import com.hp.hpl.jena.datatypes.xsd.XSDDatatype; http://git-wip-us.apache.org/repos/asf/jena/blob/74c4bd06/src/main/java/org/apache/jena/propertytable/impl/QueryIterPropertyTable.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/jena/propertytable/impl/QueryIterPropertyTable.java b/src/main/java/org/apache/jena/propertytable/impl/QueryIterPropertyTable.java deleted file mode 100644 index 1a9e350..0000000 --- a/src/main/java/org/apache/jena/propertytable/impl/QueryIterPropertyTable.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * 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.impl; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; - -import org.apache.jena.atlas.io.IndentedWriter; - -import com.hp.hpl.jena.graph.Graph; -import com.hp.hpl.jena.graph.Node; -import com.hp.hpl.jena.graph.Triple; -import com.hp.hpl.jena.sparql.core.BasicPattern; -import com.hp.hpl.jena.sparql.engine.ExecutionContext; -import com.hp.hpl.jena.sparql.engine.QueryIterator; -import com.hp.hpl.jena.sparql.engine.binding.Binding; -import com.hp.hpl.jena.sparql.engine.iterator.QueryIter1; -import com.hp.hpl.jena.sparql.serializer.SerializationContext; -import com.hp.hpl.jena.sparql.util.FmtUtils; -import com.hp.hpl.jena.sparql.util.Utils; - -public class QueryIterPropertyTable extends QueryIter1 - { - private BasicPattern pattern ; - private Graph graph ; - private QueryIterator output ; - - public static QueryIterator create(QueryIterator input, - BasicPattern pattern , - ExecutionContext execContext) - { - return new QueryIterPropertyTable(input, pattern, execContext) ; - } - - private QueryIterPropertyTable(QueryIterator input, - BasicPattern pattern , - ExecutionContext execContext) - { - super(input, execContext) ; - this.pattern = pattern ; - graph = execContext.getActiveGraph() ; - // Create a chain of triple iterators. - QueryIterator chain = getInput() ; - Collection<BasicPattern> patterns = sort(pattern); - for (BasicPattern p : patterns) - chain = new QueryIterPropertyTableRow(chain, p, execContext) ; - output = chain ; - } - - private Collection<BasicPattern> sort(BasicPattern pattern){ - HashMap<Node, BasicPattern> map= new HashMap<Node, BasicPattern>(); - for(Triple triple: pattern.getList()){ - Node subject = triple.getSubject(); - if(! map.containsKey(subject)){ - List<Triple> triples = new ArrayList<Triple>(); - BasicPattern p = BasicPattern.wrap(triples); - map.put(subject, p); - p.add(triple); - }else { - map.get(subject).add(triple); - } - } - return map.values(); - } - - @Override - protected boolean hasNextBinding() - { - return output.hasNext() ; - } - - @Override - protected Binding moveToNextBinding() - { - return output.nextBinding() ; - } - - @Override - protected void closeSubIterator() - { - if ( output != null ) - output.close() ; - output = null ; - } - - @Override - protected void requestSubCancel() - { - if ( output != null ) - output.cancel(); - } - - @Override - protected void details(IndentedWriter out, SerializationContext sCxt) - { - out.print(Utils.className(this)) ; - out.println() ; - out.incIndent() ; - FmtUtils.formatPattern(out, pattern, sCxt) ; - out.decIndent() ; - } -} http://git-wip-us.apache.org/repos/asf/jena/blob/74c4bd06/src/main/java/org/apache/jena/propertytable/impl/QueryIterPropertyTableRow.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/jena/propertytable/impl/QueryIterPropertyTableRow.java b/src/main/java/org/apache/jena/propertytable/impl/QueryIterPropertyTableRow.java deleted file mode 100644 index c304f7d..0000000 --- a/src/main/java/org/apache/jena/propertytable/impl/QueryIterPropertyTableRow.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * 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.impl; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.jena.propertytable.PropertyTable; -import org.apache.jena.propertytable.Row; - - -import com.hp.hpl.jena.graph.Node; -import com.hp.hpl.jena.graph.Triple; -import com.hp.hpl.jena.sparql.ARQInternalErrorException; -import com.hp.hpl.jena.sparql.core.BasicPattern; -import com.hp.hpl.jena.sparql.core.Var; -import com.hp.hpl.jena.sparql.engine.ExecutionContext; -import com.hp.hpl.jena.sparql.engine.QueryIterator; -import com.hp.hpl.jena.sparql.engine.binding.Binding; -import com.hp.hpl.jena.sparql.engine.binding.BindingFactory; -import com.hp.hpl.jena.sparql.engine.binding.BindingMap; -import com.hp.hpl.jena.sparql.engine.iterator.QueryIter; -import com.hp.hpl.jena.sparql.engine.iterator.QueryIterRepeatApply; -import com.hp.hpl.jena.util.iterator.ClosableIterator; -import com.hp.hpl.jena.util.iterator.ExtendedIterator; -import com.hp.hpl.jena.util.iterator.NiceIterator; -import com.hp.hpl.jena.util.iterator.WrappedIterator; - -public class QueryIterPropertyTableRow extends QueryIterRepeatApply{ - private final BasicPattern pattern ; - - public QueryIterPropertyTableRow( QueryIterator input, - BasicPattern pattern , - ExecutionContext cxt) - { - super(input, cxt) ; - this.pattern = pattern ; - } - - @Override - protected QueryIterator nextStage(Binding binding) - { - return new RowMapper(binding, pattern, getExecContext()) ; - } - - static int countMapper = 0 ; - static class RowMapper extends QueryIter - { - private PropertyTable table; - - private BasicPattern pattern; - private Binding binding ; - private ClosableIterator<Row> graphIter ; - private Binding slot = null ; - private boolean finished = false ; - private volatile boolean cancelled = false ; - - RowMapper(Binding binding, BasicPattern pattern, ExecutionContext cxt) - { - super(cxt) ; - GraphPropertyTable graph = (GraphPropertyTable)cxt.getActiveGraph() ; - - this.pattern = substitute(pattern, binding); - this.binding = binding ; - BasicPattern pattern2 = tripleNode(pattern); - - ExtendedIterator<Row> iter = graph.propertyTableBaseFind( new RowMatch( pattern2) ); - - if ( false ) - { - // Materialize the results now. Debugging only. - List<Row> x = iter.toList() ; - this.graphIter = WrappedIterator.create(x.iterator()) ; - iter.close(); - } - else - // Stream. - this.graphIter = iter ; - } - - private static Node tripleNode(Node node) - { - if ( node.isVariable() ) - return Node.ANY ; - return node ; - } - - private static BasicPattern tripleNode(BasicPattern pattern) - { - List<Triple> triples = new ArrayList<Triple>(); - for (Triple triple: pattern){ - triples.add( tripleNode(triple) ); - } - return BasicPattern.wrap(triples); - } - - private static Triple tripleNode(Triple triple){ - Node s = tripleNode(triple.getSubject()) ; - Node p = tripleNode(triple.getPredicate()) ; - Node o = tripleNode(triple.getObject()) ; - return Triple.create(s, p, o); - } - - private static Node substitute(Node node, Binding binding) - { - if ( Var.isVar(node) ) - { - Node x = binding.get(Var.alloc(node)) ; - if ( x != null ) - return x ; - } - return node ; - } - - private static Triple substitute(Triple triple, Binding binding){ - Node s = substitute(triple.getSubject(), binding) ; - Node p = substitute(triple.getPredicate(), binding) ; - Node o = substitute(triple.getObject(), binding) ; - return Triple.create(s, p, o); - } - - private static BasicPattern substitute(BasicPattern pattern , Binding binding) - { - List<Triple> triples = new ArrayList<Triple>(); - for (Triple triple: pattern){ - triples.add( substitute(triple,binding) ); - } - return BasicPattern.wrap(triples); - } - - private Binding mapper(Row r) - { - BindingMap results = BindingFactory.create(binding) ; - - if ( ! insert(pattern, r, results) ) - return null ; - return results ; - } - - private static boolean insert(BasicPattern input, Row output, BindingMap results) - { - for (Triple triple: input){ - if (! insert(triple, output, results) ){ - return false; - } - } - return true; - } - - private static boolean insert(Triple input, Row output, BindingMap results){ - if ( ! insert(input.getSubject(), output.getRowKey(), results) ) - return false ; -// if ( ! insert(input.getPredicate(), output.get, results) ) -// return false ; - if ( ! insert(input.getObject(), output.getValue( input.getPredicate() ), results) ) - return false ; - return true; - } - - private static boolean insert(Node inputNode, Node outputNode, BindingMap results) - { - if ( ! Var.isVar(inputNode) ) - return true ; - - Var v = Var.alloc(inputNode) ; - Node x = results.get(v) ; - if ( x != null ) - return outputNode.equals(x) ; - - results.add(v, outputNode) ; - return true ; - } - - @Override - protected boolean hasNextBinding() - { - if ( finished ) return false ; - if ( slot != null ) return true ; - if ( cancelled ) - { - graphIter.close() ; - finished = true ; - return false ; - } - - while(graphIter.hasNext() && slot == null ) - { - Row r = graphIter.next() ; - slot = mapper(r) ; - } - if ( slot == null ) - finished = true ; - return slot != null ; - } - - @Override - protected Binding moveToNextBinding() - { - if ( ! hasNextBinding() ) - throw new ARQInternalErrorException() ; - Binding r = slot ; - slot = null ; - return r ; - } - - @Override - protected void closeIterator() - { - if ( graphIter != null ) - NiceIterator.close(graphIter) ; - graphIter = null ; - } - - @Override - protected void requestCancel() - { - // The QueryIteratorBase machinary will do the real work. - cancelled = true ; - } - } -} http://git-wip-us.apache.org/repos/asf/jena/blob/74c4bd06/src/main/java/org/apache/jena/propertytable/impl/RowMatch.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/jena/propertytable/impl/RowMatch.java b/src/main/java/org/apache/jena/propertytable/impl/RowMatch.java deleted file mode 100644 index cbd699a..0000000 --- a/src/main/java/org/apache/jena/propertytable/impl/RowMatch.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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.impl; - -import com.hp.hpl.jena.graph.Node; -import com.hp.hpl.jena.sparql.core.BasicPattern; - -public class RowMatch { - - private BasicPattern pattern; - - public RowMatch( BasicPattern pattern ){ - this.pattern=pattern; - } - - public Node getMatchSubject(){ - return pattern.get(0).getMatchSubject(); - } - - public Node getSubject(){ - return pattern.get(0).getSubject(); - } - - public BasicPattern getBasicPattern(){ - return pattern; - } - -} http://git-wip-us.apache.org/repos/asf/jena/blob/74c4bd06/src/main/java/org/apache/jena/propertytable/impl/StageGeneratorPropertyTable.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/jena/propertytable/impl/StageGeneratorPropertyTable.java b/src/main/java/org/apache/jena/propertytable/impl/StageGeneratorPropertyTable.java deleted file mode 100644 index 68fb025..0000000 --- a/src/main/java/org/apache/jena/propertytable/impl/StageGeneratorPropertyTable.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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.impl; - -import com.hp.hpl.jena.graph.Graph; -import com.hp.hpl.jena.sparql.core.BasicPattern; -import com.hp.hpl.jena.sparql.engine.ExecutionContext; -import com.hp.hpl.jena.sparql.engine.QueryIterator; -import com.hp.hpl.jena.sparql.engine.main.StageGenerator; - -public class StageGeneratorPropertyTable implements StageGenerator { - - // Using OpExecutor is preferred. - StageGenerator above = null ; - - public StageGeneratorPropertyTable(StageGenerator original) - { - above = original ; - } - - @Override - public QueryIterator execute(BasicPattern pattern, QueryIterator input, ExecutionContext execCxt) - { - // --- In case this isn't for GraphPropertyTable - Graph g = execCxt.getActiveGraph() ; - - if ( ! ( g instanceof GraphPropertyTable ) ) - // Not us - bounce up the StageGenerator chain - return above.execute(pattern, input, execCxt) ; - if (pattern.size() <= 1){ -// System.out.println( "<=1 "+ pattern); - return above.execute(pattern, input, execCxt) ; - } -// System.out.println( ">1" + pattern); - return QueryIterPropertyTable.create(input, pattern, execCxt); - } - - -} http://git-wip-us.apache.org/repos/asf/jena/blob/74c4bd06/src/main/java/org/apache/jena/propertytable/lang/LangCSV.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/jena/propertytable/lang/LangCSV.java b/src/main/java/org/apache/jena/propertytable/lang/LangCSV.java new file mode 100644 index 0000000..d53f7a7 --- /dev/null +++ b/src/main/java/org/apache/jena/propertytable/lang/LangCSV.java @@ -0,0 +1,225 @@ +/** + * 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.lang; + +import static org.apache.jena.riot.RDFLanguages.CSV; + +import java.io.InputStream; +import java.io.Reader; +import java.util.ArrayList; +import java.util.List; + +import org.apache.jena.atlas.csv.CSVParser; +import org.apache.jena.atlas.web.ContentType; +import org.apache.jena.propertytable.util.IRILib; +import org.apache.jena.riot.Lang; +import org.apache.jena.riot.RDFLanguages; +import org.apache.jena.riot.RDFParserRegistry; +import org.apache.jena.riot.ReaderRIOT; +import org.apache.jena.riot.ReaderRIOTFactory; +import org.apache.jena.riot.lang.LangRIOT; +import org.apache.jena.riot.system.ErrorHandler; +import org.apache.jena.riot.system.ErrorHandlerFactory; +import org.apache.jena.riot.system.IRIResolver; +import org.apache.jena.riot.system.ParserProfile; +import org.apache.jena.riot.system.RiotLib; +import org.apache.jena.riot.system.StreamRDF; + +import com.hp.hpl.jena.datatypes.xsd.XSDDatatype; +import com.hp.hpl.jena.graph.Node; +import com.hp.hpl.jena.graph.NodeFactory; +import com.hp.hpl.jena.sparql.util.Context; + +public class LangCSV implements LangRIOT { + + public static final String CSV_PREFIX = "http://w3c/future-csv-vocab/"; + public static final String CSV_ROW = CSV_PREFIX + "row"; + + private InputStream input = null; + private Reader reader = null; + private String base; + private String filename; + private StreamRDF sink; + private ParserProfile profile; // Warning - we don't use all of this. + + public static void register(){ + RDFParserRegistry.removeRegistration(Lang.CSV); + RDFParserRegistry.registerLangTriples(Lang.CSV, new ReaderRIOTFactoryCSV()); + } + + @Override + public Lang getLang() { + return RDFLanguages.CSV; + } + + @Override + public ParserProfile getProfile() { + return profile; + } + + @Override + public void setProfile(ParserProfile profile) { + this.profile = profile; + } + + public LangCSV(Reader reader, String base, String filename, + ErrorHandler errorHandler, StreamRDF sink) { + this.reader = reader; + this.base = base; + this.filename = filename; + this.sink = sink; + this.profile = RiotLib.profile(getLang(), base, errorHandler); + } + + public LangCSV(InputStream in, String base, String filename, + ErrorHandler errorHandler, StreamRDF sink) { + this.input = in; + this.base = base; + this.filename = filename; + this.sink = sink; + this.profile = RiotLib.profile(getLang(), base, errorHandler); + } + + @Override + public void parse() { + sink.start(); + CSVParser parser = (input != null) ? CSVParser.create(input) + : CSVParser.create(reader); + List<String> row = null; + ArrayList<Node> predicates = new ArrayList<Node>(); + int rowNum = 0; + while ((row = parser.parse1()) != null) { + + if (rowNum == 0) { + for (String column : row) { + String uri = IRIResolver.resolveString(filename) + "#" + + toSafeLocalname(column); + Node predicate = this.profile.createURI(uri, rowNum, 0); + predicates.add(predicate); + } + } else { + //Node subject = this.profile.createBlankNode(null, -1, -1); + Node subject = caculateSubject(rowNum, filename); + Node predicateRow = this.profile.createURI(CSV_ROW, -1, -1); + Node objectRow = this.profile + .createTypedLiteral((rowNum + ""), + XSDDatatype.XSDinteger, rowNum, 0); + sink.triple(this.profile.createTriple(subject, predicateRow, + objectRow, rowNum, 0)); + for (int col = 0; col < row.size() && col<predicates.size(); col++) { + Node predicate = predicates.get(col); + String columnValue = row.get(col).trim(); + if("".equals(columnValue)){ + continue; + } + Node o; + try { + // Try for a double. + double d = Double.parseDouble(columnValue); + o = NodeFactory.createLiteral(columnValue, + XSDDatatype.XSDdouble); + } catch (Exception e) { + o = NodeFactory.createLiteral(columnValue); + } + sink.triple(this.profile.createTriple(subject, predicate, + o, rowNum, col)); + } + + } + rowNum++; + } + sink.finish(); + + } + + public static String toSafeLocalname(String raw) { + String ret = raw.trim(); + return encodeURIComponent(ret); + + } + + public static String encodeURIComponent(String s) { + return IRILib.encodeUriComponent(s); + } + + public static Node caculateSubject(int rowNum, String filename){ + Node subject = NodeFactory.createAnon(); +// String uri = IRIResolver.resolveString(filename) + "#Row_" + rowNum; +// Node subject = NodeFactory.createURI(uri); + return subject; + } + + + + + private static class ReaderRIOTFactoryCSV implements ReaderRIOTFactory + { + @Override + public ReaderRIOT create(Lang lang) { + return new ReaderRIOTLangCSV(lang) ; + } + } + + private static class ReaderRIOTLangCSV implements ReaderRIOT + { + private final Lang lang ; + private ErrorHandler errorHandler ; + private ParserProfile parserProfile = null ; + + ReaderRIOTLangCSV(Lang lang) { + this.lang = lang ; + errorHandler = ErrorHandlerFactory.getDefaultErrorHandler() ; + } + + @Override + public void read(InputStream in, String baseURI, ContentType ct, StreamRDF output, Context context) { + if ( lang == CSV){ + LangRIOT parser = new LangCSV (in, baseURI, baseURI, ErrorHandlerFactory.getDefaultErrorHandler(), output); + if ( parserProfile != null ) + parser.setProfile(parserProfile); + if ( errorHandler != null ) + parser.getProfile().setHandler(errorHandler) ; + parser.parse() ; + } else { + throw new IllegalArgumentException("The Lang must be 'CSV'!"); + } + + } + + @Override + public void read(Reader in, String baseURI, ContentType ct, StreamRDF output, Context context) { + if ( lang == CSV){ + LangRIOT parser = new LangCSV (in, baseURI, baseURI, ErrorHandlerFactory.getDefaultErrorHandler(), output); + if ( parserProfile != null ) + parser.setProfile(parserProfile); + if ( errorHandler != null ) + parser.getProfile().setHandler(errorHandler) ; + parser.parse() ; + } else { + throw new IllegalArgumentException("The Lang must be 'CSV'!"); + } + } + + @Override public ErrorHandler getErrorHandler() { return errorHandler ; } + @Override public void setErrorHandler(ErrorHandler errorHandler) { this.errorHandler = errorHandler ; } + + @Override public ParserProfile getParserProfile() { return parserProfile ; } + @Override public void setParserProfile(ParserProfile parserProfile) { this.parserProfile = parserProfile ; } + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/74c4bd06/src/main/java/org/apache/jena/propertytable/util/IRILib.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/jena/propertytable/util/IRILib.java b/src/main/java/org/apache/jena/propertytable/util/IRILib.java new file mode 100644 index 0000000..7df9b7f --- /dev/null +++ b/src/main/java/org/apache/jena/propertytable/util/IRILib.java @@ -0,0 +1,262 @@ +/* + * 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.util; + +import java.io.File ; +import java.io.IOException ; + +import org.apache.jena.atlas.AtlasException ; +import org.apache.jena.atlas.lib.Chars ; +import org.apache.jena.atlas.lib.StrUtils ; +import org.apache.jena.riot.SysRIOT ; + +/** + * Operations related to IRIs + * Add '£', based on org.apache.jena.riot.system.IRILib + */ +public class IRILib +{ + // http://www.w3.org/TR/xpath-functions/#func-encode-for-uri + // Encodes delimiters. + + /* RFC 3986 + * + * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" + * gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" + * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" + / "*" / "+" / "," / ";" / "=" + */ + + private static char uri_reserved[] = + { + '!', '*', '"', '\'', '(', ')', ';', ':', '@', '&', + '=', '+', '$', ',', '/', '?', '%', '#', '[', ']'} ; + + // No allowed in URIs + private static char uri_non_chars[] = { '<', '>', '{', '}', '|', '\\', '`', '^', ' ', '\n', '\r', '\t', '£' } ; + + // RFC 2396 + //private static char uri_unwise[] = { '{' , '}', '|', '\\', '^', '[', ']', '`' } ; + + + private static char[] charsComponent = + // reserved, + non-chars + nasties. + { '!', '*', '"', '\'', '(', ')', ';', ':', '@', '&', + '=', '+', '$', ',', '/', '?', '%', '#', '[', ']', + '{', '}', '|', '\\', '`', '^', + ' ', '<', '>', '\n', '\r', '\t', '£' } ; + + private static char[] charsFilename = + // reserved, + non-chars + nasties. + // Leave : (Windows drive charcater) and / (separator) alone + // include SPC and ~ + { '!', '*', '"', '\'', '(', ')', ';', /*':',*/ '@', '&', + '=', '+', '$', ',', /*'/',*/ '?', '%', '#', '[', ']', + '{', '}', '|', '\\', '`', '^', + ' ', '<', '>', '\n', '\r', '\t', + '~'} ; + + private static char[] charsPath = + { + // Reserved except leave the separators alone. + // Leave the path separator alone. + // Leave the drive separator alone. + '!', '*', '"', '\'', '(', ')', ';', /*':',*/ '@', '&', + '=', '+', '$', ',', /*'/',*/ '?', '%', '#', '[', ']', + '{', '}', '|', '\\', '`', '^', + // Other junk + ' ', '<', '>', '\n', '\r', '\t' } ; + + // The initializers must have run. + static final String cwd ; + static final String cwdURL ; + + // Current directory, with trailing "/" + // This matters for resolution. + static { + String x = new File(".").getAbsolutePath() ; + x = x.substring(0, x.length()-1) ; + cwd = x ; + cwdURL = plainFilenameToURL(cwd) ; + } + + // See also IRIResolver + /** Return a string that is an IRI for the filename.*/ + public static String fileToIRI(File f) + { + return filenameToIRI(f.getAbsolutePath()) ; + } + + /** Create a string that is a IRI for the filename. + * The file name may already have file:. + * The file name may be relative. + * Encode using the rules for a path (e.g. ':' and'/' do not get encoded) + */ + public static String filenameToIRI(String fn) + { + if ( fn == null ) return cwdURL ; + + if ( fn.length() == 0 ) return cwdURL ; + + if ( fn.startsWith("file:") ) + return normalizeFilenameURI(fn) ; + return plainFilenameToURL(fn) ; + } + + /** Convert an IRI to a filename */ + public static String IRIToFilename(String iri) + { + if ( ! iri.startsWith("file:") ) + throw new AtlasException("Not a file: URI: "+iri) ; + + String fn ; + if ( iri.startsWith("file:///") ) + fn = iri.substring("file://".length()) ; + else + fn = iri.substring("file:".length()) ; + return decode(fn) ; + } + + /** Convert a plain file name (no file:) to a file: URL */ + private static String plainFilenameToURL(String fn) + { + // No "file:" + // Make Absolute filename. + boolean trailingSlash = fn.endsWith("/") ; + File file = new File(fn) ; + + try { fn = file.getCanonicalPath() ; } + catch (IOException e) { fn = file.getAbsolutePath() ; } + + if ( trailingSlash && ! fn.endsWith("/") ) + fn = fn + "/" ; + + if ( SysRIOT.isWindows ) + { + // C:\ => file:///C:/... + if ( fn.length() >= 2 && fn.charAt(1) == ':' ) + // Windows drive letter - already absolute path. + // Make "URI" absolute path + fn = "/"+fn ; + // Convert \ to / + // Maybe should do this on all platforms? i.e consistency. + fn = fn.replace('\\', '/' ) ; + } + + fn = encodeFileURL(fn) ; + return "file://"+fn ; + } + + + /** Sanitize a "file:" URL. Must start "file:" */ + private static String normalizeFilenameURI(String fn) + { + if ( ! fn.startsWith("file:/") ) + { + // Relative path. + String fn2 = fn.substring("file:".length()) ; + return plainFilenameToURL(fn2) ; + } + + // Starts file:/// + if ( fn.startsWith("file:///") ) + // Assume it's good as return as-is. + return fn ; + + if ( fn.startsWith("file://") ) + { + String fn2 = fn.substring("file:/".length()) ; // Leave one "/" + return plainFilenameToURL(fn2) ; + } + + // Must be file:/ + String fn2 = fn.substring("file:".length()) ; + return plainFilenameToURL(fn2) ; + } + + /** Encode using the rules for a component (e.g. ':' and '/' get encoded) + * Does not encode non-ASCII characters + */ + public static String encodeUriComponent(String string) + { + String encStr = StrUtils.encodeHex(string,'%', charsComponent) ; + return encStr ; + } + + /** Encode using the rules for a file: URL. + * Does not encode non-ASCII characters + */ + public static String encodeFileURL(String string) + { + String encStr = StrUtils.encodeHex(string,'%', charsFilename) ; + return encStr ; + } + + /** Encode using the rules for a path (e.g. ':' and '/' do not get encoded) */ + public static String encodeUriPath(String uri) + { + // Not perfect. + // Encode path. + // %-encode chars. + uri = StrUtils.encodeHex(uri, '%', charsPath) ; + return uri ; + } + + public static String decode(String string) + { + return StrUtils.decodeHex(string, '%') ; + } + + public static String encodeNonASCII(String string) + { + if ( ! containsNonASCII(string) ) + return string ; + + byte[] bytes = StrUtils.asUTF8bytes(string) ; + StringBuilder sw = new StringBuilder() ; + for ( byte b : bytes ) + { + // Signed bytes ... + if ( b > 0 ) + { + sw.append( (char) b ); + continue; + } + + int hi = ( b & 0xF0 ) >> 4; + int lo = b & 0xF; + sw.append( '%' ); + sw.append( Chars.hexDigitsUC[hi] ); + sw.append( Chars.hexDigitsUC[lo] ); + } + return sw.toString() ; + } + + public static boolean containsNonASCII(String string) + { + boolean clean = true ; + for ( int i = 0 ; i < string.length() ; i++ ) + { + char ch = string.charAt(i) ; + if ( ch >= 127 ) + return true; + } + return false ; + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/74c4bd06/src/test/java/org/apache/jena/propertytable/TS_PropertyTable.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/jena/propertytable/TS_PropertyTable.java b/src/test/java/org/apache/jena/propertytable/TS_PropertyTable.java index 9c916e9..084365d 100644 --- a/src/test/java/org/apache/jena/propertytable/TS_PropertyTable.java +++ b/src/test/java/org/apache/jena/propertytable/TS_PropertyTable.java @@ -18,11 +18,12 @@ package org.apache.jena.propertytable; -import org.apache.jena.propertytable.impl.GraphCSVTest; +import org.apache.jena.propertytable.graph.GraphCSVTest; import org.apache.jena.propertytable.impl.PropertyTableArrayImplTest; import org.apache.jena.propertytable.impl.PropertyTableBuilderForArrayImplTest; import org.apache.jena.propertytable.impl.PropertyTableBuilderForHashMapImplTest; import org.apache.jena.propertytable.impl.PropertyTableHashMapImplTest; +import org.apache.jena.propertytable.lang.TestLangCSV; import org.junit.runner.RunWith; import org.junit.runners.Suite; @@ -34,6 +35,7 @@ import org.junit.runners.Suite; GraphCSVTest.class, PropertyTableBuilderForArrayImplTest.class, PropertyTableBuilderForHashMapImplTest.class, + TestLangCSV.class }) public class TS_PropertyTable { http://git-wip-us.apache.org/repos/asf/jena/blob/74c4bd06/src/test/java/org/apache/jena/propertytable/graph/GraphCSVTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/jena/propertytable/graph/GraphCSVTest.java b/src/test/java/org/apache/jena/propertytable/graph/GraphCSVTest.java new file mode 100644 index 0000000..d6b0c26 --- /dev/null +++ b/src/test/java/org/apache/jena/propertytable/graph/GraphCSVTest.java @@ -0,0 +1,149 @@ +/* + * 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 org.apache.jena.propertytable.graph.GraphCSV; +import org.apache.jena.propertytable.lang.LangCSV; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.hp.hpl.jena.query.ARQ; +import com.hp.hpl.jena.query.Query; +import com.hp.hpl.jena.query.QueryExecution; +import com.hp.hpl.jena.query.QueryExecutionFactory; +import com.hp.hpl.jena.query.QueryFactory; +import com.hp.hpl.jena.query.QuerySolution; +import com.hp.hpl.jena.query.ResultSet; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.ModelFactory; +import com.hp.hpl.jena.sparql.engine.main.StageBuilder; +import com.hp.hpl.jena.sparql.engine.main.StageGenerator; + +public class GraphCSVTest extends Assert { + + @BeforeClass + public static void init(){ + LangCSV.register(); + } + + @Test + public void testGraphCSV() throws Exception { + //String file = "src/test/resources/HEFCE_organogram_senior_data_31032011.csv";test.csv + String file = "src/test/resources/test.csv"; + + Model csv = ModelFactory.createModelForGraph(new GraphCSV(file)); + assertEquals(12, csv.size()); + + Query query = QueryFactory + .create("PREFIX : <src/test/resources/test.csv#> SELECT ?townName ?pop {?x :Town ?townName ; :Population ?pop ; :Predicate%20With%20Space 'PredicateWithSpace2' . FILTER(?pop > 500000)}"); + + QueryExecution qexec = QueryExecutionFactory.create(query, csv); + ResultSet results = qexec.execSelect(); + + assertTrue(results.hasNext()); + QuerySolution soln = results.nextSolution(); + assertEquals( "Northville", soln.getLiteral("townName").getString()); + assertTrue( 654000 == soln.getLiteral("pop").getInt()); + + assertFalse(results.hasNext()); + } + + @Test + public void stageGeneratorTest() throws Exception{ + wireIntoExecution(); + testGraphCSV(); + } + + private static void wireIntoExecution() { + StageGenerator orig = (StageGenerator)ARQ.getContext().get(ARQ.stageGenerator) ; + StageGenerator stageGenerator = new StageGeneratorPropertyTable(orig) ; + StageBuilder.setGenerator(ARQ.getContext(), stageGenerator) ; + } + + //http://www.w3.org/TR/csvw-ucr/#UC-OrganogramData + //2.4 Use Case #4 - Publication of public sector roles and salaries + @Test + public void testUseCase4(){ + String file = "src/test/resources/HEFCE_organogram_senior_data_31032011.csv"; + + Model csv = ModelFactory.createModelForGraph(new GraphCSV(file)); + assertEquals(72, csv.size()); + + Query query = QueryFactory + .create("PREFIX : <src/test/resources/HEFCE_organogram_senior_data_31032011.csv#> SELECT ?name ?unit {?x :Name ?name ; :Unit ?unit ; :Actual%20Pay%20Floor%20%28%A3%29 ?floor ; :Actual%20Pay%20Ceiling%20%28%A3%29 ?ceiling . FILTER(?floor > 100000 && ?ceiling <120000 )}"); + + QueryExecution qexec = QueryExecutionFactory.create(query, csv); + ResultSet results = qexec.execSelect(); + + assertTrue(results.hasNext()); + QuerySolution soln = results.nextSolution(); + assertEquals( "David Sweeney", soln.getLiteral("name").getString()); + assertEquals( "Research, Innovation and Skills", soln.getLiteral("unit").getString()); + + assertFalse(results.hasNext()); + } + + + //http://www.w3.org/TR/csvw-ucr/#UC-JournalArticleSearch + //2.6 Use Case #6 - Journal Article Solr Search Results + @Test + public void testUseCase6(){ + String file = "src/test/resources/PLOSone-search-results.csv"; + + Model csv = ModelFactory.createModelForGraph(new GraphCSV(file)); + assertEquals(30, csv.size()); + + Query query = QueryFactory + .create("PREFIX : <src/test/resources/PLOSone-search-results.csv#> SELECT ?author {?x :author ?author ; :doi '10.1371/journal.pone.0095156' }"); + + QueryExecution qexec = QueryExecutionFactory.create(query, csv); + ResultSet results = qexec.execSelect(); + + assertTrue(results.hasNext()); + QuerySolution soln = results.nextSolution(); + assertEquals( "Oshrat Raz,Dorit L Lev,Alexander Battler,Eli I Lev", soln.getLiteral("author").getString()); + + assertFalse(results.hasNext()); + } + + //http://www.w3.org/TR/csvw-ucr/#UC-PaloAltoTreeData + //2.11 Use Case #11 - City of Palo Alto Tree Data + @Test + public void testUseCase11(){ + String file = "src/test/resources/Palo_Alto_Trees.csv"; + + Model csv = ModelFactory.createModelForGraph(new GraphCSV(file)); + assertEquals(199, csv.size()); + + Query query = QueryFactory + .create("PREFIX : <src/test/resources/Palo_Alto_Trees.csv#> SELECT ?longitude ?latitude {?x :Longitude ?longitude ; :Latitude ?latitude ; :Distance%20from%20Property ?distance . FILTER(?distance > 50 )}"); + + QueryExecution qexec = QueryExecutionFactory.create(query, csv); + ResultSet results = qexec.execSelect(); + + assertTrue(results.hasNext()); + QuerySolution soln = results.nextSolution(); + assertEquals( -122.1566921, soln.getLiteral("longitude").getDouble(), 0); + assertEquals( 37.4408948, soln.getLiteral("latitude").getDouble(), 0); + + assertFalse(results.hasNext()); + } + +}
