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) [email protected]( { + 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)); + } + +}
