You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by rv...@apache.org on 2014/10/02 11:48:55 UTC
[46/50] [abbrv] Move jena-csv code to intended location
http://git-wip-us.apache.org/repos/asf/jena/blob/e7ac8b4d/jena-csv/src/main/java/org/apache/jena/propertytable/impl/PropertyTableBuilder.java
----------------------------------------------------------------------
diff --git a/jena-csv/src/main/java/org/apache/jena/propertytable/impl/PropertyTableBuilder.java b/jena-csv/src/main/java/org/apache/jena/propertytable/impl/PropertyTableBuilder.java
new file mode 100644
index 0000000..665c282
--- /dev/null
+++ b/jena-csv/src/main/java/org/apache/jena/propertytable/impl/PropertyTableBuilder.java
@@ -0,0 +1,134 @@
+/*
+ * 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.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.jena.atlas.csv.CSVParser;
+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.propertytable.lang.LangCSV;
+import org.apache.jena.riot.system.IRIResolver;
+
+import com.hp.hpl.jena.datatypes.xsd.XSDDatatype;
+import com.hp.hpl.jena.graph.Node;
+import com.hp.hpl.jena.graph.NodeFactory;
+
+
+/**
+ * A tool for constructing PropertyTable from a file (e.g., a CSV file).
+ *
+ *
+ */
+public class PropertyTableBuilder {
+
+ public static Node CSV_ROW_NODE = NodeFactory.createURI(LangCSV.CSV_ROW);
+
+ public static PropertyTable buildPropetyTableHashMapImplFromCsv(String csvFilePath) {
+ PropertyTable table = new PropertyTableHashMapImpl();
+ return fillPropertyTable(table, csvFilePath);
+ }
+
+ public static PropertyTable buildPropetyTableArrayImplFromCsv(String csvFilePath) {
+ PropertyTable table = createEmptyPropertyTableArrayImpl(csvFilePath);
+ return fillPropertyTable(table, csvFilePath);
+ }
+
+ private static PropertyTable createEmptyPropertyTableArrayImpl (String csvFilePath) {
+ CSVParser parser = CSVParser.create(csvFilePath);
+ List<String> rowLine = null;
+ int rowNum = 0;
+ int columnNum = 0;
+
+ while ((rowLine = parser.parse1()) != null) {
+ if (rowNum == 0) {
+ columnNum = rowLine.size();
+ }
+ rowNum++;
+ }
+ if (rowNum!=0 && columnNum!=0){
+ return new PropertyTableArrayImpl(rowNum, columnNum+1);
+ } else {
+ return null;
+ }
+ }
+
+ protected static PropertyTable fillPropertyTable(PropertyTable table, String csvFilePath ){
+ InputStream input = IO.openFile(csvFilePath) ;
+ CSVTokenIterator iterator = new CSVTokenIterator(input) ;
+ return fillPropertyTable(table, iterator, csvFilePath);
+ }
+
+ protected static PropertyTable fillPropertyTable(PropertyTable table, CSVTokenIterator iterator, String csvFilePath){
+ if (table == null){
+ return null;
+ }
+ CSVParser parser = new CSVParser (iterator);
+ List<String> rowLine = null;
+ ArrayList<Node> predicates = new ArrayList<Node>();
+ int rowNum = 0;
+
+ while ((rowLine = parser.parse1()) != null) {
+ if (rowNum == 0) {
+ table.createColumn(CSV_ROW_NODE);
+ for (String column : rowLine) {
+ String uri = createColumnKeyURI(csvFilePath, column);
+ Node p = NodeFactory.createURI(uri);
+ predicates.add(p);
+ table.createColumn(p);
+ }
+ } else {
+ Node subject = LangCSV.caculateSubject(rowNum, csvFilePath);
+ Row row = table.createRow(subject);
+
+ row.setValue(table.getColumn(CSV_ROW_NODE), NodeFactory.createLiteral(
+ (rowNum + ""), XSDDatatype.XSDinteger));
+
+ for (int col = 0; col < rowLine.size() && col<predicates.size(); col++) {
+
+ String columnValue = rowLine.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);
+ }
+ row.setValue(table.getColumn(predicates.get(col)), o);
+ }
+ }
+ rowNum++;
+ }
+ return table;
+ }
+
+ protected static String createColumnKeyURI(String csvFilePath, String column){
+ String uri = IRIResolver.resolveString(csvFilePath) + "#" + LangCSV.toSafeLocalname(column);
+ return uri;
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/e7ac8b4d/jena-csv/src/main/java/org/apache/jena/propertytable/impl/PropertyTableHashMapImpl.java
----------------------------------------------------------------------
diff --git a/jena-csv/src/main/java/org/apache/jena/propertytable/impl/PropertyTableHashMapImpl.java b/jena-csv/src/main/java/org/apache/jena/propertytable/impl/PropertyTableHashMapImpl.java
new file mode 100644
index 0000000..b74925b
--- /dev/null
+++ b/jena-csv/src/main/java/org/apache/jena/propertytable/impl/PropertyTableHashMapImpl.java
@@ -0,0 +1,357 @@
+/*
+ * 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 java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.apache.jena.atlas.iterator.Iter;
+import org.apache.jena.atlas.iterator.IteratorConcat;
+import org.apache.jena.propertytable.Column;
+import org.apache.jena.propertytable.PropertyTable;
+import org.apache.jena.propertytable.Row;
+
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.SetMultimap;
+import com.hp.hpl.jena.graph.Node;
+import com.hp.hpl.jena.graph.Triple;
+import com.hp.hpl.jena.util.iterator.ExtendedIterator;
+import com.hp.hpl.jena.util.iterator.WrappedIterator;
+
+/**
+ * A PropertyTable Implementation using HashMap.
+ * It contains PSO and POS indexes.
+ *
+ */
+public class PropertyTableHashMapImpl implements PropertyTable {
+
+ private Map<Node, Column> columnIndex; // Maps property Node key to Column
+ private List<Column> columnList; // Stores the list of columns in the table
+ private Map<Node, Row> rowIndex; // Maps the subject Node key to Row.
+ private List<Row> rowList; // Stores the list of rows in the table
+
+ // PSO index
+ private Map<Node, Map<Node, Node>> valueIndex; // Maps column Node to
+ // (subject Node, value)
+ // pairs
+ // POS index
+ private Map<Node, SetMultimap<Node, Node>> valueReverseIndex; // Maps column
+ // Node to
+ // (value,
+ // subject
+ // Node)
+ // pairs
+
+ PropertyTableHashMapImpl() {
+ columnIndex = new HashMap<Node, Column>();
+ columnList = new ArrayList<Column>();
+ rowIndex = new HashMap<Node, Row>();
+ rowList = new ArrayList<Row>();
+ valueIndex = new HashMap<Node, Map<Node, Node>>();
+ valueReverseIndex = new HashMap<Node, SetMultimap<Node, Node>>();
+ }
+
+ @Override
+ public ExtendedIterator<Triple> getTripleIterator() {
+
+ // use PSO index to scan all the table (slow)
+ IteratorConcat<Triple> iter = new IteratorConcat<Triple>();
+ for (Column column : getColumns()) {
+ iter.add(getTripleIterator(column));
+ }
+ return WrappedIterator.create(Iter.distinct(iter));
+ }
+
+ @Override
+ public ExtendedIterator<Triple> getTripleIterator(Column column) {
+
+ // use PSO index directly (fast)
+
+ if (column == null || column.getColumnKey() == null)
+ throw new NullPointerException("column is null");
+
+ ArrayList<Triple> triples = new ArrayList<Triple>();
+ Map<Node, Node> values = valueIndex.get(column.getColumnKey());
+
+ for (Entry<Node, Node> entry : values.entrySet()) {
+ Node subject = entry.getKey();
+ Node value = entry.getValue();
+ triples.add(Triple.create(subject, column.getColumnKey(), value));
+ }
+ return WrappedIterator.create(triples.iterator());
+ }
+
+ @Override
+ public ExtendedIterator<Triple> getTripleIterator(Node value) {
+
+ // use POS index ( O(n), n= column count )
+
+ if (value == null)
+ throw new NullPointerException("value is null");
+
+ IteratorConcat<Triple> iter = new IteratorConcat<Triple>();
+ for (Column column : this.getColumns()) {
+ ExtendedIterator<Triple> eIter = getTripleIterator(column,value);
+ iter.add(eIter);
+ }
+ return WrappedIterator.create(Iter.distinct(iter));
+ }
+
+ @Override
+ public ExtendedIterator<Triple> getTripleIterator(Column column, Node value) {
+
+ // use POS index directly (fast)
+
+ if (column == null || column.getColumnKey() == null)
+ throw new NullPointerException("column is null");
+
+ if (value == null)
+ throw new NullPointerException("value is null");
+
+
+ Node p = column.getColumnKey();
+ final SetMultimap<Node, Node> valueToSubjectMap = valueReverseIndex
+ .get(p);
+ final Set<Node> subjects = valueToSubjectMap.get(value);
+ ArrayList<Triple> triples = new ArrayList<Triple>();
+ for (Node subject : subjects) {
+ triples.add(Triple.create(subject, p, value));
+ }
+ return WrappedIterator.create(triples.iterator());
+ }
+
+
+ @Override
+ public ExtendedIterator<Triple> getTripleIterator(Row row) {
+ // use PSO index ( O(n), n= column count )
+
+ if (row == null || row.getRowKey() == null)
+ throw new NullPointerException("row is null");
+
+ ArrayList<Triple> triples = new ArrayList<Triple>();
+ for (Column column : getColumns()) {
+ Node value = row.getValue(column);
+ triples.add(Triple.create(row.getRowKey(), column.getColumnKey(), value));
+ }
+ return WrappedIterator.create(triples.iterator());
+ }
+
+ @Override
+ public Collection<Column> getColumns() {
+ return columnList;
+ }
+
+ @Override
+ public Column getColumn(Node p) {
+ if (p == null)
+ throw new NullPointerException("column node is null");
+ return columnIndex.get(p);
+ }
+
+ @Override
+ public Column createColumn(Node p) {
+ if (p == null)
+ throw new NullPointerException("column node is null");
+
+ if (columnIndex.containsKey(p))
+ throw new IllegalArgumentException("column already exists: '"
+ + p.toString());
+
+ columnIndex.put(p, new ColumnImpl(this, p));
+ columnList.add(columnIndex.get(p));
+ valueIndex.put(p, new HashMap<Node, Node>());
+ valueReverseIndex.put(p, HashMultimap.<Node, Node> create());
+ return getColumn(p);
+ }
+
+ @Override
+ public Row getRow(final Node s) {
+ if (s == null)
+ throw new NullPointerException("subject node is null");
+ Row row = rowIndex.get(s);
+ return row;
+
+ }
+
+ @Override
+ public Row createRow(final Node s){
+ Row row = this.getRow(s);
+ if (row != null)
+ return row;
+
+ row = new InternalRow(s);
+ rowIndex.put(s, row);
+ rowList.add(row);
+
+ return row;
+ }
+
+ @Override
+ public List<Row> getAllRows() {
+ return rowList;
+ }
+
+
+
+ @Override
+ public List<Node> getColumnValues(Column column) {
+ if (column == null || column.getColumnKey() == null)
+ throw new NullPointerException("column is null");
+
+ Map<Node, Node> values = valueIndex.get(column.getColumnKey());
+
+ List<Node> list = new ArrayList<Node>(values.size());
+ list.addAll(values.values());
+ return list;
+ }
+
+ @Override
+ public Collection<Row> getMatchingRows(Column column, Node value) {
+ if (column == null || column.getColumnKey() == null)
+ throw new NullPointerException("column is null");
+
+ if (value == null)
+ throw new NullPointerException("value is null");
+
+
+ Node p = column.getColumnKey();
+ final SetMultimap<Node, Node> valueToSubjectMap = valueReverseIndex
+ .get(p);
+ final Set<Node> subjects = valueToSubjectMap.get(value);
+
+ final ArrayList<Row> matchingRows = new ArrayList<Row>();
+ for (Node subject : subjects) {
+ matchingRows.add(this.getRow(subject));
+ }
+ return matchingRows;
+ }
+
+ private final void setX(final Node s, final Node p, final Node value) {
+ if (p == null)
+ throw new NullPointerException("column Node must not be null.");
+ if (value == null)
+ throw new NullPointerException("value must not be null.");
+
+ Map<Node, Node> subjectToValueMap = valueIndex.get(p);
+ if (!columnIndex.containsKey(p) || subjectToValueMap == null)
+ throw new IllegalArgumentException("column: '" + p
+ + "' does not yet exist.");
+
+ Node oldValue = subjectToValueMap.get(s);
+ subjectToValueMap.put(s, value);
+ addToReverseMap(p, s, oldValue, value);
+ }
+
+ private void addToReverseMap(final Node p, final Node s,
+ final Node oldValue, final Node value) {
+
+ final SetMultimap<Node, Node> valueToSubjectMap = valueReverseIndex
+ .get(p);
+ valueToSubjectMap.remove(oldValue, s);
+ valueToSubjectMap.put(value, s);
+ }
+
+ private void unSetX(final Node s, final Node p) {
+
+ final Map<Node, Node> subjectToValueMap = valueIndex.get(p);
+ if (!columnIndex.containsKey(p) || subjectToValueMap == null)
+ throw new IllegalArgumentException("column: '" + p
+ + "' does not yet exist.");
+
+ final Node value = subjectToValueMap.get(s);
+ if (value == null)
+ return;
+
+ subjectToValueMap.remove(s);
+ removeFromReverseMap(p, s, value);
+ }
+
+ private void removeFromReverseMap(final Node p, final Node s,
+ final Node value) {
+ final SetMultimap<Node, Node> valueTokeysMap = valueReverseIndex.get(p);
+ valueTokeysMap.remove(s, value);
+ }
+
+ private Node getX(final Node s, final Node p) {
+ final Map<Node, Node> subjectToValueMap = valueIndex.get(p);
+ if (!columnIndex.containsKey(p) || subjectToValueMap == null)
+ throw new IllegalArgumentException("column: '" + p
+ + "' does not yet exist.");
+ return subjectToValueMap.get(s);
+ }
+
+ private final class InternalRow implements Row {
+ private final Node key;
+
+ InternalRow(final Node key) {
+ this.key = key;
+ }
+
+ @Override
+ public void setValue(Column column, Node value) {
+ if (value == null)
+ unSetX(key, column.getColumnKey());
+ else
+ setX(key, column.getColumnKey(), value);
+ }
+
+ @Override
+ public Node getValue(Column column) {
+ return getX(key, column.getColumnKey());
+ }
+
+ @Override
+ public Node getValue(Node columnKey) {
+ return getX(key, columnKey);
+ }
+
+ @Override
+ public PropertyTable getTable() {
+ return PropertyTableHashMapImpl.this;
+ }
+
+ @Override
+ public Node getRowKey() {
+ return key;
+ }
+
+ @Override
+ public Collection<Column> getColumns() {
+ // TODO Auto-generated method stub
+ return PropertyTableHashMapImpl.this.getColumns();
+ }
+
+ @Override
+ public ExtendedIterator<Triple> getTripleIterator() {
+ ArrayList<Triple> triples = new ArrayList<Triple>();
+ for (Column column : getColumns()) {
+ Node value = this.getValue(column);
+ triples.add(Triple.create(key, column.getColumnKey(), value));
+ }
+ return WrappedIterator.create(triples.iterator());
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/e7ac8b4d/jena-csv/src/main/java/org/apache/jena/propertytable/lang/LangCSV.java
----------------------------------------------------------------------
diff --git a/jena-csv/src/main/java/org/apache/jena/propertytable/lang/LangCSV.java b/jena-csv/src/main/java/org/apache/jena/propertytable/lang/LangCSV.java
new file mode 100644
index 0000000..ccda47e
--- /dev/null
+++ b/jena-csv/src/main/java/org/apache/jena/propertytable/lang/LangCSV.java
@@ -0,0 +1,229 @@
+/**
+ * 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;
+
+/**
+ * The LangRIOT implementation for CSV
+ *
+ */
+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/e7ac8b4d/jena-csv/src/main/java/org/apache/jena/propertytable/util/IRILib.java
----------------------------------------------------------------------
diff --git a/jena-csv/src/main/java/org/apache/jena/propertytable/util/IRILib.java b/jena-csv/src/main/java/org/apache/jena/propertytable/util/IRILib.java
new file mode 100644
index 0000000..b535c88
--- /dev/null
+++ b/jena-csv/src/main/java/org/apache/jena/propertytable/util/IRILib.java
@@ -0,0 +1,264 @@
+/*
+ * 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 support for '£', based on {@link org.apache.jena.riot.system.IRILib}
+ *
+ * This class should be merged into riot IRILib in future.
+ */
+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/e7ac8b4d/jena-csv/src/main/java/riotcmd/LocatorOupputFile.java
----------------------------------------------------------------------
diff --git a/jena-csv/src/main/java/riotcmd/LocatorOupputFile.java b/jena-csv/src/main/java/riotcmd/LocatorOupputFile.java
new file mode 100644
index 0000000..14caeeb
--- /dev/null
+++ b/jena-csv/src/main/java/riotcmd/LocatorOupputFile.java
@@ -0,0 +1,148 @@
+/*
+ * 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 riotcmd;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.security.AccessControlException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.hp.hpl.jena.util.FileManager;
+import com.hp.hpl.jena.util.FileUtils;
+import com.hp.hpl.jena.util.LocatorFile;
+
+class LocatorOupputFile {
+ static Logger log = LoggerFactory.getLogger(LocatorOupputFile.class) ;
+ private String thisDir = null ;
+ private String thisDirLogStr = "" ;
+
+ public LocatorOupputFile(String dir)
+ {
+ if ( dir != null )
+ {
+ if ( dir.endsWith("/") || dir.endsWith(java.io.File.separator) )
+ dir = dir.substring(0,dir.length()-1) ;
+ thisDirLogStr = " ["+dir+"]" ;
+ }
+ thisDir = dir ;
+ }
+
+ LocatorOupputFile()
+ {
+ this(null) ;
+ }
+
+ @Override
+ public boolean equals( Object other )
+ {
+ return
+ other instanceof LocatorFile
+ && equals( thisDir, ((LocatorOupputFile) other).thisDir );
+ }
+
+ private boolean equals( String a, String b )
+ {
+ return a == null ? b == null : a.equals( b );
+ }
+
+ @Override
+ public int hashCode()
+ {
+ if ( thisDir == null )
+ return 157 ;
+ return thisDir.hashCode();
+ }
+
+ private File toFile(String filenameOrURI)
+ {
+ String fn = FileUtils.toFilename(filenameOrURI) ;
+ if ( fn == null )
+ return null ;
+
+ if ( thisDir != null && ! fn.startsWith("/") && ! fn.startsWith(FileManager.filePathSeparator) )
+ fn = thisDir+java.io.File.separator+fn ;
+
+ return new File(fn) ;
+ }
+
+
+ public boolean exists(String filenameOrURI)
+ {
+ File f = toFile(filenameOrURI) ;
+
+ if ( f == null )
+ return false ;
+
+ return f.exists() ;
+ }
+
+
+ public OutputStream open(String filenameOrURI)
+ {
+ // Worry about %20.
+ // toFile calls FileUtils.toFilename(filenameOrURI) ;
+ File f = toFile(filenameOrURI) ;
+
+ try {
+ if ( f == null )
+ {
+ if ( log.isTraceEnabled())
+ log.trace("Not found: "+filenameOrURI+thisDirLogStr) ;
+ return null ;
+ }
+ } catch (AccessControlException e) {
+ log.warn("Security problem testing for file", e);
+ return null;
+ }
+
+ try {
+ OutputStream out = new FileOutputStream(f) ;
+
+ if ( log.isTraceEnabled() )
+ log.trace("Found: "+filenameOrURI+thisDirLogStr) ;
+
+
+ // Create base -- Java 1.4-isms
+ //base = f.toURI().toURL().toExternalForm() ;
+ //base = base.replaceFirst("^file:/([^/])", "file:///$1") ;
+ return out ;
+ } catch (IOException ioEx)
+ {
+ // Includes FileNotFoundException
+ // We already tested whether the file exists or not.
+ // log.warn("File unreadable (but exists): "+f.getPath()+" Exception: "+ioEx.getMessage()) ;
+ return null ;
+ }
+ }
+
+ public String getDir() { return thisDir ; }
+
+
+ public String getName()
+ {
+ String tmp = "LocatorFile" ;
+ if ( thisDir != null )
+ tmp = tmp+"("+thisDir+")" ;
+ return tmp ;
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/e7ac8b4d/jena-csv/src/main/java/riotcmd/ModDest.java
----------------------------------------------------------------------
diff --git a/jena-csv/src/main/java/riotcmd/ModDest.java b/jena-csv/src/main/java/riotcmd/ModDest.java
new file mode 100644
index 0000000..e5560f0
--- /dev/null
+++ b/jena-csv/src/main/java/riotcmd/ModDest.java
@@ -0,0 +1,51 @@
+/*
+ * 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 riotcmd;
+
+import arq.cmd.CmdException;
+import arq.cmdline.ArgDecl;
+import arq.cmdline.ArgModuleGeneral;
+import arq.cmdline.CmdArgModule;
+import arq.cmdline.CmdGeneral;
+
+class ModDest implements ArgModuleGeneral{
+
+ private ArgDecl argDest = new ArgDecl(ArgDecl.HasValue, "dest") ;
+ private String dest = null ;
+
+ @Override
+ public void processArgs(CmdArgModule cmdLine) {
+ if ( cmdLine.contains(argDest) ) {
+ dest = cmdLine.getValue(argDest) ;
+ } else {
+ throw new CmdException("No destination output file! Please add '--dest=file' in the program arguements") ;
+ }
+ }
+
+ @Override
+ public void registerWith(CmdGeneral cmdLine) {
+ cmdLine.getUsage().startCategory("Destination Output") ;
+ cmdLine.add(argDest, "--dest=file", "The destination output file") ;
+ }
+
+ public String getDest() {
+ return dest ;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/e7ac8b4d/jena-csv/src/main/java/riotcmd/csv2rdf.java
----------------------------------------------------------------------
diff --git a/jena-csv/src/main/java/riotcmd/csv2rdf.java b/jena-csv/src/main/java/riotcmd/csv2rdf.java
new file mode 100644
index 0000000..882a29a
--- /dev/null
+++ b/jena-csv/src/main/java/riotcmd/csv2rdf.java
@@ -0,0 +1,205 @@
+/*
+ * 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 riotcmd;
+
+import java.io.OutputStream;
+
+import org.apache.jena.atlas.io.IO;
+import org.apache.jena.atlas.web.ContentType;
+import org.apache.jena.atlas.web.TypedInputStream;
+import org.apache.jena.riot.Lang;
+import org.apache.jena.riot.RDFDataMgr;
+import org.apache.jena.riot.RDFLanguages;
+import org.apache.jena.riot.ReaderRIOT;
+import org.apache.jena.riot.RiotException;
+import org.apache.jena.riot.SysRIOT;
+import org.apache.jena.riot.lang.LabelToNode;
+import org.apache.jena.riot.lang.StreamRDFCounting;
+import org.apache.jena.riot.out.NodeToLabel;
+import org.apache.jena.riot.process.inf.InfFactory;
+import org.apache.jena.riot.system.ErrorHandler;
+import org.apache.jena.riot.system.ErrorHandlerFactory;
+import org.apache.jena.riot.system.RiotLib;
+import org.apache.jena.riot.system.StreamRDF;
+import org.apache.jena.riot.system.StreamRDF2;
+import org.apache.jena.riot.system.StreamRDFLib;
+import org.apache.jena.riot.system.SyntaxLabels;
+
+import arq.cmd.CmdException;
+
+import com.hp.hpl.jena.sparql.util.Utils;
+
+/**
+ * It's a command line tool for direct and scalable transforming from CSV to the formatted RDF syntax (i.e. N-Triples),
+ * with no intermediary Graph or PropertyTable.
+ *
+ * It reuses the parsing functions from CmdLangParse and sinks the triples into the destination output file.
+ *
+ */
+public class csv2rdf extends CmdLangParse{
+
+ protected ModDest modDest = new ModDest() ;
+ protected OutputStream destOut;
+
+ public static void main(String... argv)
+ {
+ new csv2rdf(argv).mainRun() ;
+ }
+
+ protected csv2rdf(String[] argv)
+ {
+ super(argv) ;
+ super.addModule(modDest) ;
+
+ }
+
+ @Override
+ protected Lang selectLang(String filename, ContentType contentType,
+ Lang dftLang) {
+ return RDFLanguages.CSV;
+ }
+
+ @Override
+ protected String getCommandName() {
+ return Utils.classShortName(csv2rdf.class) ;
+ }
+
+ @Override
+ protected String getSummary()
+ {
+ return getCommandName()+" --dest=outputFile inputFile ..." ;
+ }
+
+ // override the original CmdLangParse.parseRIOT()
+ protected void parseRIOT(String baseURI, String filename, TypedInputStream in)
+ {
+
+ String dest = modDest.getDest();
+ LocatorOupputFile l = new LocatorOupputFile();
+ destOut = l.open(dest);
+
+ if (destOut == null){
+ System.err.println("Can't write to destination output file: '"+dest+"' ") ;
+ return ;
+ }
+
+ // I ti s shame we effectively duplicate deciding thelnaguage but we want to control the
+ // pasrer at a deep level (in validation, we want line numbers get into error message)
+ // This code predates RDFDataMgr.
+
+ ContentType ct = in.getMediaType() ;
+
+ baseURI = SysRIOT.chooseBaseIRI(baseURI, filename) ;
+
+ boolean checking = true ;
+ if ( modLangParse.explicitChecking() ) checking = true ;
+ if ( modLangParse.explicitNoChecking() ) checking = false ;
+
+ ErrorHandler errHandler = null ;
+ if ( checking )
+ {
+ if ( modLangParse.stopOnBadTerm() )
+ errHandler = ErrorHandlerFactory.errorHandlerStd ;
+ else
+ // Try to go on if possible. This is the default behaviour.
+ errHandler = ErrorHandlerFactory.errorHandlerWarn ;
+ }
+
+ if ( modLangParse.skipOnBadTerm() )
+ {
+ // TODO skipOnBadterm
+ }
+
+ Lang lang = selectLang(filename, ct, RDFLanguages.NQUADS) ;
+ LangHandler handler = dispatch.get(lang) ;
+ if ( handler == null )
+ throw new CmdException("Undefined language: "+lang) ;
+
+ // If multiple files, choose the overall labels.
+ if ( langHandlerOverall == null )
+ langHandlerOverall = handler ;
+ else
+ {
+ if ( langHandlerOverall != langHandlerAny )
+ {
+ if ( langHandlerOverall != handler )
+ langHandlerOverall = langHandlerAny ;
+ }
+ }
+
+ // Make a flag.
+ // Input and output subflags.
+ // If input is "label, then output using NodeToLabel.createBNodeByLabelRaw() ;
+ // else use NodeToLabel.createBNodeByLabel() ;
+ // Also, as URI.
+ final boolean labelsAsGiven = false ;
+
+ NodeToLabel labels = SyntaxLabels.createNodeToLabel() ;
+ if ( labelsAsGiven )
+ labels = NodeToLabel.createBNodeByLabelEncoded() ;
+
+ StreamRDF s = StreamRDFLib.sinkNull() ;
+ if ( ! modLangParse.toBitBucket() )
+ s = StreamRDFLib.writer(output) ;
+
+ // add dest output
+ if ( destOut != null)
+ s = new StreamRDF2(s, StreamRDFLib.writer(destOut));
+
+ if ( setup != null )
+ s = InfFactory.inf(s, setup) ;
+
+ StreamRDFCounting sink = StreamRDFLib.count(s) ;
+ s = null ;
+
+ ReaderRIOT reader = RDFDataMgr.createReader(lang) ;
+ try {
+ if ( checking ) {
+ if ( lang == RDFLanguages.NTRIPLES || lang == RDFLanguages.NQUADS )
+ reader.setParserProfile(RiotLib.profile(baseURI, false, true, errHandler)) ;
+ else
+ reader.setParserProfile(RiotLib.profile(baseURI, true, true, errHandler)) ;
+ } else
+ reader.setParserProfile(RiotLib.profile(baseURI, false, false, errHandler)) ;
+
+ if ( labelsAsGiven )
+ reader.getParserProfile().setLabelToNode(LabelToNode.createUseLabelAsGiven()) ;
+ modTime.startTimer() ;
+ reader.read(in, baseURI, ct, sink, null) ;
+ } catch (RiotException ex) {
+ // Should have handled the exception and logged a message by now.
+ // System.err.println("++++"+ex.getMessage());
+
+ if ( modLangParse.stopOnBadTerm() )
+ return ;
+ } finally {
+ // Not close - we may write again to the underlying output stream in another call to parse a file.
+ sink.finish() ;
+ IO.close(in) ;
+ }
+ long x = modTime.endTimer() ;
+ long n = sink.countTriples()+sink.countQuads() ;
+
+ if ( modTime.timingEnabled() )
+ output(filename, n, x, handler) ;
+
+ totalMillis += x ;
+ totalTuples += n ;
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/e7ac8b4d/jena-csv/src/test/java/org/apache/jena/propertytable/AbstractColumnTest.java
----------------------------------------------------------------------
diff --git a/jena-csv/src/test/java/org/apache/jena/propertytable/AbstractColumnTest.java b/jena-csv/src/test/java/org/apache/jena/propertytable/AbstractColumnTest.java
new file mode 100644
index 0000000..90ff0af
--- /dev/null
+++ b/jena-csv/src/test/java/org/apache/jena/propertytable/AbstractColumnTest.java
@@ -0,0 +1,80 @@
+/*
+ * 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;
+
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.hp.hpl.jena.graph.Node;
+import com.hp.hpl.jena.graph.NodeFactory;
+
+/**
+ * Tests related to Column.
+ *
+ */
+public abstract class AbstractColumnTest extends BaseTest{
+
+
+ @Test(expected = NullPointerException.class)
+ public void testCreateColumnWithArgNull() {
+ table.createColumn(null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testCreateListColumnWithAlreadyExistingCoulmnName() {
+ table.createColumn(URI("something"));
+ table.createColumn(URI("something"));
+ }
+
+ @Test
+ public void testColumnCreate() {
+ table.createColumn(URI("something"));
+ Assert.assertEquals(1, table.getColumns().size());
+ Assert.assertTrue(collectionContains(table.getColumns(), URI("something")));
+ }
+
+ @Test
+ public void testGetColumnValues() {
+ Column something = table.createColumn(URI("something"));
+ final Row row1 = table.createRow(NodeFactory.createAnon());
+ row1.setValue(something, URI("apple"));
+ final Row row2 = table.createRow(NodeFactory.createAnon());
+ row2.setValue(something, URI("orange"));
+ final List<Node> values = something.getValues();
+ Assert.assertTrue(values.size() == 2);
+ Assert.assertTrue(values.contains( URI("apple")));
+ Assert.assertTrue(values.contains( URI("orange")));
+ }
+
+ @Test
+ public void testGetColumn() {
+ table.createColumn(URI("something"));
+ Assert.assertNotNull(table.getColumn(URI("something")));
+ Assert.assertNull(table.getColumn( URI("nonExistentColumnName")));
+ }
+
+ @Test
+ public void testGetTable() {
+ Column something = table.createColumn(URI("something"));
+ Assert.assertEquals(table, something.getTable());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/e7ac8b4d/jena-csv/src/test/java/org/apache/jena/propertytable/AbstractPropertyTableTest.java
----------------------------------------------------------------------
diff --git a/jena-csv/src/test/java/org/apache/jena/propertytable/AbstractPropertyTableTest.java b/jena-csv/src/test/java/org/apache/jena/propertytable/AbstractPropertyTableTest.java
new file mode 100644
index 0000000..3738d4e
--- /dev/null
+++ b/jena-csv/src/test/java/org/apache/jena/propertytable/AbstractPropertyTableTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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;
+
+import java.util.Collection;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.hp.hpl.jena.graph.NodeFactory;
+
+/**
+ * Tests related to PropertyTable.
+ *
+ */
+public abstract class AbstractPropertyTableTest extends AbstractRowTest{
+
+ @Test
+ public void testGetMatchingColumns() {
+ Column something = table.createColumn(URI("something") );
+ final Row row1 = table.createRow(NodeFactory.createAnon());
+ row1.setValue(something, URI("apple"));
+ final Row row2 = table.createRow(NodeFactory.createAnon());
+ row2.setValue(something, URI("orange"));
+ Collection<Row> matchingRows = table.getMatchingRows(something, URI("apple"));
+ Assert.assertTrue(matchingRows.size() == 1);
+ matchingRows = table.getMatchingRows(something, URI("banana"));
+ Assert.assertTrue(matchingRows.isEmpty());
+ }
+
+ @Test
+ public void testGetAllRows() {
+ Assert.assertTrue(table.getAllRows().size() == 1);
+ table.createRow(NodeFactory.createAnon());
+ Assert.assertTrue(table.getAllRows().size() == 2);
+ table.createRow(NodeFactory.createAnon());
+ Assert.assertTrue(table.getAllRows().size() == 3);
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/e7ac8b4d/jena-csv/src/test/java/org/apache/jena/propertytable/AbstractRowTest.java
----------------------------------------------------------------------
diff --git a/jena-csv/src/test/java/org/apache/jena/propertytable/AbstractRowTest.java b/jena-csv/src/test/java/org/apache/jena/propertytable/AbstractRowTest.java
new file mode 100644
index 0000000..9457375
--- /dev/null
+++ b/jena-csv/src/test/java/org/apache/jena/propertytable/AbstractRowTest.java
@@ -0,0 +1,106 @@
+/*
+ * 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;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.hp.hpl.jena.graph.Node;
+import com.hp.hpl.jena.graph.NodeFactory;
+
+/**
+ * Tests related to Row.
+ *
+ */
+public abstract class AbstractRowTest extends AbstractColumnTest{
+
+ @Test
+ public void testAddRowValue() {
+
+ Column something = table.createColumn(URI("something"));
+ Column somethingElse = table.createColumn(URI("somethingElse"));
+
+ row.setValue(something, URI("apple"));
+ row.setValue(somethingElse, URI("orange"));
+
+ Assert.assertEquals(URI("apple"), row.getValue(something));
+ Assert.assertEquals(URI("orange"), row.getValue(somethingElse));
+ }
+
+ @Test
+ public void testUnsetRowValue() {
+ Column something = table.createColumn(URI("something"));
+ row.setValue( something , URI("apple"));
+ Assert.assertEquals(URI("apple"), row.getValue(something));
+ row.setValue( something , null);
+ Assert.assertEquals(null, row.getValue(something));
+ }
+
+ @Test(expected=NullPointerException.class)
+ public void testGetRowWithNullKey() {
+ table.getRow(null);
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void testAddValueToNotExistingColumn() {
+ row.setValue(table.getColumn(URI("something")), URI("apple"));
+ }
+
+
+
+ @Test(expected=IllegalArgumentException.class)
+ public void testGetListWithANonExistantColumn() {
+ Assert.assertNull(row.getValue( NodeFactory.createAnon() ));
+ }
+
+ @Test
+ public void testGetListWithAnMissingRowValue() {
+ Column something = table.createColumn(URI("something"));
+ Assert.assertNull(row.getValue(something));
+ }
+
+ @Test
+ public void testGetValue() {
+ Column something = table.createColumn(URI("something"));
+ row.setValue(something, URI("apple"));
+ Node value = row.getValue(something);
+ Assert.assertEquals(URI("apple"), value);
+ }
+
+ @Test
+ public void testRowExistsFalse(){
+ Assert.assertNull(table.getRow(NodeFactory.createAnon()));
+ }
+
+ @Test
+ public void testRowExistsTrue() {
+ Assert.assertNotNull(table.getRow(rowSubject));
+ }
+
+ @Test
+ public void testGetRowFalseAndDoesntCreateRow() {
+ Assert.assertNull(table.getRow(NodeFactory.createAnon()));
+ Assert.assertNull(table.getRow(NodeFactory.createAnon()));
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void testGetValueBeforeColumnExists() {
+ row.getValue(URI("nonexistentColumnX"));
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/e7ac8b4d/jena-csv/src/test/java/org/apache/jena/propertytable/BaseTest.java
----------------------------------------------------------------------
diff --git a/jena-csv/src/test/java/org/apache/jena/propertytable/BaseTest.java b/jena-csv/src/test/java/org/apache/jena/propertytable/BaseTest.java
new file mode 100644
index 0000000..282f649
--- /dev/null
+++ b/jena-csv/src/test/java/org/apache/jena/propertytable/BaseTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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;
+
+import java.util.Collection;
+
+import com.hp.hpl.jena.graph.Node;
+import com.hp.hpl.jena.graph.NodeFactory;
+
+public abstract class BaseTest {
+ protected PropertyTable table;
+ protected PropertyTable table2;
+ protected Row row;
+ private static final String ns = "eh:foo/bar#";
+ protected static final Node rowSubject = URI("rowSubject");
+ protected static final String csvFilePath = "src/test/resources/test.csv";
+
+
+ protected static Node URI(String localName) {
+ return NodeFactory.createURI(ns + localName);
+ }
+
+ protected static boolean collectionContains(
+ final Collection<Column> columns, final Node columnkey) {
+ for (final Column column : columns) {
+ if (column.getColumnKey().equals(columnkey))
+ return true;
+ }
+ return false;
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/e7ac8b4d/jena-csv/src/test/java/org/apache/jena/propertytable/TS_PropertyTable.java
----------------------------------------------------------------------
diff --git a/jena-csv/src/test/java/org/apache/jena/propertytable/TS_PropertyTable.java b/jena-csv/src/test/java/org/apache/jena/propertytable/TS_PropertyTable.java
new file mode 100644
index 0000000..084365d
--- /dev/null
+++ b/jena-csv/src/test/java/org/apache/jena/propertytable/TS_PropertyTable.java
@@ -0,0 +1,42 @@
+/*
+ * 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;
+
+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;
+
+
+@RunWith(Suite.class)
+@Suite.SuiteClasses( {
+ PropertyTableArrayImplTest.class,
+ PropertyTableHashMapImplTest.class,
+ GraphCSVTest.class,
+ PropertyTableBuilderForArrayImplTest.class,
+ PropertyTableBuilderForHashMapImplTest.class,
+ TestLangCSV.class
+})
+public class TS_PropertyTable {
+
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/e7ac8b4d/jena-csv/src/test/java/org/apache/jena/propertytable/graph/GraphCSVTest.java
----------------------------------------------------------------------
diff --git a/jena-csv/src/test/java/org/apache/jena/propertytable/graph/GraphCSVTest.java b/jena-csv/src/test/java/org/apache/jena/propertytable/graph/GraphCSVTest.java
new file mode 100644
index 0000000..3d23f86
--- /dev/null
+++ b/jena-csv/src/test/java/org/apache/jena/propertytable/graph/GraphCSVTest.java
@@ -0,0 +1,153 @@
+/*
+ * 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;
+
+/**
+ * Tests related to GraphCSV with some real world data.
+ *
+ */
+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());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/e7ac8b4d/jena-csv/src/test/java/org/apache/jena/propertytable/impl/AbstractPropertyTableBuilderTest.java
----------------------------------------------------------------------
diff --git a/jena-csv/src/test/java/org/apache/jena/propertytable/impl/AbstractPropertyTableBuilderTest.java b/jena-csv/src/test/java/org/apache/jena/propertytable/impl/AbstractPropertyTableBuilderTest.java
new file mode 100644
index 0000000..f7a1e02
--- /dev/null
+++ b/jena-csv/src/test/java/org/apache/jena/propertytable/impl/AbstractPropertyTableBuilderTest.java
@@ -0,0 +1,147 @@
+/*
+ * 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.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+
+import org.apache.jena.atlas.csv.CSVTokenIterator;
+import org.apache.jena.propertytable.BaseTest;
+import org.apache.jena.propertytable.Row;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.hp.hpl.jena.graph.Node;
+import com.hp.hpl.jena.graph.NodeFactory;
+
+
+/**
+ * Tests related to PropertyTableBuilder, or more explicitly for the CSV parser in the current release.
+ *
+ */
+public abstract class AbstractPropertyTableBuilderTest extends BaseTest {
+
+ @Test
+ public void testFillPropertyTable() {
+ CSVTokenIterator iterator = csv("a,b\nc,d\ne,f");
+ PropertyTableBuilder.fillPropertyTable(table, iterator, csvFilePath);
+
+ Assert.assertEquals(3, table.getColumns().size());
+ containsColumn(PropertyTableBuilder.CSV_ROW_NODE);
+ containsColumn("a");
+ containsColumn("b");
+
+ Assert.assertEquals(2, table.getAllRows().size());
+ containsValue(0, "a", "c");
+ containsValue(0, "b", "d");
+
+ containsValue(1, "a", "e");
+ containsValue(1, "b", "f");
+
+ }
+
+ @Test
+ public void testIrregularTable1() {
+ CSVTokenIterator iterator = csv("a,b\nc\ne,f");
+ PropertyTableBuilder.fillPropertyTable(table, iterator, csvFilePath);
+
+ Assert.assertEquals(3, table.getColumns().size());
+ containsColumn(PropertyTableBuilder.CSV_ROW_NODE);
+ containsColumn("a");
+ containsColumn("b");
+
+ Assert.assertEquals(2, table.getAllRows().size());
+ containsValue(0, "a", "c");
+ nullValue(0, "b");
+
+ containsValue(1, "a", "e");
+ containsValue(1, "b", "f");
+ }
+
+ @Test
+ public void testIrregularTable2() {
+ CSVTokenIterator iterator = csv("a,b\nc,d1,d2\ne,f");
+ PropertyTableBuilder.fillPropertyTable(table, iterator, csvFilePath);
+
+ Assert.assertEquals(3, table.getColumns().size());
+ containsColumn(PropertyTableBuilder.CSV_ROW_NODE);
+ containsColumn("a");
+ containsColumn("b");
+
+ Assert.assertEquals(2, table.getAllRows().size());
+ containsValue(0, "a", "c");
+ containsValue(0, "b", "d1");
+
+ containsValue(1, "a", "e");
+ containsValue(1, "b", "f");
+ }
+
+ @Test
+ public void testIrregularTable3() {
+ CSVTokenIterator iterator = csv("a,b\n,d\ne,f");
+ PropertyTableBuilder.fillPropertyTable(table, iterator, csvFilePath);
+
+ Assert.assertEquals(3, table.getColumns().size());
+ containsColumn(PropertyTableBuilder.CSV_ROW_NODE);
+ containsColumn("a");
+ containsColumn("b");
+
+ Assert.assertEquals(2, table.getAllRows().size());
+ nullValue(0, "a");
+ containsValue(0, "b", "d");
+
+ containsValue(1, "a", "e");
+ containsValue(1, "b", "f");
+ }
+
+ private void nullValue(int rowIndex, String column) {
+ Row row = table.getAllRows().get(rowIndex);
+ Node v = row.getValue(NodeFactory.createURI(getColumnKey(column)));
+ Assert.assertEquals(null, v);
+ }
+
+ private void containsValue(int rowIndex, String column, String value) {
+ Row row = table.getAllRows().get(rowIndex);
+ Node v = row.getValue(NodeFactory.createURI(getColumnKey(column)));
+ Assert.assertEquals(value, v.getLiteralValue());
+ }
+
+ private String getColumnKey(String column) {
+ return PropertyTableBuilder.createColumnKeyURI(csvFilePath, column);
+ }
+
+ private void containsColumn(String column) {
+ containsColumn(NodeFactory.createURI(getColumnKey(column)));
+ }
+
+ private void containsColumn(Node columnKey) {
+ Assert.assertTrue(collectionContains(table.getColumns(), columnKey));
+ }
+
+ private CSVTokenIterator csv(String input) {
+ try {
+ InputStream in = new ByteArrayInputStream(input.getBytes("UTF-8"));
+ CSVTokenIterator iterator = new CSVTokenIterator(in);
+ return iterator;
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/e7ac8b4d/jena-csv/src/test/java/org/apache/jena/propertytable/impl/PropertyTableArrayImplTest.java
----------------------------------------------------------------------
diff --git a/jena-csv/src/test/java/org/apache/jena/propertytable/impl/PropertyTableArrayImplTest.java b/jena-csv/src/test/java/org/apache/jena/propertytable/impl/PropertyTableArrayImplTest.java
new file mode 100644
index 0000000..ba1ca2d
--- /dev/null
+++ b/jena-csv/src/test/java/org/apache/jena/propertytable/impl/PropertyTableArrayImplTest.java
@@ -0,0 +1,84 @@
+/*
+ * 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.AbstractPropertyTableTest;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests for PropertyTableArrayImpl
+ *
+ */
+public class PropertyTableArrayImplTest extends AbstractPropertyTableTest{
+
+ private static int rowNum = 10;
+ private static int columnNum = 10 ;
+
+ @Before
+ public void setUp() {
+ table = new PropertyTableArrayImpl(rowNum, columnNum);
+ table2 = new PropertyTableArrayImpl(rowNum, columnNum);
+ row = table.createRow(rowSubject);
+
+ }
+
+ @After
+ public void tearDown() {
+ table = null;
+ table2 = null;
+ row = null;
+ }
+
+ @Test
+ public void testColumnOutofBounds1() {
+ for (int i=0;i<columnNum;i++){
+ table.createColumn(URI("something_"+i));
+ }
+ Assert.assertEquals(columnNum, table.getColumns().size());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testColumnOutofBounds2() {
+ for (int i=0;i<columnNum+1;i++){
+ table.createColumn(URI("something_"+i));
+ }
+ }
+
+ @Test
+ public void testRowOutofBounds1() {
+
+ // we've already created a new Row in @Before
+ for (int i=0;i<rowNum-1;i++){
+ table.createRow(URI("something_"+i));
+ }
+ Assert.assertEquals(rowNum, table.getAllRows().size());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testRowOutofBounds2() {
+
+ // we've already created a new Row in @Before
+ for (int i=0;i<rowNum;i++){
+ table.createRow(URI("something_"+i));
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/e7ac8b4d/jena-csv/src/test/java/org/apache/jena/propertytable/impl/PropertyTableBuilderForArrayImplTest.java
----------------------------------------------------------------------
diff --git a/jena-csv/src/test/java/org/apache/jena/propertytable/impl/PropertyTableBuilderForArrayImplTest.java b/jena-csv/src/test/java/org/apache/jena/propertytable/impl/PropertyTableBuilderForArrayImplTest.java
new file mode 100644
index 0000000..7b7e0c8
--- /dev/null
+++ b/jena-csv/src/test/java/org/apache/jena/propertytable/impl/PropertyTableBuilderForArrayImplTest.java
@@ -0,0 +1,39 @@
+/*
+ * 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.junit.After;
+import org.junit.Before;
+
+public class PropertyTableBuilderForArrayImplTest extends AbstractPropertyTableBuilderTest{
+
+ private static int rowNum = 10;
+ private static int columnNum = 10 ;
+
+ @Before
+ public void setUp() {
+ table = new PropertyTableArrayImpl(rowNum, columnNum);
+ }
+
+ @After
+ public void tearDown() {
+ table = null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/e7ac8b4d/jena-csv/src/test/java/org/apache/jena/propertytable/impl/PropertyTableBuilderForHashMapImplTest.java
----------------------------------------------------------------------
diff --git a/jena-csv/src/test/java/org/apache/jena/propertytable/impl/PropertyTableBuilderForHashMapImplTest.java b/jena-csv/src/test/java/org/apache/jena/propertytable/impl/PropertyTableBuilderForHashMapImplTest.java
new file mode 100644
index 0000000..f2768f5
--- /dev/null
+++ b/jena-csv/src/test/java/org/apache/jena/propertytable/impl/PropertyTableBuilderForHashMapImplTest.java
@@ -0,0 +1,34 @@
+/*
+ * 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.junit.After;
+import org.junit.Before;
+
+public class PropertyTableBuilderForHashMapImplTest extends AbstractPropertyTableBuilderTest{
+ @Before
+ public void setUp() {
+ table = new PropertyTableHashMapImpl();
+ }
+
+ @After
+ public void tearDown() {
+ table = null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/e7ac8b4d/jena-csv/src/test/java/org/apache/jena/propertytable/impl/PropertyTableHashMapImplTest.java
----------------------------------------------------------------------
diff --git a/jena-csv/src/test/java/org/apache/jena/propertytable/impl/PropertyTableHashMapImplTest.java b/jena-csv/src/test/java/org/apache/jena/propertytable/impl/PropertyTableHashMapImplTest.java
new file mode 100644
index 0000000..33d95ae
--- /dev/null
+++ b/jena-csv/src/test/java/org/apache/jena/propertytable/impl/PropertyTableHashMapImplTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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.AbstractPropertyTableTest;
+import org.junit.After;
+import org.junit.Before;
+
+/**
+ * Tests for PropertyTableHashMapImpl
+ *
+ */
+public class PropertyTableHashMapImplTest extends AbstractPropertyTableTest{
+
+ @Before
+ public void setUp() {
+ table = new PropertyTableHashMapImpl();
+ table2 = new PropertyTableHashMapImpl();
+ row = table.createRow(rowSubject);
+
+ }
+
+ @After
+ public void tearDown() {
+ table = null;
+ table2 = null;
+ row = null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/e7ac8b4d/jena-csv/src/test/java/org/apache/jena/propertytable/lang/TestLangCSV.java
----------------------------------------------------------------------
diff --git a/jena-csv/src/test/java/org/apache/jena/propertytable/lang/TestLangCSV.java b/jena-csv/src/test/java/org/apache/jena/propertytable/lang/TestLangCSV.java
new file mode 100644
index 0000000..697ba27
--- /dev/null
+++ b/jena-csv/src/test/java/org/apache/jena/propertytable/lang/TestLangCSV.java
@@ -0,0 +1,113 @@
+/*
+ * 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 java.io.StringReader;
+
+import org.apache.jena.atlas.junit.BaseTest;
+import org.apache.jena.atlas.lib.StrUtils;
+import org.apache.jena.riot.Lang;
+import org.apache.jena.riot.RDFDataMgr;
+import org.apache.jena.riot.RDFLanguages;
+import org.apache.jena.riot.system.IRIResolver;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.hp.hpl.jena.rdf.model.Model;
+import com.hp.hpl.jena.rdf.model.ModelFactory;
+
+
+/**
+ * Tests for the registered LangCSV in RIOT.
+ *
+ */
+public class TestLangCSV extends BaseTest {
+
+ private static final String FILE_NAME = "src/test/resources/test.csv";
+ private static final String FILE_URI = IRIResolver.resolveString(FILE_NAME);
+
+ @BeforeClass
+ public static void init(){
+ LangCSV.register();
+ }
+
+ @Test
+ public void testPredicateWithSpace() {
+ String[] s1 = { "Predicate With Space", "PredicateWithSpace" };
+ String[] s2 = {
+ //"<"+ LangCSV.caculateSubject(1, FILE_NAME) + "> <" + FILE_URI + "#Predicate+With+Space> 'PredicateWithSpace' ; ",
+ " [] <" + FILE_URI + "#Predicate%20With%20Space> 'PredicateWithSpace' ; ",
+ " <http://w3c/future-csv-vocab/row> 1 ." };
+ assertIsomorphicWith(s1, s2);
+ }
+
+ @Test
+ public void testNonURICharacters() {
+ String[] s1 = { "`~!@#$%^&*()-_=+[{]}|\\;:'\"<.>/?", "NonURICharacters" };
+ String[] s2 = {
+ //"<"+ LangCSV.caculateSubject(1, FILE_NAME) + "> <" + FILE_URI + "#%60%7E%21%40%23%24%25%5E%26*%28%29-_%3D%2B%5B%7B%5D%7D%7C%5C%3B%3A%27%22%3C.%3E%2F%3F> 'NonURICharacters' ; ",
+ " [] <" + FILE_URI + "#%60~%21%40%23%24%25%5E%26%2A%28%29-_%3D%2B%5B%7B%5D%7D%7C%5C%3B%3A%27%22%3C.%3E%2F%3F> 'NonURICharacters' ; ",
+ " <http://w3c/future-csv-vocab/row> 1 ." };
+ assertIsomorphicWith(s1, s2);
+ }
+
+ @Test
+ public void testDigitalLocalName() {
+ String[] s1 = { "1234", "DigitalLocalName" };
+ String[] s2 = {
+ //"<"+ LangCSV.caculateSubject(1, FILE_NAME) + "> <" + FILE_URI + "#1234> 'DigitalLocalName' ; ",
+ " [] <" + FILE_URI + "#1234> 'DigitalLocalName' ; ",
+ " <http://w3c/future-csv-vocab/row> 1 ." };
+ assertIsomorphicWith(s1, s2);
+ }
+
+ @Test
+ public void testMoney() {
+ String[] s1 = { "£", "£" };
+ String[] s2 = {
+ //"<"+ LangCSV.caculateSubject(1, FILE_NAME) + "> <" + FILE_URI + "#1234> 'DigitalLocalName' ; ",
+ " [] <" + FILE_URI + "#%A3> '£' ; ",
+ " <http://w3c/future-csv-vocab/row> 1 ." };
+ assertIsomorphicWith(s1, s2);
+ }
+
+ @Test
+ public void RDFDataMgrReadTest() {
+ Model m1 = RDFDataMgr.loadModel(FILE_NAME, RDFLanguages.CSV);
+ Model m2 = ModelFactory.createDefaultModel();
+ m2.read(FILE_NAME, "CSV");
+ assertEquals(12, m1.size());
+ assertTrue(m1.isIsomorphicWith(m2));
+ }
+
+ private Model parseToModel(String[] strings, Lang lang) {
+ String string = StrUtils.strjoin("\n", strings);
+ StringReader r = new StringReader(string);
+ Model model = ModelFactory.createDefaultModel();
+ RDFDataMgr.read(model, r, FILE_NAME, lang);
+ return model;
+ }
+
+ private void assertIsomorphicWith(String[] s1, String[] s2){
+ Model m1 = parseToModel(s1, RDFLanguages.CSV);
+ Model m2 = parseToModel(s2, RDFLanguages.TURTLE);
+ assertTrue(m1.isIsomorphicWith(m2));
+ }
+
+}