./0000755000175000017500000000000011061274763011674 5ustar janpascaljanpascal./pom.xml0000644000175000017500000000572411061274763013221 0ustar janpascaljanpascal 4.0.0 org.apache.commons commons-sandbox-parent 7 commons-csv 1.0-SNAPSHOT Commons CSV (Sandbox) http://commons.apache.org/sandbox/csv/ junit junit 3.8.1 test bayard Henri Yandell bayard@apache.org Apache Martin van den Bemt mvdb mvdb@apache.org Apache Yonik Seeley yonik yonik@apache.org Apache scm:svn:http://svn.apache.org/repos/asf/commons/sandbox/csv/trunk scm:svn:https://svn.apache.org/repos/asf/commons/sandbox/csv/trunk http://svn.apache.org/repos/asf/commons/sandbox/csv/trunk apache.website Apache Website ${commons.deployment.protocol}://people.apache.org/www/commons.apache.org/sandbox/csv/ csv 12311182 src/java src/test org.apache.maven.plugins maven-changes-plugin 2.0 %URL%/%ISSUE% changes-report org.apache.maven.plugins maven-checkstyle-plugin 2.1 ${basedir}/checkstyle.xml false ./checkstyle.xml0000644000175000017500000000315111061274763014554 0ustar janpascaljanpascal ./LICENSE.txt0000644000175000017500000002613611061274763013527 0ustar janpascaljanpascal Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed 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. ./src/0000755000175000017500000000000011061274763012463 5ustar janpascaljanpascal./src/java/0000755000175000017500000000000011061274762013403 5ustar janpascaljanpascal./src/java/org/0000755000175000017500000000000011061274762014172 5ustar janpascaljanpascal./src/java/org/apache/0000755000175000017500000000000011061274762015413 5ustar janpascaljanpascal./src/java/org/apache/commons/0000755000175000017500000000000011061274762017066 5ustar janpascaljanpascal./src/java/org/apache/commons/csv/0000755000175000017500000000000011061274763017662 5ustar janpascaljanpascal./src/java/org/apache/commons/csv/writer/0000755000175000017500000000000011061274762021175 5ustar janpascaljanpascal./src/java/org/apache/commons/csv/writer/CSVConfigGuesser.java0000644000175000017500000001256511061274762025170 0ustar janpascaljanpascal/* * 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.commons.csv.writer; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; /** * Tries to guess a config based on an InputStream. * * @author Martin van den Bemt * @version $Id: $ */ public class CSVConfigGuesser { /** The stream to read */ private InputStream in; /** * if the file has a field header (need this info, to be able to guess better) * Defaults to false */ private boolean hasFieldHeader = false; /** The found config */ protected CSVConfig config; /** * */ public CSVConfigGuesser() { this.config = new CSVConfig(); } /** * @param in the inputstream to guess from */ public CSVConfigGuesser(InputStream in) { this(); setInputStream(in); } public void setInputStream(InputStream in) { this.in = in; } /** * Allow override. * @return the inputstream that was set. */ protected InputStream getInputStream() { return in; } /** * Guess the config based on the first 10 (or less when less available) * records of a CSV file. * * @return the guessed config. */ public CSVConfig guess() { try { // tralalal BufferedReader bIn = new BufferedReader(new InputStreamReader((getInputStream()))); String[] lines = new String[10]; String line = null; int counter = 0; while ( (line = bIn.readLine()) != null && counter <= 10) { lines[counter] = line; counter++; } if (counter < 10) { // remove nulls from the array, so we can skip the null checking. String[] newLines = new String[counter]; System.arraycopy(lines, 0, newLines, 0, counter); lines = newLines; } analyseLines(lines); } catch(Exception e) { e.printStackTrace(); } finally { if (in != null) { try { in.close(); } catch(Exception e) { // ignore exception. } } } CSVConfig conf = config; // cleanup the config. config = null; return conf; } protected void analyseLines(String[] lines) { guessFixedWidth(lines); guessFieldSeperator(lines); } /** * Guess if this file is fixedwidth. * Just basing the fact on all lines being of the same length * @param lines */ protected void guessFixedWidth(String[] lines) { int lastLength = 0; // assume fixedlength. config.setFixedWidth(true); for (int i = 0; i < lines.length; i++) { if (i == 0) { lastLength = lines[i].length(); } else { if (lastLength != lines[i].length()) { config.setFixedWidth(false); } } } } protected void guessFieldSeperator(String[] lines) { if (config.isFixedWidth()) { guessFixedWidthSeperator(lines); return; } for (int i = 0; i < lines.length; i++) { } } protected void guessFixedWidthSeperator(String[] lines) { // keep track of the fieldlength int previousMatch = -1; for (int i = 0; i < lines[0].length(); i++) { char last = ' '; boolean charMatches = true; for (int j = 0; j < lines.length; j++) { if (j == 0) { last = lines[j].charAt(i); } if (last != lines[j].charAt(i)) { charMatches = false; break; } } if (charMatches) { if (previousMatch == -1) { previousMatch = 0; } CSVField field = new CSVField(); field.setName("field"+config.getFields().length+1); field.setSize((i-previousMatch)); config.addField(field); } } } /** * * @return if the field uses a field header. Defaults to false. */ public boolean hasFieldHeader() { return hasFieldHeader; } /** * Specify if the CSV file has a field header * @param hasFieldHeader true or false */ public void setHasFieldHeader(boolean hasFieldHeader) { this.hasFieldHeader = hasFieldHeader; } } ./src/java/org/apache/commons/csv/writer/CSVConfig.java0000644000175000017500000001737411061274762023635 0ustar janpascaljanpascal/* * 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.commons.csv.writer; import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; /** * The CSVConfig is used to configure the CSV writer * * @author Martin van den Bemt * @version $Id: $ */ public class CSVConfig { /** specifies if it is a fixed width csv file **/ private boolean fixedWidth; /** list of fields **/ private List fields; /** Do no do any filling **/ public static final int FILLNONE = 0; /** Fill content the the left. Mainly usable together with fixedWidth **/ public static final int FILLLEFT = 1; /** Fill content to the right. Mainly usable together with fixedWidth **/ public static final int FILLRIGHT = 2; /** The fill pattern */ private int fill; /** The fill char. Defaults to a space */ private char fillChar = ' '; /** The seperator character. Defaults to , */ private char delimiter = ','; /** Should we ignore the delimiter. Defaults to false */ private boolean ignoreDelimiter = false; /** the value delimiter. Defaults to " */ private char valueDelimiter = '"'; /** Should we ignore the value delimiter. Defaults to true */ private boolean ignoreValueDelimiter = true; /** Specifies if we want to use a field header */ private boolean fieldHeader = false; /** Specifies if the end of the line needs to be trimmed */ private boolean endTrimmed = false; /** * */ public CSVConfig() { super(); } /** * @return if the CSV file is fixedWidth */ public boolean isFixedWidth() { return fixedWidth; } /** * Specify if the CSV file is fixed width. * Defaults to false * @param fixedWidth the fixedwidth */ public void setFixedWidth(boolean fixedWidth) { this.fixedWidth = fixedWidth; } public void addField(CSVField field) { if (fields == null) { fields = new ArrayList(); } fields.add(field); } /** * Set the fields that should be used by the writer. * This will overwrite currently added fields completely! * @param csvFields the csvfields array. If null it will do nothing */ public void setFields(CSVField[] csvFields) { if (csvFields == null) { return; } fields = new ArrayList(Arrays.asList(csvFields)); } /** * Set the fields that should be used by the writer * @param csvField a collection with fields. If null it will do nothing */ public void setFields(Collection csvField) { if (csvField == null) { return; } fields = new ArrayList(csvField); } /** * @return an array with the known fields (even if no fields are specified) */ public CSVField[] getFields() { CSVField[] csvFields = new CSVField[0]; if (fields != null) { return (CSVField[]) fields.toArray(csvFields); } return csvFields; } public CSVField getField(String name) { if (fields == null || name == null) { return null; } for(int i = 0; i < fields.size(); i++) { CSVField field = (CSVField) fields.get(i); if (name.equals(field.getName())) { return field; } } return null; } /** * @return the fill pattern. */ public int getFill() { return fill; } /** * Set the fill pattern. Defaults to {@link #FILLNONE} *
Other options are : {@link #FILLLEFT} and {@link #FILLRIGHT} * @param fill the fill pattern. */ public void setFill(int fill) { this.fill = fill; } /** * * @return the fillchar. Defaults to a space. */ public char getFillChar() { return fillChar; } /** * Set the fill char * @param fillChar the fill char */ public void setFillChar(char fillChar) { this.fillChar = fillChar; } /** * @return the delimeter used. */ public char getDelimiter() { return delimiter; } /** * Set the delimiter to use * @param delimiter the delimiter character. */ public void setDelimiter(char delimiter) { this.delimiter = delimiter; } /** * @return if the writer should ignore the delimiter character. */ public boolean isDelimiterIgnored() { return ignoreDelimiter; } /** * Specify if the writer should ignore the delimiter. * @param ignoreDelimiter defaults to false. */ public void setIgnoreDelimiter(boolean ignoreDelimiter) { this.ignoreDelimiter = ignoreDelimiter; } /** * @return the value delimeter used. Defaults to " */ public char getValueDelimiter() { return valueDelimiter; } /** * Set the value delimiter to use * @param valueDelimiter the value delimiter character. */ public void setValueDelimiter(char valueDelimiter) { this.valueDelimiter = valueDelimiter; } /** * @return if the writer should ignore the value delimiter character. * Defaults to true. */ public boolean isValueDelimiterIgnored() { return ignoreValueDelimiter; } /** * Specify if the writer should ignore the value delimiter. * @param ignoreValueDelimiter defaults to false. */ public void setIgnoreValueDelimiter(boolean ignoreValueDelimiter) { this.ignoreValueDelimiter = ignoreValueDelimiter; } /** * @return if a field header is used. Defaults to false */ public boolean isFieldHeader() { return fieldHeader; } /** * Specify if you want to use a field header. * @param fieldHeader true or false. */ public void setFieldHeader(boolean fieldHeader) { this.fieldHeader = fieldHeader; } /** * TODO.. * @see java.lang.Object#equals(java.lang.Object) */ public boolean equals(Object obj) { if (obj == null && !(obj instanceof CSVConfig)) { return false; } return super.equals(obj); // CSVConfig config = (CSVConfig) obj; // getFill() == config.getFill() // getFields().equals(config.getFields()) } /** * Creates a config based on a stream. It tries to guess
* NOTE : The stream will be closed. * @param inputStream the inputstream. * @return the guessed config. */ public static CSVConfig guessConfig(InputStream inputStream) { return null; } /** * @return if the end of the line should be trimmed. Default is false. */ public boolean isEndTrimmed() { return endTrimmed; } /** * Specify if the end of the line needs to be trimmed. Defaults to false. * @param endTrimmed */ public void setEndTrimmed(boolean endTrimmed) { this.endTrimmed = endTrimmed; } } ./src/java/org/apache/commons/csv/writer/CSVWriter.java0000644000175000017500000001031511061274762023670 0ustar janpascaljanpascal/* * 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.commons.csv.writer; import java.io.Writer; import java.util.Arrays; import java.util.Map; /** * CSVWriter * * @author Martin van den Bemt * @version $Id: $ */ public class CSVWriter { /** The CSV config **/ private CSVConfig config; /** The writer **/ private Writer writer; /** * */ public CSVWriter() { } public CSVWriter(CSVConfig config) { setConfig(config); } public void writeRecord(Map map) { CSVField[] fields = config.getFields(); try { StringBuffer sb = new StringBuffer(); for (int i = 0; i < fields.length; i++) { Object o = map.get(fields[i].getName()); if (o != null) { String value = o.toString(); value = writeValue(fields[i], value); sb.append(value); } if (!config.isDelimiterIgnored() && fields.length != (i+1)) { sb.append(config.getDelimiter()); } } if (config.isEndTrimmed()) { for (int i = sb.length()-1; i >= 0; i--) { System.out.println("i : " + i); if (Character.isWhitespace(sb.charAt(i))) { sb.deleteCharAt(i); } else { break; } } } sb.append("\n"); String line = sb.toString(); writer.write(line); } catch(Exception e) { e.printStackTrace(); } } protected String writeValue(CSVField field, String value) throws Exception { if (config.isFixedWidth()) { if (value.length() < field.getSize()) { int fillPattern = config.getFill(); if (field.overrideFill()) { fillPattern = field.getFill(); } StringBuffer sb = new StringBuffer(); int fillSize = (field.getSize() - value.length()); char[] fill = new char[fillSize]; Arrays.fill(fill, config.getFillChar()); if (fillPattern == CSVConfig.FILLLEFT) { sb.append(fill); sb.append(value); value = sb.toString(); } else { // defaults to fillpattern FILLRIGHT when fixedwidth is used sb.append(value); sb.append(fill); value = sb.toString(); } } else if (value.length() > field.getSize()) { // value to big.. value = value.substring(0, field.getSize()); } if (!config.isValueDelimiterIgnored()) { // add the value delimiter.. value = config.getValueDelimiter()+value+config.getValueDelimiter(); } } return value; } /** * @return the CVSConfig or null if not present */ public CSVConfig getConfig() { return config; } /** * Set the CSVConfig * @param config the CVSConfig */ public void setConfig(CSVConfig config) { this.config = config; } /** * Set the writer to write the CSV file to. * @param writer the writer. */ public void setWriter(Writer writer) { this.writer = writer; } } ./src/java/org/apache/commons/csv/writer/CSVField.java0000644000175000017500000000465511061274762023451 0ustar janpascaljanpascal/* * 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.commons.csv.writer; /** * * @author Martin van den Bemt * @version $Id: $ */ public class CSVField { private String name; private int size; private int fill; private boolean overrideFill; /** * */ public CSVField() { } /** * @param name the name of the field */ public CSVField(String name) { setName(name); } /** * @param name the name of the field * @param size the size of the field */ public CSVField(String name, int size) { setName(name); setSize(size); } /** * @return the name of the field */ public String getName() { return name; } /** * Set the name of the field * @param name the name */ public void setName(String name) { this.name = name; } /** * * @return the size of the field */ public int getSize() { return size; } /** * Set the size of the field. * The size will be ignored when fixedwidth is set to false in the CSVConfig * @param size the size of the field. */ public void setSize(int size) { this.size = size; } /** * @return the fill pattern. */ public int getFill() { return fill; } /** * Sets overrideFill to true. * @param fill the file pattern */ public void setFill(int fill) { overrideFill = true; this.fill = fill; } /** * Does this field override fill ? * * @return */ public boolean overrideFill() { return overrideFill; } } ./src/java/org/apache/commons/csv/CharBuffer.java0000644000175000017500000001431011061274763022533 0ustar janpascaljanpascal/* * 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.commons.csv; /** * A simple StringBuffer replacement that aims to * reduce copying as much as possible. The buffer * grows as necessary. * This class is not thread safe. * * @author Ortwin Gl�ck */ public class CharBuffer { private char[] c; /** * Actually used number of characters in the array. * It is also the index at which * a new character will be inserted into c. */ private int length; /** * Creates a new CharBuffer with an initial capacity of 32 characters. */ public CharBuffer() { this(32); } /** * Creates a new CharBuffer with an initial capacity * of length characters. */ public CharBuffer(final int length) { if (length == 0) { throw new IllegalArgumentException("Can't create an empty CharBuffer"); } this.c = new char[length]; } /** * Empties the buffer. The capacity still remains the same, so no memory is freed. */ public void clear() { length = 0; } /** * Returns the number of characters in the buffer. * @return the number of characters */ public int length() { return length; } /** * Returns the current capacity of the buffer. * @return the maximum number of characters that can be stored in this buffer without * resizing it. */ public int capacity() { return c.length; } /** * Appends the contents of cb to the end of this CharBuffer. * @param cb the CharBuffer to append or null */ public void append(final CharBuffer cb) { if (cb == null) { return; } provideCapacity(length + cb.length); System.arraycopy(cb.c, 0, c, length, cb.length); length += cb.length; } /** * Appends s to the end of this CharBuffer. * This method involves copying the new data once! * @param s the String to append or null */ public void append(final String s) { if (s == null) { return; } append(s.toCharArray()); } /** * Appends sb to the end of this CharBuffer. * This method involves copying the new data once! * @param sb the StringBuffer to append or null */ public void append(final StringBuffer sb) { if (sb == null) { return; } provideCapacity(length + sb.length()); sb.getChars(0, sb.length(), c, length); length += sb.length(); } /** * Appends data to the end of this CharBuffer. * This method involves copying the new data once! * @param data the char[] to append or null */ public void append(final char[] data) { if (data == null) { return; } provideCapacity(length + data.length); System.arraycopy(data, 0, c, length, data.length); length += data.length; } /** * Appends a single character to the end of this CharBuffer. * This method involves copying the new data once! * @param data the char to append */ public void append(final char data) { provideCapacity(length + 1); c[length] = data; length++; } /** * Shrinks the capacity of the buffer to the current length if necessary. * This method involves copying the data once! */ public void shrink() { if (c.length == length) { return; } char[] newc = new char[length]; System.arraycopy(c, 0, newc, 0, length); c = newc; } /** * Removes trailing whitespace. */ public void trimTrailingWhitespace() { while (length>0 && Character.isWhitespace(c[length-1])) { length--; } } /** * Returns the contents of the buffer as a char[]. The returned array may * be the internal array of the buffer, so the caller must take care when * modifying it. * This method allows to avoid copying if the caller knows the exact capacity * before. * @return */ public char[] getCharacters() { if (c.length == length) { return c; } char[] chars = new char[length]; System.arraycopy(c, 0, chars, 0, length); return chars; } /** * Returns the character at the specified position. */ public char charAt(int pos) { return c[pos]; } /** * Converts the contents of the buffer into a StringBuffer. * This method involves copying the new data once! * @return */ public StringBuffer toStringBuffer() { StringBuffer sb = new StringBuffer(length); sb.append(c, 0, length); return sb; } /** * Converts the contents of the buffer into a StringBuffer. * This method involves copying the new data once! * @return */ public String toString() { return new String(c, 0, length); } /** * Copies the data into a new array of at least capacity size. * @param capacity */ public void provideCapacity(final int capacity) { if (c.length >= capacity) { return; } int newcapacity = ((capacity*3)>>1) + 1; char[] newc = new char[newcapacity]; System.arraycopy(c, 0, newc, 0, length); c = newc; } } ./src/java/org/apache/commons/csv/ExtendedBufferedReader.java0000644000175000017500000002047411061274763025062 0ustar janpascaljanpascal/* * 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.commons.csv; import java.io.BufferedReader; import java.io.IOException; import java.io.Reader; /** * ExtendedBufferedReader * * A special reader decorater which supports more * sophisticated access to the underlying reader object. * * In particular the reader supports a look-ahead option, * which allows you to see the next char returned by * next(). * Furthermore the skip-method supports skipping until * (but excluding) a given char. Similar functionality * is supported by the reader as well. * */ class ExtendedBufferedReader extends BufferedReader { /** the end of stream symbol */ public static final int END_OF_STREAM = -1; /** undefined state for the lookahead char */ public static final int UNDEFINED = -2; /** the lookahead chars */ private int lookaheadChar = UNDEFINED; /** the last char returned */ private int lastChar = UNDEFINED; /** the line counter */ private int lineCounter = 0; private CharBuffer line = new CharBuffer(); /** * Created extended buffered reader using default buffer-size * */ public ExtendedBufferedReader(Reader r) { super(r); /* note uh: do not fetch the first char here, * because this might block the method! */ } /** * Create extended buffered reader using the given buffer-size */ public ExtendedBufferedReader(Reader r, int bufSize) { super(r, bufSize); /* note uh: do not fetch the first char here, * because this might block the method! */ } /** * Reads the next char from the input stream. * @return the next char or END_OF_STREAM if end of stream has been reached. */ public int read() throws IOException { // initalize the lookahead if (lookaheadChar == UNDEFINED) { lookaheadChar = super.read(); } lastChar = lookaheadChar; if (super.ready()) { lookaheadChar = super.read(); } else { lookaheadChar = UNDEFINED; } if (lastChar == '\n') { lineCounter++; } return lastChar; } /** * Returns the last read character again. * * @return the last read char or UNDEFINED */ public int readAgain() { return lastChar; } /** * Non-blocking reading of len chars into buffer buf starting * at bufferposition off. * * performs an iteratative read on the underlying stream * as long as the following conditions hold: * - less than len chars have been read * - end of stream has not been reached * - next read is not blocking * * @return nof chars actually read or END_OF_STREAM */ public int read(char[] buf, int off, int len) throws IOException { // do not claim if len == 0 if (len == 0) { return 0; } // init lookahead, but do not block !! if (lookaheadChar == UNDEFINED) { if (ready()) { lookaheadChar = super.read(); } else { return -1; } } // 'first read of underlying stream' if (lookaheadChar == -1) { return -1; } // continue until the lookaheadChar would block int cOff = off; while (len > 0 && ready()) { if (lookaheadChar == -1) { // eof stream reached, do not continue return cOff - off; } else { buf[cOff++] = (char) lookaheadChar; if (lookaheadChar == '\n') { lineCounter++; } lastChar = lookaheadChar; lookaheadChar = super.read(); len--; } } return cOff - off; } /** * Reads all characters up to (but not including) the given character. * * @param c the character to read up to * @return the string up to the character c * @throws IOException */ public String readUntil(char c) throws IOException { if (lookaheadChar == UNDEFINED) { lookaheadChar = super.read(); } line.clear(); // reuse while (lookaheadChar != c && lookaheadChar != END_OF_STREAM) { line.append((char) lookaheadChar); if (lookaheadChar == '\n') { lineCounter++; } lastChar = lookaheadChar; lookaheadChar = super.read(); } return line.toString(); } /** * @return A String containing the contents of the line, not * including any line-termination characters, or null * if the end of the stream has been reached */ public String readLine() throws IOException { if (lookaheadChar == UNDEFINED) { lookaheadChar = super.read(); } line.clear(); //reuse // return null if end of stream has been reached if (lookaheadChar == END_OF_STREAM) { return null; } // do we have a line termination already char laChar = (char) lookaheadChar; if (laChar == '\n' || laChar == '\r') { lastChar = lookaheadChar; lookaheadChar = super.read(); // ignore '\r\n' as well if ((char) lookaheadChar == '\n') { lastChar = lookaheadChar; lookaheadChar = super.read(); } lineCounter++; return line.toString(); } // create the rest-of-line return and update the lookahead line.append(laChar); String restOfLine = super.readLine(); // TODO involves copying lastChar = lookaheadChar; lookaheadChar = super.read(); if (restOfLine != null) { line.append(restOfLine); } lineCounter++; return line.toString(); } /** * Skips char in the stream * * ATTENTION: invalidates the line-counter !!!!! * * @return nof skiped chars */ public long skip(long n) throws IllegalArgumentException, IOException { if (lookaheadChar == UNDEFINED) { lookaheadChar = super.read(); } // illegal argument if (n < 0) { throw new IllegalArgumentException("negative argument not supported"); } // no skipping if (n == 0 || lookaheadChar == END_OF_STREAM) { return 0; } // skip and reread the lookahead-char long skiped = 0; if (n > 1) { skiped = super.skip(n - 1); } lookaheadChar = super.read(); // fixme uh: we should check the skiped sequence for line-terminations... lineCounter = Integer.MIN_VALUE; return skiped + 1; } /** * Skips all chars in the input until (but excluding) the given char * * @param c * @return * @throws IllegalArgumentException * @throws IOException */ public long skipUntil(char c) throws IllegalArgumentException, IOException { if (lookaheadChar == UNDEFINED) { lookaheadChar = super.read(); } long counter = 0; while (lookaheadChar != c && lookaheadChar != END_OF_STREAM) { if (lookaheadChar == '\n') { lineCounter++; } lookaheadChar = super.read(); counter++; } return counter; } /** * Returns the next char in the stream without consuming it. * * Remember the next char read by read(..) will always be * identical to lookAhead(). * * @return the next char (without consuming it) or END_OF_STREAM */ public int lookAhead() throws IOException { if (lookaheadChar == UNDEFINED) { lookaheadChar = super.read(); } return lookaheadChar; } /** * Returns the nof line read * ATTENTION: the skip-method does invalidate the line-number counter * * @return the current-line-number (or -1) */ public int getLineNumber() { if (lineCounter > -1) { return lineCounter; } else { return -1; } } public boolean markSupported() { /* note uh: marking is not supported, cause we cannot * see into the future... */ return false; } } ./src/java/org/apache/commons/csv/package.html0000644000175000017500000000716011061274763022147 0ustar janpascaljanpascal org.apache.commons.csv package

Jakarta-Commons CSV Format Support

CSV (or its dialects) are widely used as interfaces to legacy systems or manual data-imports. Basically CSV stands for "Comma Separated Values" but this simple abbreviation leads to more confusion than definitions.

Common to all file dialects is its basic structure: The CSV data-format is record oriented, whereas each record starts on a new textual line. A record is build of a list of values. Keep in mind that not all records must have an equal number of values:

      csv    := records*
      record := values*

The following list contains the csv aspects the WAKE CSV parser supports:

Separators (for lines)
The record separators are hardcoded and cannot be changed. The must be '\n' or '\r\n'.
Delimiter (for values)
The delimiter for values is freely configurable (default ',').
Comments
Some CSV-dialects support a simple comment syntax. A comment is a record which must start with a designated character (the commentStarter). A record of this kind is treated as comment and gets removed from the input (default '(char)0')
Encapsulator
Two encapsulator characters (default '"') are used to enclose -> complex values.
Simple values
A simple value consist of all characters (except the separator) until (but not including) the next separator or a record-terminator. Optionally all leading whitespaces of a simple value can be ignored (default: true).
Complex values
Complex values are encapsulated within the defined encapsulator character. The encapsulator itself must be escaped by '\' or doubled when used inside complex values. Complex values preserve all kind of formatting (including newlines -> multiline-values)
Unicode escapes
Some non-unicode CSVs use unicode escaping sequences for certain unicode characters. The standard unicode-escaping is '\uXXXX' whereas XXXX is the unicode-character-code in hex-format. The parser can optionally resolve unicode escapes (default: disabled).
Empty line skipping
Optionally empty lines in CSV files might be skiped. Not skiping empty lines will return an empty record on '\nEOF' combinations.

In addition to individually defined dialects, two predefined dialects (strict-csv, and excel-csv) can be set directly.

Example usage:

String[] parsedLine = CSVParser.parseLine("a,b,c");
for (int i = 0; i < parsedLine.length; ++i) {
  System.out.println("value " + i + "=" + parsedLine[i]);
}
./src/java/org/apache/commons/csv/CSVPrinter.java0000644000175000017500000001657011061274763022535 0ustar janpascaljanpascal/* * 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.commons.csv; import java.io.OutputStream; import java.io.PrintWriter; import java.io.Writer; /** * Print values as a comma separated list. */ public class CSVPrinter { /** The place that the values get written. */ protected PrintWriter out; /** True if we just began a new line. */ protected boolean newLine = true; private CSVStrategy strategy = CSVStrategy.DEFAULT_STRATEGY; /** * Create a printer that will print values to the given * stream. Character to byte conversion is done using * the default character encoding. Comments will be * written using the default comment character '#'. * * @param out stream to which to print. */ public CSVPrinter(OutputStream out) { this.out = new PrintWriter(out); } /** * Create a printer that will print values to the given * stream. Comments will be * written using the default comment character '#'. * * @param out stream to which to print. */ public CSVPrinter(Writer out) { if (out instanceof PrintWriter) { this.out = (PrintWriter) out; } else { this.out = new PrintWriter(out); } } // ====================================================== // strategies // ====================================================== /** * Sets the specified CSV Strategy * * @return current instance of CSVParser to allow chained method calls */ public CSVPrinter setStrategy(CSVStrategy strategy) { this.strategy = strategy; return this; } /** * Obtain the specified CSV Strategy * * @return strategy currently being used */ public CSVStrategy getStrategy() { return this.strategy; } // ====================================================== // printing implementation // ====================================================== /** * Print the string as the last value on the line. The value * will be quoted if needed. * * @param value value to be outputted. */ public void println(String value) { print(value); out.println(); out.flush(); newLine = true; } /** * Output a blank line */ public void println() { out.println(); out.flush(); newLine = true; } /** * Print a single line of comma separated values. * The values will be quoted if needed. Quotes and * newLine characters will be escaped. * * @param values values to be outputted. */ public void println(String[] values) { for (int i = 0; i < values.length; i++) { print(values[i]); } out.println(); out.flush(); newLine = true; } /** * Print several lines of comma separated values. * The values will be quoted if needed. Quotes and * newLine characters will be escaped. * * @param values values to be outputted. */ public void println(String[][] values) { for (int i = 0; i < values.length; i++) { println(values[i]); } if (values.length == 0) { out.println(); } out.flush(); newLine = true; } /** * Put a comment among the comma separated values. * Comments will always begin on a new line and occupy a * least one full line. The character specified to star * comments and a space will be inserted at the beginning of * each new line in the comment. * * @param comment the comment to output */ public void printlnComment(String comment) { if(this.strategy.isCommentingDisabled()) { return; } if (!newLine) { out.println(); } out.print(this.strategy.getCommentStart()); out.print(' '); for (int i = 0; i < comment.length(); i++) { char c = comment.charAt(i); switch (c) { case '\r' : if (i + 1 < comment.length() && comment.charAt(i + 1) == '\n') { i++; } // break intentionally excluded. case '\n' : out.println(); out.print(this.strategy.getCommentStart()); out.print(' '); break; default : out.print(c); break; } } out.println(); out.flush(); newLine = true; } /** * Print the string as the next value on the line. The value * will be quoted if needed. * * @param value value to be outputted. */ public void print(String value) { boolean quote = false; if (value.length() > 0) { char c = value.charAt(0); if (newLine && (c < '0' || (c > '9' && c < 'A') || (c > 'Z' && c < 'a') || (c > 'z'))) { quote = true; } if (c == ' ' || c == '\f' || c == '\t') { quote = true; } for (int i = 0; i < value.length(); i++) { c = value.charAt(i); if (c == '"' || c == this.strategy.getDelimiter() || c == '\n' || c == '\r') { quote = true; c = value.charAt( value.length() - 1 ); break; } } if (c == ' ' || c == '\f' || c == '\t') { quote = true; } } else if (newLine) { // always quote an empty token that is the first // on the line, as it may be the only thing on the // line. If it were not quoted in that case, // an empty line has no tokens. quote = true; } if (newLine) { newLine = false; } else { out.print(this.strategy.getDelimiter()); } if (quote) { out.print(escapeAndQuote(value)); } else { out.print(value); } out.flush(); } /** * Enclose the value in quotes and escape the quote * and comma characters that are inside. * * @param value needs to be escaped and quoted * @return the value, escaped and quoted */ private String escapeAndQuote(String value) { // the initial count is for the preceding and trailing quotes int count = 2; for (int i = 0; i < value.length(); i++) { switch (value.charAt(i)) { case '\"' : case '\n' : case '\r' : case '\\' : count++; break; default: break; } } StringBuffer sb = new StringBuffer(value.length() + count); sb.append(strategy.getEncapsulator()); for (int i = 0; i < value.length(); i++) { char c = value.charAt(i); if (c == strategy.getEncapsulator()) { sb.append('\\').append(c); continue; } switch (c) { case '\n' : sb.append("\\n"); break; case '\r' : sb.append("\\r"); break; case '\\' : sb.append("\\\\"); break; default : sb.append(c); } } sb.append(strategy.getEncapsulator()); return sb.toString(); } } ./src/java/org/apache/commons/csv/CSVUtils.java0000644000175000017500000001012111061274763022174 0ustar janpascaljanpascal/* * 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.commons.csv; import java.io.StringWriter; import java.io.StringReader; import java.io.IOException; /** * Utility methods for dealing with CSV files */ public class CSVUtils { private static final String[] EMPTY_STRING_ARRAY = new String[0]; private static final String[][] EMPTY_DOUBLE_STRING_ARRAY = new String[0][0]; /** *

CSVUtils instances should NOT be constructed in * standard programming. * *

This constructor is public to permit tools that require a JavaBean * instance to operate.

*/ public CSVUtils() { } /** * Converts an array of string values into a single CSV line. All * null values are converted to the string "null", * all strings equal to "null" will additionally get quotes * around. * * @param values the value array * @return the CSV string, will be an empty string if the length of the * value array is 0 */ public static String printLine(String[] values) { // set up a CSVUtils StringWriter stringWriter = new StringWriter(); CSVPrinter csvPrinter = new CSVPrinter(stringWriter); // check for null values an "null" as strings and convert them // into the strings "null" and "\"null\"" for (int i = 0; i < values.length; i++) { if (values[i] == null) { values[i] = "null"; } else if (values[i].equals("null")) { values[i] = "\"null\""; } } // convert to CSV csvPrinter.println(values); // as the resulting string has \r\n at the end, we will trim that away return stringWriter.toString().trim(); } // ====================================================== // static parsers // ====================================================== /** * Parses the given String according to the default {@link CSVStrategy}. * * @param s CSV String to be parsed. * @return parsed String matrix (which is never null) * @throws IOException in case of error */ public static String[][] parse(String s) throws IOException { if (s == null) { throw new IllegalArgumentException("Null argument not allowed."); } String[][] result = (new CSVParser(new StringReader(s))).getAllValues(); if (result == null) { // since CSVStrategy ignores empty lines an empty array is returned // (i.e. not "result = new String[][] {{""}};") result = EMPTY_DOUBLE_STRING_ARRAY; } return result; } /** * Parses the first line only according to the default {@link CSVStrategy}. * * Parsing empty string will be handled as valid records containing zero * elements, so the following property holds: parseLine("").length == 0. * * @param s CSV String to be parsed. * @return parsed String vector (which is never null) * @throws IOException in case of error */ public static String[] parseLine(String s) throws IOException { if (s == null) { throw new IllegalArgumentException("Null argument not allowed."); } // uh,jh: make sure that parseLine("").length == 0 if (s.length() == 0) { return EMPTY_STRING_ARRAY; } return (new CSVParser(new StringReader(s))).getLine(); } } ./src/java/org/apache/commons/csv/CSVStrategy.java0000644000175000017500000001340311061274763022704 0ustar janpascaljanpascal/* * 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.commons.csv; import java.io.Serializable; /** * CSVStrategy * * Represents the strategy for a CSV. */ public class CSVStrategy implements Cloneable, Serializable { private char delimiter; private char encapsulator; private char commentStart; private char escape; private boolean ignoreLeadingWhitespaces; private boolean ignoreTrailingWhitespaces; private boolean interpretUnicodeEscapes; private boolean ignoreEmptyLines; // -2 is used to signal disabled, because it won't be confused with // an EOF signal (-1), and because \ufffe in UTF-16 would be // encoded as two chars (using surrogates) and thus there should never // be a collision with a real text char. public static char COMMENTS_DISABLED = (char)-2; public static char ESCAPE_DISABLED = (char)-2; public static CSVStrategy DEFAULT_STRATEGY = new CSVStrategy(',', '"', COMMENTS_DISABLED, ESCAPE_DISABLED, true, true, false, true); public static CSVStrategy EXCEL_STRATEGY = new CSVStrategy(',', '"', COMMENTS_DISABLED, ESCAPE_DISABLED, false, false, false, false); public static CSVStrategy TDF_STRATEGY = new CSVStrategy('\t', '"', COMMENTS_DISABLED, ESCAPE_DISABLED, true, true, false, true); public CSVStrategy(char delimiter, char encapsulator, char commentStart) { this(delimiter, encapsulator, commentStart, true, false, true); } /** * Customized CSV strategy setter. * * @param delimiter a Char used for value separation * @param encapsulator a Char used as value encapsulation marker * @param commentStart a Char used for comment identification * @param ignoreLeadingWhitespace TRUE when leading whitespaces should be * ignored * @param interpretUnicodeEscapes TRUE when unicode escapes should be * interpreted * @param ignoreEmptyLines TRUE when the parser should skip emtpy lines */ public CSVStrategy( char delimiter, char encapsulator, char commentStart, char escape, boolean ignoreLeadingWhitespace, boolean ignoreTrailingWhitespace, boolean interpretUnicodeEscapes, boolean ignoreEmptyLines) { setDelimiter(delimiter); setEncapsulator(encapsulator); setCommentStart(commentStart); setEscape(escape); setIgnoreLeadingWhitespaces(ignoreLeadingWhitespace); setIgnoreTrailingWhitespaces(ignoreTrailingWhitespace); setUnicodeEscapeInterpretation(interpretUnicodeEscapes); setIgnoreEmptyLines(ignoreEmptyLines); } /** @deprecated */ public CSVStrategy( char delimiter, char encapsulator, char commentStart, boolean ignoreLeadingWhitespace, boolean interpretUnicodeEscapes, boolean ignoreEmptyLines) { this(delimiter, encapsulator, commentStart, CSVStrategy.ESCAPE_DISABLED, ignoreLeadingWhitespace, true, interpretUnicodeEscapes, ignoreEmptyLines); } public void setDelimiter(char delimiter) { this.delimiter = delimiter; } public char getDelimiter() { return this.delimiter; } public void setEncapsulator(char encapsulator) { this.encapsulator = encapsulator; } public char getEncapsulator() { return this.encapsulator; } public void setCommentStart(char commentStart) { this.commentStart = commentStart; } public char getCommentStart() { return this.commentStart; } public boolean isCommentingDisabled() { return this.commentStart == COMMENTS_DISABLED; } public void setEscape(char escape) { this.escape = escape; } public char getEscape() { return this.escape; } public void setIgnoreLeadingWhitespaces(boolean ignoreLeadingWhitespaces) { this.ignoreLeadingWhitespaces = ignoreLeadingWhitespaces; } public boolean getIgnoreLeadingWhitespaces() { return this.ignoreLeadingWhitespaces; } public void setIgnoreTrailingWhitespaces(boolean ignoreTrailingWhitespaces) { this.ignoreTrailingWhitespaces = ignoreTrailingWhitespaces; } public boolean getIgnoreTrailingWhitespaces() { return this.ignoreTrailingWhitespaces; } public void setUnicodeEscapeInterpretation(boolean interpretUnicodeEscapes) { this.interpretUnicodeEscapes = interpretUnicodeEscapes; } public boolean getUnicodeEscapeInterpretation() { return this.interpretUnicodeEscapes; } public void setIgnoreEmptyLines(boolean ignoreEmptyLines) { this.ignoreEmptyLines = ignoreEmptyLines; } public boolean getIgnoreEmptyLines() { return this.ignoreEmptyLines; } public Object clone() { try { return super.clone(); } catch (CloneNotSupportedException e) { throw new RuntimeException(e); // impossible } } } ./src/java/org/apache/commons/csv/CSVParser.java0000644000175000017500000004672011061274763022346 0ustar janpascaljanpascal/* * 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.commons.csv; import java.io.IOException; import java.io.Reader; import java.io.InputStreamReader; import java.io.InputStream; import java.util.ArrayList; /** * Parses CSV files according to the specified configuration. * * Because CSV appears in many different dialects, the parser supports many * configuration settings by allowing the specification of a {@link CSVStrategy}. * *

Parsing of a csv-string having tabs as separators, * '"' as an optional value encapsulator, and comments starting with '#':

*
 *  String[][] data = 
 *   (new CSVParser(new StringReader("a\tb\nc\td"), new CSVStrategy('\t','"','#'))).getAllValues();
 * 
* *

Parsing of a csv-string in Excel CSV format

*
 *  String[][] data =
 *   (new CSVParser(new StringReader("a;b\nc;d"), CSVStrategy.EXCEL_STRATEGY)).getAllValues();
 * 
* *

* Internal parser state is completely covered by the strategy * and the reader-state.

* *

see package documentation * for more details

*/ public class CSVParser { /** length of the initial token (content-)buffer */ private static final int INITIAL_TOKEN_LENGTH = 50; // the token types /** Token has no valid content, i.e. is in its initilized state. */ protected static final int TT_INVALID = -1; /** Token with content, at beginning or in the middle of a line. */ protected static final int TT_TOKEN = 0; /** Token (which can have content) when end of file is reached. */ protected static final int TT_EOF = 1; /** Token with content when end of a line is reached. */ protected static final int TT_EORECORD = 2; /** Immutable empty String array. */ private static final String[] EMPTY_STRING_ARRAY = new String[0]; // the input stream private final ExtendedBufferedReader in; // TODO: this can be made final if setStrategy is removed private CSVStrategy strategy; // the following objects are shared to reduce garbage /** A record buffer for getLine(). Grows as necessary and is reused. */ private final ArrayList record = new ArrayList(); private final Token reusableToken = new Token(); private final CharBuffer wsBuf = new CharBuffer(); private final CharBuffer code = new CharBuffer(4); /** * Token is an internal token representation. * * It is used as contract between the lexer and the parser. */ static class Token { /** Token type, see TT_xxx constants. */ int type = TT_INVALID; /** The content buffer. */ CharBuffer content = new CharBuffer(INITIAL_TOKEN_LENGTH); /** Token ready flag: indicates a valid token with content (ready for the parser). */ boolean isReady; Token reset() { content.clear(); type = TT_INVALID; isReady = false; return this; } } // ====================================================== // the constructor // ====================================================== /** * Default strategy for the parser follows the default {@link CSVStrategy}. * * @param input an InputStream containing "csv-formatted" stream * @deprecated use {@link #CSVParser(Reader)}. */ public CSVParser(InputStream input) { this(new InputStreamReader(input)); } /** * CSV parser using the default {@link CSVStrategy}. * * @param input a Reader containing "csv-formatted" input */ public CSVParser(Reader input) { // note: must match default-CSV-strategy !! this(input, ','); } /** * Customized value delimiter parser. * * The parser follows the default {@link CSVStrategy} * except for the delimiter setting. * * @param input a Reader based on "csv-formatted" input * @param delimiter a Char used for value separation * @deprecated use {@link #CSVParser(Reader,CSVStrategy)}. */ public CSVParser(Reader input, char delimiter) { this(input, delimiter, '"', CSVStrategy.COMMENTS_DISABLED); } /** * Customized csv parser. * * The parser parses according to the given CSV dialect settings. * Leading whitespaces are truncated, unicode escapes are * not interpreted and empty lines are ignored. * * @param input a Reader based on "csv-formatted" input * @param delimiter a Char used for value separation * @param encapsulator a Char used as value encapsulation marker * @param commentStart a Char used for comment identification * @deprecated use {@link #CSVParser(Reader,CSVStrategy)}. */ public CSVParser(Reader input, char delimiter, char encapsulator, char commentStart) { this(input, new CSVStrategy(delimiter, encapsulator, commentStart)); } /** * Customized CSV parser using the given {@link CSVStrategy} * * @param input a Reader containing "csv-formatted" input * @param strategy the CSVStrategy used for CSV parsing */ public CSVParser(Reader input, CSVStrategy strategy) { this.in = new ExtendedBufferedReader(input); this.strategy = strategy; } // ====================================================== // the parser // ====================================================== /** * Parses the CSV according to the given strategy * and returns the content as an array of records * (whereas records are arrays of single values). *

* The returned content starts at the current parse-position in * the stream. * * @return matrix of records x values ('null' when end of file) * @throws IOException on parse error or input read-failure */ public String[][] getAllValues() throws IOException { ArrayList records = new ArrayList(); String[] values; String[][] ret = null; while ((values = getLine()) != null) { records.add(values); } if (records.size() > 0) { ret = new String[records.size()][]; records.toArray(ret); } return ret; } /** * Parses the CSV according to the given strategy * and returns the next csv-value as string. * * @return next value in the input stream ('null' when end of file) * @throws IOException on parse error or input read-failure */ public String nextValue() throws IOException { Token tkn = nextToken(); String ret = null; switch (tkn.type) { case TT_TOKEN: case TT_EORECORD: ret = tkn.content.toString(); break; case TT_EOF: ret = null; break; case TT_INVALID: default: // error no token available (or error) throw new IOException( "(line " + getLineNumber() + ") invalid parse sequence"); // unreachable: break; } return ret; } /** * Parses from the current point in the stream til * the end of the current line. * * @return array of values til end of line * ('null' when end of file has been reached) * @throws IOException on parse error or input read-failure */ public String[] getLine() throws IOException { String[] ret = EMPTY_STRING_ARRAY; record.clear(); while (true) { reusableToken.reset(); nextToken(reusableToken); switch (reusableToken.type) { case TT_TOKEN: record.add(reusableToken.content.toString()); break; case TT_EORECORD: record.add(reusableToken.content.toString()); break; case TT_EOF: if (reusableToken.isReady) { record.add(reusableToken.content.toString()); } else { ret = null; } break; case TT_INVALID: default: // error: throw IOException throw new IOException("(line " + getLineNumber() + ") invalid parse sequence"); // unreachable: break; } if (reusableToken.type != TT_TOKEN) { break; } } if (!record.isEmpty()) { ret = (String[]) record.toArray(new String[record.size()]); } return ret; } /** * Returns the current line number in the input stream. * * ATTENTION: in case your csv has multiline-values the returned * number does not correspond to the record-number * * @return current line number */ public int getLineNumber() { return in.getLineNumber(); } // ====================================================== // the lexer(s) // ====================================================== /** * Convenience method for nextToken(null). */ protected Token nextToken() throws IOException { return nextToken(new Token()); } /** * Returns the next token. * * A token corresponds to a term, a record change or an * end-of-file indicator. * * @param tkn an existing Token object to reuse. The caller is responsible to initialize the * Token. * @return the next token found * @throws IOException on stream access error */ protected Token nextToken(Token tkn) throws IOException { wsBuf.clear(); // resuse // get the last read char (required for empty line detection) int lastChar = in.readAgain(); // read the next char and set eol /* note: unfourtunately isEndOfLine may consumes a character silently. * this has no effect outside of the method. so a simple workaround * is to call 'readAgain' on the stream... * uh: might using objects instead of base-types (jdk1.5 autoboxing!) */ int c = in.read(); boolean eol = isEndOfLine(c); c = in.readAgain(); // empty line detection: eol AND (last char was EOL or beginning) while (strategy.getIgnoreEmptyLines() && eol && (lastChar == '\n' || lastChar == ExtendedBufferedReader.UNDEFINED) && !isEndOfFile(lastChar)) { // go on char ahead ... lastChar = c; c = in.read(); eol = isEndOfLine(c); c = in.readAgain(); // reached end of file without any content (empty line at the end) if (isEndOfFile(c)) { tkn.type = TT_EOF; return tkn; } } // did we reached eof during the last iteration already ? TT_EOF if (isEndOfFile(lastChar) || (lastChar != strategy.getDelimiter() && isEndOfFile(c))) { tkn.type = TT_EOF; return tkn; } // important: make sure a new char gets consumed in each iteration while (!tkn.isReady) { // ignore whitespaces at beginning of a token while (isWhitespace(c) && !eol) { wsBuf.append((char) c); c = in.read(); eol = isEndOfLine(c); } // ok, start of token reached: comment, encapsulated, or token if (c == strategy.getCommentStart()) { // ignore everything till end of line and continue (incr linecount) in.readLine(); tkn = nextToken(tkn.reset()); } else if (c == strategy.getDelimiter()) { // empty token return TT_TOKEN("") tkn.type = TT_TOKEN; tkn.isReady = true; } else if (eol) { // empty token return TT_EORECORD("") //noop: tkn.content.append(""); tkn.type = TT_EORECORD; tkn.isReady = true; } else if (c == strategy.getEncapsulator()) { // consume encapsulated token encapsulatedTokenLexer(tkn, c); } else if (isEndOfFile(c)) { // end of file return TT_EOF() //noop: tkn.content.append(""); tkn.type = TT_EOF; tkn.isReady = true; } else { // next token must be a simple token // add removed blanks when not ignoring whitespace chars... if (!strategy.getIgnoreLeadingWhitespaces()) { tkn.content.append(wsBuf); } simpleTokenLexer(tkn, c); } } return tkn; } /** * A simple token lexer * * Simple token are tokens which are not surrounded by encapsulators. * A simple token might contain escaped delimiters (as \, or \;). The * token is finished when one of the following conditions become true: *

    *
  • end of line has been reached (TT_EORECORD)
  • *
  • end of stream has been reached (TT_EOF)
  • *
  • an unescaped delimiter has been reached (TT_TOKEN)
  • *
* * @param tkn the current token * @param c the current character * @return the filled token * * @throws IOException on stream access error */ private Token simpleTokenLexer(Token tkn, int c) throws IOException { for (;;) { if (isEndOfLine(c)) { // end of record tkn.type = TT_EORECORD; tkn.isReady = true; break; } else if (isEndOfFile(c)) { // end of file tkn.type = TT_EOF; tkn.isReady = true; break; } else if (c == strategy.getDelimiter()) { // end of token tkn.type = TT_TOKEN; tkn.isReady = true; break; } else if (c == '\\' && strategy.getUnicodeEscapeInterpretation() && in.lookAhead() == 'u') { // interpret unicode escaped chars (like \u0070 -> p) tkn.content.append((char) unicodeEscapeLexer(c)); } else if (c == strategy.getEscape()) { tkn.content.append((char)readEscape(c)); } else { tkn.content.append((char) c); } c = in.read(); } if (strategy.getIgnoreTrailingWhitespaces()) { tkn.content.trimTrailingWhitespace(); } return tkn; } /** * An encapsulated token lexer * * Encapsulated tokens are surrounded by the given encapsulating-string. * The encapsulator itself might be included in the token using a * doubling syntax (as "", '') or using escaping (as in \", \'). * Whitespaces before and after an encapsulated token are ignored. * * @param tkn the current token * @param c the current character * @return a valid token object * @throws IOException on invalid state */ private Token encapsulatedTokenLexer(Token tkn, int c) throws IOException { // save current line int startLineNumber = getLineNumber(); // ignore the given delimiter // assert c == delimiter; for (;;) { c = in.read(); if (c == '\\' && strategy.getUnicodeEscapeInterpretation() && in.lookAhead()=='u') { tkn.content.append((char) unicodeEscapeLexer(c)); } else if (c == strategy.getEscape()) { tkn.content.append((char)readEscape(c)); } else if (c == strategy.getEncapsulator()) { if (in.lookAhead() == strategy.getEncapsulator()) { // double or escaped encapsulator -> add single encapsulator to token c = in.read(); tkn.content.append((char) c); } else { // token finish mark (encapsulator) reached: ignore whitespace till delimiter for (;;) { c = in.read(); if (c == strategy.getDelimiter()) { tkn.type = TT_TOKEN; tkn.isReady = true; return tkn; } else if (isEndOfFile(c)) { tkn.type = TT_EOF; tkn.isReady = true; return tkn; } else if (isEndOfLine(c)) { // ok eo token reached tkn.type = TT_EORECORD; tkn.isReady = true; return tkn; } else if (!isWhitespace(c)) { // error invalid char between token and next delimiter throw new IOException( "(line " + getLineNumber() + ") invalid char between encapsulated token end delimiter" ); } } } } else if (isEndOfFile(c)) { // error condition (end of file before end of token) throw new IOException( "(startline " + startLineNumber + ")" + "eof reached before encapsulated token finished" ); } else { // consume character tkn.content.append((char) c); } } } /** * Decodes Unicode escapes. * * Interpretation of "\\uXXXX" escape sequences * where XXXX is a hex-number. * @param c current char which is discarded because it's the "\\" of "\\uXXXX" * @return the decoded character * @throws IOException on wrong unicode escape sequence or read error */ protected int unicodeEscapeLexer(int c) throws IOException { int ret = 0; // ignore 'u' (assume c==\ now) and read 4 hex digits c = in.read(); code.clear(); try { for (int i = 0; i < 4; i++) { c = in.read(); if (isEndOfFile(c) || isEndOfLine(c)) { throw new NumberFormatException("number too short"); } code.append((char) c); } ret = Integer.parseInt(code.toString(), 16); } catch (NumberFormatException e) { throw new IOException( "(line " + getLineNumber() + ") Wrong unicode escape sequence found '" + code.toString() + "'" + e.toString()); } return ret; } private int readEscape(int c) throws IOException { // assume c is the escape char (normally a backslash) c = in.read(); int out; switch (c) { case 'r': out='\r'; break; case 'n': out='\n'; break; case 't': out='\t'; break; case 'b': out='\b'; break; case 'f': out='\f'; break; default : out=c; } return out; } // ====================================================== // strategies // ====================================================== /** * Sets the specified CSV Strategy * * @return current instance of CSVParser to allow chained method calls * @deprecated the strategy should be set in the constructor {@link #CSVParser(Reader,CSVStrategy)}. */ public CSVParser setStrategy(CSVStrategy strategy) { this.strategy = strategy; return this; } /** * Obtain the specified CSV Strategy * * @return strategy currently being used */ public CSVStrategy getStrategy() { return this.strategy; } // ====================================================== // Character class checker // ====================================================== /** * @return true if the given char is a whitespace character */ private boolean isWhitespace(int c) { return Character.isWhitespace((char) c) && (c != strategy.getDelimiter()); } /** * Greedy - accepts \n and \r\n * This checker consumes silently the second control-character... * * @return true if the given character is a line-terminator */ private boolean isEndOfLine(int c) throws IOException { // check if we have \r\n... if (c == '\r') { if (in.lookAhead() == '\n') { // note: does not change c outside of this method !! c = in.read(); } } return (c == '\n'); } /** * @return true if the given character indicates end of file */ private boolean isEndOfFile(int c) { return c == ExtendedBufferedReader.END_OF_STREAM; } } ./src/site/0000755000175000017500000000000011061274763013427 5ustar janpascaljanpascal./src/site/site.xml0000644000175000017500000000145011061274763015115 0ustar janpascaljanpascal ./src/site/xdoc/0000755000175000017500000000000011061274763014364 5ustar janpascaljanpascal./src/site/xdoc/downloads.xml0000644000175000017500000000402611061274763017102 0ustar janpascaljanpascal Downloads

There are currently no official downloads, and will not be until CSV moves out of the Sandbox.

Nightly Builds are built once a day from the current SVN HEAD. This is (nearly) the latest code and so should be treated with caution.

./src/site/xdoc/cvs-usage.xml0000644000175000017500000000354611061274763017013 0ustar janpascaljanpascal Source repository Commons Documentation Team

Apache Commons CSV is hosted on the Apache subversion repository.

The project URL is:
http://svn.apache.org/repos/asf/commons/sandbox/csv/trunk

The best way to view the repository is via the subversion viewer.

The alternative is to use the native subversion display.

For more information on subversion and creating patches see the Apache Contributors Guide.

./src/site/xdoc/examples.xml0000644000175000017500000000216511061274763016730 0ustar janpascaljanpascal Code Examples Commons Documentation Team
  
./src/site/xdoc/issue-tracking.xml0000644000175000017500000001331711061274763020043 0ustar janpascaljanpascal Commons CSV (Sandbox) Issue tracking Commons Documentation Team

Commons CSV (Sandbox) uses ASF JIRA for tracking issues. See the Sandbox JIRA project page.

To use JIRA you may need to create an account (if you have previously created/updated Commons issues using Bugzilla an account will have been automatically created and you can use the Forgot Password page to get a new password).

If you would like to report a bug, or raise an enhancement request with Commons CSV (Sandbox) please do the following:

  1. Search existing open bugs. If you find your issue listed then please add a comment with your details.
  2. Search the mailing list archive(s). You may find your issue or idea has already been discussed.
  3. Decide if your issue is a bug or an enhancement.
  4. Submit either a bug report or enhancement request.

Please also remember these points:

  • the more information you provide, the better we can help you
  • test cases are vital, particularly for any proposed enhancements
  • the developers of Commons CSV (Sandbox) are all unpaid volunteers

For more information on subversion and creating patches see the Apache Contributors Guide.

You may also find these links useful:

./src/site/xdoc/index.xml0000644000175000017500000000546111061274763016223 0ustar janpascaljanpascal Home Commons Documentation Team

Commons CSV was started to unify a common and simple interface for reading and writing CSV files under an ASL license. It has been bootstrapped by a code donation from Netcetera in Switzerland. There are three pre-existing BSD compatible CSV parsers which this component will hopefully make redundant (authors willing):

In addition to the code from Netcetera (org.apache.commons.csv), Martin van den Bemt has added an additional writer API (org.apache.commons.csv.writer).

Other CSV implementations:

There are currently no official downloads, and will not be until CSV moves out of the Sandbox, but a nightly build is available from http://people.apache.org/builds/commons/nightly/commons-csv/.

The latest code may be checked out from the following url - http://svn.apache.org/repos/asf/commons/sandbox/csv/trunk/.

Please report any bugs or issues in the Commons Sandbox Jira project at http://issues.apache.org/jira/browse/SANDBOX. Please ask any questions or suggest any ideas for improvement on the commons-dev and commons-user mailing lists.

./src/changes/0000755000175000017500000000000011061274763014073 5ustar janpascaljanpascal./src/changes/changes.xml0000644000175000017500000000301311061274763016222 0ustar janpascaljanpascal Release Notes ./src/test/0000755000175000017500000000000011061274762013441 5ustar janpascaljanpascal./src/test/org/0000755000175000017500000000000011061274762014230 5ustar janpascaljanpascal./src/test/org/apache/0000755000175000017500000000000011061274762015451 5ustar janpascaljanpascal./src/test/org/apache/commons/0000755000175000017500000000000011061274762017124 5ustar janpascaljanpascal./src/test/org/apache/commons/csv/0000755000175000017500000000000011061274762017717 5ustar janpascaljanpascal./src/test/org/apache/commons/csv/CharBufferTest.java0000644000175000017500000001442511061274762023437 0ustar janpascaljanpascal/* * 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.commons.csv; import junit.framework.TestCase; /** * * @author Ortwin Glück */ public class CharBufferTest extends TestCase { public void testCreate() { CharBuffer cb = new CharBuffer(); assertEquals(0, cb.length()); try { cb = new CharBuffer(0); fail("Should not be possible"); } catch(IllegalArgumentException e) { // expected } cb = new CharBuffer(128); assertEquals(0, cb.length()); } public void testAppendChar() { CharBuffer cb = new CharBuffer(1); String expected = ""; for (char c = 'a'; c < 'z'; c++) { cb.append(c); expected += c; assertEquals(expected, cb.toString()); assertEquals(expected.length(), cb.length()); } } public void testAppendCharArray() { CharBuffer cb = new CharBuffer(1); char[] abcd = "abcd".toCharArray(); String expected = ""; for (int i=0; i<10; i++) { cb.append(abcd); expected += "abcd"; assertEquals(expected, cb.toString()); assertEquals(4*(i+1), cb.length()); } } public void testAppendString() { CharBuffer cb = new CharBuffer(1); String abcd = "abcd"; String expected = ""; for (int i=0; i<10; i++) { cb.append(abcd); expected += abcd; assertEquals(expected, cb.toString()); assertEquals(4*(i+1), cb.length()); } } public void testAppendStringBuffer() { CharBuffer cb = new CharBuffer(1); StringBuffer abcd = new StringBuffer("abcd"); String expected = ""; for (int i=0; i<10; i++) { cb.append(abcd); expected += "abcd"; assertEquals(expected, cb.toString()); assertEquals(4*(i+1), cb.length()); } } public void testAppendCharBuffer() { CharBuffer cb = new CharBuffer(1); CharBuffer abcd = new CharBuffer(17); abcd.append("abcd"); String expected = ""; for (int i=0; i<10; i++) { cb.append(abcd); expected += "abcd"; assertEquals(expected, cb.toString()); assertEquals(4*(i+1), cb.length()); } } public void testShrink() { String data = "123456789012345678901234567890"; CharBuffer cb = new CharBuffer(data.length() + 100); assertEquals(data.length() + 100, cb.capacity()); cb.append(data); assertEquals(data.length() + 100, cb.capacity()); assertEquals(data.length(), cb.length()); cb.shrink(); assertEquals(data.length(), cb.capacity()); assertEquals(data.length(), cb.length()); assertEquals(data, cb.toString()); } //-- the following test cases have been adapted from the HttpComponents project //-- written by Oleg Kalnichevski public void testSimpleAppend() throws Exception { CharBuffer buffer = new CharBuffer(16); assertEquals(16, buffer.capacity()); assertEquals(0, buffer.length()); char[] b1 = buffer.getCharacters(); assertNotNull(b1); assertEquals(0, b1.length); assertEquals(0, buffer.length()); char[] tmp = new char[] { '1', '2', '3', '4'}; buffer.append(tmp); assertEquals(16, buffer.capacity()); assertEquals(4, buffer.length()); char[] b2 = buffer.getCharacters(); assertNotNull(b2); assertEquals(4, b2.length); for (int i = 0; i < tmp.length; i++) { assertEquals(tmp[i], b2[i]); } assertEquals("1234", buffer.toString()); buffer.clear(); assertEquals(16, buffer.capacity()); assertEquals(0, buffer.length()); } public void testAppendString2() throws Exception { CharBuffer buffer = new CharBuffer(8); buffer.append("stuff"); buffer.append(" and more stuff"); assertEquals("stuff and more stuff", buffer.toString()); } public void testAppendNull() throws Exception { CharBuffer buffer = new CharBuffer(8); buffer.append((StringBuffer)null); assertEquals("", buffer.toString()); buffer.append((String)null); assertEquals("", buffer.toString()); buffer.append((CharBuffer)null); assertEquals("", buffer.toString()); buffer.append((char[])null); assertEquals("", buffer.toString()); } public void testAppendCharArrayBuffer() throws Exception { CharBuffer buffer1 = new CharBuffer(8); buffer1.append(" and more stuff"); CharBuffer buffer2 = new CharBuffer(8); buffer2.append("stuff"); buffer2.append(buffer1); assertEquals("stuff and more stuff", buffer2.toString()); } public void testAppendSingleChar() throws Exception { CharBuffer buffer = new CharBuffer(4); buffer.append('1'); buffer.append('2'); buffer.append('3'); buffer.append('4'); buffer.append('5'); buffer.append('6'); assertEquals("123456", buffer.toString()); } public void testProvideCapacity() throws Exception { CharBuffer buffer = new CharBuffer(4); buffer.provideCapacity(2); assertEquals(4, buffer.capacity()); buffer.provideCapacity(8); assertTrue(buffer.capacity() >= 8); } } ./src/test/org/apache/commons/csv/ExtendedBufferedReaderTest.java0000644000175000017500000001626111061274762025756 0ustar janpascaljanpascal/* * 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.commons.csv; import java.io.StringReader; import java.util.Arrays; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * ExtendedBufferedReaderTest * */ public class ExtendedBufferedReaderTest extends TestCase { // ====================================================== // the test cases // ====================================================== public void testConstructors() { ExtendedBufferedReader br = new ExtendedBufferedReader(new StringReader("")); br = new ExtendedBufferedReader(new StringReader(""), 10); } public void testReadLookahead1() throws Exception { assertEquals(ExtendedBufferedReader.END_OF_STREAM, getEBR("").read()); ExtendedBufferedReader br = getEBR("1\n2\r3\n"); assertEquals('1', br.lookAhead()); assertEquals(ExtendedBufferedReader.UNDEFINED, br.readAgain()); assertEquals('1', br.read()); assertEquals('1', br.readAgain()); assertEquals(0, br.getLineNumber()); assertEquals('\n', br.lookAhead()); assertEquals(0, br.getLineNumber()); assertEquals('1', br.readAgain()); assertEquals('\n', br.read()); assertEquals(1, br.getLineNumber()); assertEquals('\n', br.readAgain()); assertEquals(1, br.getLineNumber()); assertEquals('2', br.lookAhead()); assertEquals(1, br.getLineNumber()); assertEquals('\n', br.readAgain()); assertEquals(1, br.getLineNumber()); assertEquals('2', br.read()); assertEquals('2', br.readAgain()); assertEquals('\r', br.lookAhead()); assertEquals('2', br.readAgain()); assertEquals('\r', br.read()); assertEquals('\r', br.readAgain()); assertEquals('3', br.lookAhead()); assertEquals('\r', br.readAgain()); assertEquals('3', br.read()); assertEquals('3', br.readAgain()); assertEquals('\n', br.lookAhead()); assertEquals(1, br.getLineNumber()); assertEquals('3', br.readAgain()); assertEquals('\n', br.read()); assertEquals(2, br.getLineNumber()); assertEquals('\n', br.readAgain()); assertEquals(2, br.getLineNumber()); assertEquals(ExtendedBufferedReader.END_OF_STREAM, br.lookAhead()); assertEquals('\n', br.readAgain()); assertEquals(ExtendedBufferedReader.END_OF_STREAM, br.read()); assertEquals(ExtendedBufferedReader.END_OF_STREAM, br.readAgain()); assertEquals(ExtendedBufferedReader.END_OF_STREAM, br.read()); assertEquals(ExtendedBufferedReader.END_OF_STREAM, br.lookAhead()); } public void testReadLookahead2() throws Exception { char[] ref = new char[5]; char[] res = new char[5]; ExtendedBufferedReader br = getEBR(""); assertEquals(0, br.read(res, 0, 0)); assertTrue(Arrays.equals(res, ref)); br = getEBR("abcdefg"); ref[0] = 'a'; ref[1] = 'b'; ref[2] = 'c'; assertEquals(3, br.read(res, 0, 3)); assertTrue(Arrays.equals(res, ref)); assertEquals('c', br.readAgain()); assertEquals('d', br.lookAhead()); ref[4] = 'd'; assertEquals(1, br.read(res, 4, 1)); assertTrue(Arrays.equals(res, ref)); assertEquals('d', br.readAgain()); } public void testMarkSupported() { assertFalse(getEBR("foo").markSupported()); } public void testReadLine() throws Exception { ExtendedBufferedReader br = getEBR(""); assertTrue(br.readLine() == null); br = getEBR("\n"); assertTrue(br.readLine().equals("")); assertTrue(br.readLine() == null); br = getEBR("foo\n\nhello"); assertEquals(0, br.getLineNumber()); assertTrue(br.readLine().equals("foo")); assertEquals(1, br.getLineNumber()); assertTrue(br.readLine().equals("")); assertEquals(2, br.getLineNumber()); assertTrue(br.readLine().equals("hello")); assertEquals(3, br.getLineNumber()); assertTrue(br.readLine() == null); assertEquals(3, br.getLineNumber()); br = getEBR("foo\n\nhello"); assertEquals('f', br.read()); assertEquals('o', br.lookAhead()); assertTrue(br.readLine().equals("oo")); assertEquals(1, br.getLineNumber()); assertEquals('\n', br.lookAhead()); assertTrue(br.readLine().equals("")); assertEquals(2, br.getLineNumber()); assertEquals('h', br.lookAhead()); assertTrue(br.readLine().equals("hello")); assertTrue(br.readLine() == null); assertEquals(3, br.getLineNumber()); br = getEBR("foo\rbaar\r\nfoo"); assertTrue(br.readLine().equals("foo")); assertEquals('b', br.lookAhead()); assertTrue(br.readLine().equals("baar")); assertEquals('f', br.lookAhead()); assertTrue(br.readLine().equals("foo")); assertTrue(br.readLine() == null); } public void testSkip0() throws Exception { ExtendedBufferedReader br = getEBR(""); assertEquals(0, br.skip(0)); assertEquals(0, br.skip(1)); br = getEBR(""); assertEquals(0, br.skip(1)); br = getEBR("abcdefg"); assertEquals(0, br.skip(0)); assertEquals('a', br.lookAhead()); assertEquals(0, br.skip(0)); assertEquals('a', br.lookAhead()); assertEquals(1, br.skip(1)); assertEquals('b', br.lookAhead()); assertEquals('b', br.read()); assertEquals(3, br.skip(3)); assertEquals('f', br.lookAhead()); assertEquals(2, br.skip(5)); assertTrue(br.readLine() == null); br = getEBR("12345"); assertEquals(5, br.skip(5)); assertTrue (br.lookAhead() == ExtendedBufferedReader.END_OF_STREAM); } public void testSkipUntil() throws Exception { ExtendedBufferedReader br = getEBR(""); assertEquals(0, br.skipUntil(';')); br = getEBR("ABCDEF,GHL,,MN"); assertEquals(6, br.skipUntil(',')); assertEquals(0, br.skipUntil(',')); br.skip(1); assertEquals(3, br.skipUntil(',')); br.skip(1); assertEquals(0, br.skipUntil(',')); br.skip(1); assertEquals(2, br.skipUntil(',')); } public void testReadUntil() throws Exception { ExtendedBufferedReader br = getEBR(""); assertTrue(br.readUntil(';').equals("")); br = getEBR("ABCDEF;GHL;;MN"); assertTrue(br.readUntil(';').equals("ABCDEF")); assertTrue(br.readUntil(';').length() == 0); br.skip(1); assertTrue(br.readUntil(';').equals("GHL")); br.skip(1); assertTrue(br.readUntil(';').equals("")); br.skip(1); assertTrue(br.readUntil(',').equals("MN")); } private ExtendedBufferedReader getEBR(String s) { return new ExtendedBufferedReader(new StringReader(s)); } } ./src/test/org/apache/commons/csv/writer/0000755000175000017500000000000011061274762021233 5ustar janpascaljanpascal./src/test/org/apache/commons/csv/writer/CSVFieldTest.java0000644000175000017500000000350511061274762024340 0ustar janpascaljanpascal/* * 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.commons.csv.writer; import junit.framework.TestCase; /** * * @author Martin van den Bemt * @version $Id: $ */ public class CSVFieldTest extends TestCase { public void testCSVField() { CSVField field = new CSVField(); assertEquals(null, field.getName()); field.setName("id"); assertEquals("id", field.getName()); assertEquals(0, field.getSize()); field.setSize(10); assertEquals(10, field.getSize()); field = new CSVField("name"); assertEquals("name", field.getName()); field = new CSVField("name", 10); assertEquals("name", field.getName()); assertEquals(10, field.getSize()); } public void testFill() { CSVField field = new CSVField(); assertEquals(CSVConfig.FILLNONE, field.getFill()); assertEquals(false, field.overrideFill()); field.setFill(CSVConfig.FILLLEFT); assertEquals(true, field.overrideFill()); assertEquals(CSVConfig.FILLLEFT, field.getFill()); } } ./src/test/org/apache/commons/csv/writer/CSVConfigGuesserTest.java0000644000175000017500000000656611061274762026072 0ustar janpascaljanpascal/* * 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.commons.csv.writer; import java.io.ByteArrayInputStream; import junit.framework.TestCase; /** * Tests for the config guesser. * * @author Martin van den Bemt * @version $Id: $ */ public class CSVConfigGuesserTest extends TestCase { public void testSetters() throws Exception { CSVConfigGuesser guesser = new CSVConfigGuesser(); ByteArrayInputStream in = new ByteArrayInputStream(new byte[0]); guesser.setInputStream(in); assertEquals(in, guesser.getInputStream()); guesser = new CSVConfigGuesser(in); assertEquals(in, guesser.getInputStream()); assertEquals(false, guesser.hasFieldHeader()); guesser.setHasFieldHeader(true); assertEquals(true, guesser.hasFieldHeader()); } /** * Test a format like * 1234 ; abcd ; 1234 ; * */ public void testConfigGuess1() { CSVConfig expected = new CSVConfig(); expected.setDelimiter(';'); expected.setValueDelimiter(' '); expected.setFill(CSVConfig.FILLRIGHT); expected.setIgnoreValueDelimiter(false); expected.setFixedWidth(true); CSVField field = new CSVField(); field.setSize(4); expected.addField(field); expected.addField(field); StringBuffer sb = new StringBuffer(); sb.append("1234;abcd;1234\n"); sb.append("abcd;1234;abcd"); ByteArrayInputStream in = new ByteArrayInputStream(sb.toString().getBytes()); CSVConfigGuesser guesser = new CSVConfigGuesser(in); CSVConfig guessed = guesser.guess(); assertEquals(expected.isFixedWidth(), guessed.isFixedWidth()); assertEquals(expected.getFields().length, guessed.getFields().length); assertEquals(expected.getFields()[0].getSize(), guessed.getFields()[0].getSize()); } /** * Test a format like * 1234,123123,12312312,213123 * 1,2,3,4 * */ public void testConfigGuess2() { CSVConfig expected = new CSVConfig(); expected.setDelimiter(';'); expected.setValueDelimiter(' '); expected.setFill(CSVConfig.FILLRIGHT); expected.setIgnoreValueDelimiter(false); // expected.setFixedWidth(false); StringBuffer sb = new StringBuffer(); sb.append("1,2,3,4\n"); sb.append("abcd,1234,abcd,1234"); ByteArrayInputStream in = new ByteArrayInputStream(sb.toString().getBytes()); CSVConfigGuesser guesser = new CSVConfigGuesser(in); CSVConfig guessed = guesser.guess(); assertEquals(expected.isFixedWidth(), guessed.isFixedWidth()); } } ./src/test/org/apache/commons/csv/writer/CSVConfigTest.java0000644000175000017500000000712411061274762024523 0ustar janpascaljanpascal/* * 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.commons.csv.writer; import java.util.Collection; import junit.framework.TestCase; /** * Testcase for the CSVConfig * * @author Martin van den Bemt * @version $Id: $ */ public class CSVConfigTest extends TestCase { public void testFixedWith() { CSVConfig config = new CSVConfig(); assertEquals(false, config.isFixedWidth()); config.setFixedWidth(true); assertEquals(true, config.isFixedWidth()); } public void testFields() { CSVConfig config = new CSVConfig(); assertEquals(0, config.getFields().length); config.setFields((CSVField[])null); assertEquals(0, config.getFields().length); config.setFields((Collection)null); assertEquals(0, config.getFields().length); CSVField field = new CSVField(); field.setName("field1"); config.addField(field); assertEquals(field, config.getFields()[0]); assertEquals(null, config.getField(null)); assertEquals(null, config.getField("field11")); assertEquals(field, config.getField("field1")); } public void testFill() { CSVConfig config = new CSVConfig(); assertEquals(CSVConfig.FILLNONE, config.getFill()); config.setFill(CSVConfig.FILLLEFT); assertEquals(CSVConfig.FILLLEFT, config.getFill()); config.setFill(CSVConfig.FILLRIGHT); assertEquals(CSVConfig.FILLRIGHT, config.getFill()); assertEquals(' ', config.getFillChar()); config.setFillChar('m'); assertEquals('m', config.getFillChar()); } public void testDelimiter() { CSVConfig config = new CSVConfig(); assertEquals(',', config.getDelimiter()); config.setDelimiter(';'); assertEquals(';', config.getDelimiter()); assertEquals(false, config.isDelimiterIgnored()); config.setIgnoreDelimiter(true); assertEquals(true, config.isDelimiterIgnored()); } public void testValueDelimiter() { CSVConfig config = new CSVConfig(); assertEquals('"', config.getValueDelimiter()); config.setValueDelimiter('m'); assertEquals('m', config.getValueDelimiter()); assertEquals(true, config.isValueDelimiterIgnored()); config.setIgnoreValueDelimiter(false); assertEquals(false, config.isValueDelimiterIgnored()); } public void testFieldHeader() { CSVConfig config = new CSVConfig(); assertEquals(false, config.isFieldHeader()); config.setFieldHeader(true); assertEquals(true, config.isFieldHeader()); } public void testTrimEnd() { CSVConfig config = new CSVConfig(); assertEquals(false, config.isEndTrimmed()); config.setEndTrimmed(true); assertEquals(true, config.isEndTrimmed()); } } ./src/test/org/apache/commons/csv/writer/CSVWriterTest.java0000644000175000017500000000370411061274762024572 0ustar janpascaljanpascal/* * 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.commons.csv.writer; import java.io.StringWriter; import java.util.HashMap; import java.util.Map; import junit.framework.TestCase; /** * The testcase for the csv writer. * * @author Martin van den Bemt * @version $Id: $ */ public class CSVWriterTest extends TestCase { public void testCSVConfig() { CSVWriter writer = new CSVWriter(); assertEquals(null, writer.getConfig()); CSVConfig config = new CSVConfig(); writer.setConfig(config); assertEquals(config, writer.getConfig()); writer = new CSVWriter(config); assertEquals(config, writer.getConfig()); } public void testWriter() { CSVWriter writer = new CSVWriter(); CSVConfig config = new CSVConfig(); config.addField(new CSVField("field1", 5)); config.addField(new CSVField("field2", 4)); writer.setConfig(config); StringWriter sw = new StringWriter(); writer.setWriter(sw); Map map = new HashMap(); map.put("field1", "12345"); map.put("field2", "1234"); writer.writeRecord(map); assertEquals("12345,1234\n",sw.toString()); } } ./src/test/org/apache/commons/csv/CSVUtilsTest.java0000644000175000017500000001157211061274762023104 0ustar janpascaljanpascal/* * 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.commons.csv; import java.io.IOException; import junit.framework.TestCase; /** * CSVUtilsTest */ public class CSVUtilsTest extends TestCase { // ====================================================== // static parser tests // ====================================================== public void testParse1() throws IOException { String[][] data = CSVUtils.parse("abc\ndef"); assertEquals(2, data.length); assertEquals(1, data[0].length); assertEquals(1, data[1].length); assertEquals("abc", data[0][0]); assertEquals("def", data[1][0]); } public void testParse2() throws IOException { String[][] data = CSVUtils.parse("abc,def,\"ghi,jkl\"\ndef"); assertEquals(2, data.length); assertEquals(3, data[0].length); assertEquals(1, data[1].length); assertEquals("abc", data[0][0]); assertEquals("def", data[0][1]); assertEquals("ghi,jkl", data[0][2]); assertEquals("def", data[1][0]); } public void testParse3() throws IOException { String[][] data = CSVUtils.parse("abc,\"def\nghi\"\njkl"); assertEquals(2, data.length); assertEquals(2, data[0].length); assertEquals(1, data[1].length); assertEquals("abc", data[0][0]); assertEquals("def\nghi", data[0][1]); assertEquals("jkl", data[1][0]); } public void testParse4() throws IOException { String[][] data = CSVUtils.parse("abc,\"def\\\\nghi\"\njkl"); assertEquals(2, data.length); assertEquals(2, data[0].length); assertEquals(1, data[1].length); assertEquals("abc", data[0][0]); // an escape char in quotes only escapes a delimiter, not itself assertEquals("def\\\\nghi", data[0][1]); assertEquals("jkl", data[1][0]); } public void testParse5() throws IOException { String[][] data = CSVUtils.parse("abc,def\\nghi\njkl"); assertEquals(2, data.length); assertEquals(2, data[0].length); assertEquals(1, data[1].length); assertEquals("abc", data[0][0]); assertEquals("def\\nghi", data[0][1]); assertEquals("jkl", data[1][0]); } public void testParse6() throws IOException { String[][] data = CSVUtils.parse(""); // default strategy is CSV, which ignores empty lines assertEquals(0, data.length); } public void testParse7() throws IOException { boolean io = false; try { CSVUtils.parse(null); } catch (IllegalArgumentException e) { io = true; } assertTrue(io); } public void testParseLine1() throws IOException { String[] data = CSVUtils.parseLine("abc,def,ghi"); assertEquals(3, data.length); assertEquals("abc", data[0]); assertEquals("def", data[1]); assertEquals("ghi", data[2]); } public void testParseLine2() throws IOException { String[] data = CSVUtils.parseLine("abc,def,ghi\n"); assertEquals(3, data.length); assertEquals("abc", data[0]); assertEquals("def", data[1]); assertEquals("ghi", data[2]); } public void testParseLine3() throws IOException { String[] data = CSVUtils.parseLine("abc,\"def,ghi\""); assertEquals(2, data.length); assertEquals("abc", data[0]); assertEquals("def,ghi", data[1]); } public void testParseLine4() throws IOException { String[] data = CSVUtils.parseLine("abc,\"def\nghi\""); assertEquals(2, data.length); assertEquals("abc", data[0]); assertEquals("def\nghi", data[1]); } public void testParseLine5() throws IOException { String[] data = CSVUtils.parseLine(""); assertEquals(0, data.length); // assertEquals("", data[0]); } public void testParseLine6() throws IOException { boolean io = false; try { CSVUtils.parseLine(null); } catch (IllegalArgumentException e) { io = true; } assertTrue(io); } public void testParseLine7() throws IOException { String[] res = CSVUtils.parseLine(""); assertNotNull(res); assertEquals(0, res.length); } } ./src/test/org/apache/commons/csv/CSVStrategyTest.java0000644000175000017500000000763211061274762023610 0ustar janpascaljanpascal/* * 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.commons.csv; import java.io.StringReader; import junit.framework.TestCase; /** * CSVStrategyTest * * The test are organized in three different sections: * The 'setter/getter' section, the lexer section and finally the strategy * section. In case a test fails, you should follow a top-down approach for * fixing a potential bug (its likely that the strategy itself fails if the lexer * has problems...). */ public class CSVStrategyTest extends TestCase { // ====================================================== // getters / setters // ====================================================== public void testGetSetCommentStart() { CSVParser parser = new CSVParser(new StringReader("hello world")); CSVStrategy strategy = parser.getStrategy(); strategy.setCommentStart('#'); assertEquals(strategy.getCommentStart(), '#'); strategy.setCommentStart('!'); assertEquals(strategy.getCommentStart(), '!'); } public void testGetSetEncapsulator() { CSVParser parser = new CSVParser(new StringReader("hello world")); CSVStrategy strategy = parser.getStrategy(); strategy.setEncapsulator('"'); assertEquals(strategy.getEncapsulator(), '"'); strategy.setEncapsulator('\''); assertEquals(strategy.getEncapsulator(), '\''); } public void testGetSetDelimiter() { CSVParser parser = new CSVParser(new StringReader("hello world")); CSVStrategy strategy = parser.getStrategy(); strategy.setDelimiter(';'); assertEquals(strategy.getDelimiter(), ';'); strategy.setDelimiter(','); assertEquals(strategy.getDelimiter(), ','); strategy.setDelimiter('\t'); assertEquals(strategy.getDelimiter(), '\t'); } public void testSetCSVStrategy() { CSVParser parser = new CSVParser(new StringReader("hello world")); CSVStrategy strategy = parser.getStrategy(); // default settings assertEquals(strategy.getDelimiter(), ','); assertEquals(strategy.getEncapsulator(), '"'); assertEquals(strategy.getCommentStart(), CSVStrategy.COMMENTS_DISABLED); assertEquals(true, strategy.getIgnoreLeadingWhitespaces()); assertEquals(false, strategy.getUnicodeEscapeInterpretation()); assertEquals(true, strategy.getIgnoreEmptyLines()); // explicit csv settings parser.setStrategy(CSVStrategy.DEFAULT_STRATEGY); assertEquals(strategy.getDelimiter(), ','); assertEquals(strategy.getEncapsulator(), '"'); assertEquals(strategy.getCommentStart(), CSVStrategy.COMMENTS_DISABLED); assertEquals(true, strategy.getIgnoreLeadingWhitespaces()); assertEquals(false, strategy.getUnicodeEscapeInterpretation()); assertEquals(true, strategy.getIgnoreEmptyLines()); } public void testSetExcelStrategy() { CSVStrategy strategy = CSVStrategy.EXCEL_STRATEGY; assertEquals(strategy.getDelimiter(), ','); assertEquals(strategy.getEncapsulator(), '"'); assertEquals(strategy.getCommentStart(), CSVStrategy.COMMENTS_DISABLED); assertEquals(false, strategy.getIgnoreLeadingWhitespaces()); assertEquals(false, strategy.getUnicodeEscapeInterpretation()); assertEquals(false, strategy.getIgnoreEmptyLines()); } } ./src/test/org/apache/commons/csv/CSVPrinterTest.java0000644000175000017500000000462611061274762023431 0ustar janpascaljanpascal/* * 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.commons.csv; import java.io.StringWriter; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * CSVPrinterTest */ public class CSVPrinterTest extends TestCase { String lineSeparator = System.getProperty("line.separator"); public void testPrinter1() { StringWriter sw = new StringWriter(); CSVPrinter printer = new CSVPrinter(sw); String[] line1 = {"a", "b"}; printer.println(line1); assertEquals("a,b" + lineSeparator, sw.toString()); } public void testPrinter2() { StringWriter sw = new StringWriter(); CSVPrinter printer = new CSVPrinter(sw); String[] line1 = {"a,b", "b"}; printer.println(line1); assertEquals("\"a,b\",b" + lineSeparator, sw.toString()); } public void testPrinter3() { StringWriter sw = new StringWriter(); CSVPrinter printer = new CSVPrinter(sw); String[] line1 = {"a, b", "b "}; printer.println(line1); assertEquals("\"a, b\",\"b \"" + lineSeparator, sw.toString()); } public void testExcelPrinter1() { StringWriter sw = new StringWriter(); CSVPrinter printer = new CSVPrinter(sw); printer.setStrategy(CSVStrategy.EXCEL_STRATEGY); String[] line1 = {"a", "b"}; printer.println(line1); assertEquals("a,b" + lineSeparator, sw.toString()); } public void testExcelPrinter2() { StringWriter sw = new StringWriter(); CSVPrinter printer = new CSVPrinter(sw); printer.setStrategy(CSVStrategy.EXCEL_STRATEGY); String[] line1 = {"a,b", "b"}; printer.println(line1); assertEquals("\"a,b\",b" + lineSeparator, sw.toString()); } } ./src/test/org/apache/commons/csv/CSVParserTest.java0000644000175000017500000004645411061274762023247 0ustar janpascaljanpascal/* * 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.commons.csv; import java.io.IOException; import java.io.Reader; import java.io.StringReader; import java.util.Arrays; import junit.framework.TestCase; /** * CSVParserTest * * The test are organized in three different sections: * The 'setter/getter' section, the lexer section and finally the parser * section. In case a test fails, you should follow a top-down approach for * fixing a potential bug (its likely that the parser itself fails if the lexer * has problems...). */ public class CSVParserTest extends TestCase { /** * TestCSVParser. */ class TestCSVParser extends CSVParser { /** * Test parser to investigate the type of the internal Token. * @param in a Reader */ TestCSVParser(Reader in) { super(in); } /** * Calls super.nextToken() and prints out a String representation of token * type and content. * @return String representation of token type and content * @throws IOException like {@link CSVParser#nextToken()} */ public String testNextToken() throws IOException { Token t = super.nextToken(); return Integer.toString(t.type) + ";" + t.content + ";"; } } // ====================================================== // lexer tests // ====================================================== // Single line (without comment) public void testNextToken1() throws IOException { String code = "abc,def, hijk, lmnop, qrst,uv ,wxy ,z , ,"; TestCSVParser parser = new TestCSVParser(new StringReader(code)); parser.setStrategy(CSVStrategy.DEFAULT_STRATEGY); assertEquals(CSVParser.TT_TOKEN + ";abc;", parser.testNextToken()); assertEquals(CSVParser.TT_TOKEN + ";def;", parser.testNextToken()); assertEquals(CSVParser.TT_TOKEN + ";hijk;", parser.testNextToken()); assertEquals(CSVParser.TT_TOKEN + ";lmnop;", parser.testNextToken()); assertEquals(CSVParser.TT_TOKEN + ";qrst;", parser.testNextToken()); assertEquals(CSVParser.TT_TOKEN + ";uv;", parser.testNextToken()); assertEquals(CSVParser.TT_TOKEN + ";wxy;", parser.testNextToken()); assertEquals(CSVParser.TT_TOKEN + ";z;", parser.testNextToken()); assertEquals(CSVParser.TT_TOKEN + ";;", parser.testNextToken()); assertEquals(CSVParser.TT_EOF + ";;", parser.testNextToken()); } // multiline including comments (and empty lines) public void testNextToken2() throws IOException { /* file: 1,2,3, * a,b x,c * * # this is a comment * d,e, * */ String code = "1,2,3,\na,b x,c\n#foo\n\nd,e,\n\n"; TestCSVParser parser = new TestCSVParser(new StringReader(code)); parser.getStrategy().setIgnoreEmptyLines(false); parser.setStrategy(CSVStrategy.DEFAULT_STRATEGY); parser.getStrategy().setCommentStart('#'); assertEquals(CSVParser.TT_TOKEN + ";1;", parser.testNextToken()); assertEquals(CSVParser.TT_TOKEN + ";2;", parser.testNextToken()); assertEquals(CSVParser.TT_TOKEN + ";3;", parser.testNextToken()); assertEquals(CSVParser.TT_EORECORD + ";;", parser.testNextToken()); assertEquals(CSVParser.TT_TOKEN + ";a;", parser.testNextToken()); assertEquals(CSVParser.TT_TOKEN + ";b x;", parser.testNextToken()); assertEquals(CSVParser.TT_EORECORD + ";c;", parser.testNextToken()); assertEquals(CSVParser.TT_EORECORD + ";;", parser.testNextToken()); assertEquals(CSVParser.TT_TOKEN + ";d;", parser.testNextToken()); assertEquals(CSVParser.TT_TOKEN + ";e;", parser.testNextToken()); assertEquals(CSVParser.TT_EORECORD + ";;", parser.testNextToken()); assertEquals(CSVParser.TT_EOF + ";;", parser.testNextToken()); assertEquals(CSVParser.TT_EOF + ";;", parser.testNextToken()); } // simple token with escaping public void testNextToken3() throws IOException { /* file: a,\,,b * \,, */ String code = "a,\\,,b\n\\,,"; TestCSVParser parser = new TestCSVParser(new StringReader(code)); parser.setStrategy(CSVStrategy.DEFAULT_STRATEGY); parser.getStrategy().setCommentStart('#'); assertEquals(CSVParser.TT_TOKEN + ";a;", parser.testNextToken()); // an unquoted single backslash is not an escape char assertEquals(CSVParser.TT_TOKEN + ";\\;", parser.testNextToken()); assertEquals(CSVParser.TT_TOKEN + ";;", parser.testNextToken()); assertEquals(CSVParser.TT_EORECORD + ";b;", parser.testNextToken()); // an unquoted single backslash is not an escape char assertEquals(CSVParser.TT_TOKEN + ";\\;", parser.testNextToken()); assertEquals(CSVParser.TT_TOKEN + ";;", parser.testNextToken()); assertEquals(CSVParser.TT_EOF + ";;", parser.testNextToken()); } // encapsulator tokenizer (sinle line) public void testNextToken4() throws IOException { /* file: a,"foo",b * a, " foo",b * a,"foo " ,b // whitespace after closing encapsulator * a, " foo " ,b */ String code = "a,\"foo\",b\na, \" foo\",b\na,\"foo \" ,b\na, \" foo \" ,b"; TestCSVParser parser = new TestCSVParser(new StringReader(code)); parser.setStrategy(CSVStrategy.DEFAULT_STRATEGY); assertEquals(CSVParser.TT_TOKEN + ";a;", parser.testNextToken()); assertEquals(CSVParser.TT_TOKEN + ";foo;", parser.testNextToken()); assertEquals(CSVParser.TT_EORECORD + ";b;", parser.testNextToken()); assertEquals(CSVParser.TT_TOKEN + ";a;", parser.testNextToken()); assertEquals(CSVParser.TT_TOKEN + "; foo;", parser.testNextToken()); assertEquals(CSVParser.TT_EORECORD + ";b;", parser.testNextToken()); assertEquals(CSVParser.TT_TOKEN + ";a;", parser.testNextToken()); assertEquals(CSVParser.TT_TOKEN + ";foo ;", parser.testNextToken()); assertEquals(CSVParser.TT_EORECORD + ";b;", parser.testNextToken()); assertEquals(CSVParser.TT_TOKEN + ";a;", parser.testNextToken()); assertEquals(CSVParser.TT_TOKEN + "; foo ;", parser.testNextToken()); // assertEquals(CSVParser.TT_EORECORD + ";b;", parser.testNextToken()); assertEquals(CSVParser.TT_EOF + ";b;", parser.testNextToken()); } // encapsulator tokenizer (multi line, delimiter in string) public void testNextToken5() throws IOException { String code = "a,\"foo\n\",b\n\"foo\n baar ,,,\"\n\"\n\t \n\""; TestCSVParser parser = new TestCSVParser(new StringReader(code)); parser.setStrategy(CSVStrategy.DEFAULT_STRATEGY); assertEquals(CSVParser.TT_TOKEN + ";a;", parser.testNextToken()); assertEquals(CSVParser.TT_TOKEN + ";foo\n;", parser.testNextToken()); assertEquals(CSVParser.TT_EORECORD + ";b;", parser.testNextToken()); assertEquals(CSVParser.TT_EORECORD + ";foo\n baar ,,,;", parser.testNextToken()); assertEquals(CSVParser.TT_EOF + ";\n\t \n;", parser.testNextToken()); } // change delimiters, comment, encapsulater public void testNextToken6() throws IOException { /* file: a;'b and \' more * ' * !comment;;;; * ;; */ String code = "a;'b and '' more\n'\n!comment;;;;\n;;"; TestCSVParser parser = new TestCSVParser(new StringReader(code)); parser.setStrategy( new CSVStrategy(';', '\'', '!') ); assertEquals(CSVParser.TT_TOKEN + ";a;", parser.testNextToken()); assertEquals( CSVParser.TT_EORECORD + ";b and ' more\n;", parser.testNextToken()); } // ====================================================== // parser tests // ====================================================== String code = "a,b,c,d\n" + " a , b , 1 2 \n" + "\"foo baar\", b,\n" // + " \"foo\n,,\n\"\",,\n\\\"\",d,e\n"; + " \"foo\n,,\n\"\",,\n\"\"\",d,e\n"; // changed to use standard CSV escaping String[][] res = { {"a", "b", "c", "d"}, {"a", "b", "1 2"}, {"foo baar", "b", ""}, {"foo\n,,\n\",,\n\"", "d", "e"} }; public void testGetLine() throws IOException { CSVParser parser = new CSVParser(new StringReader(code)); String[] tmp = null; for (int i = 0; i < res.length; i++) { tmp = parser.getLine(); assertTrue(Arrays.equals(res[i], tmp)); } tmp = parser.getLine(); assertTrue(tmp == null); } public void testNextValue() throws IOException { CSVParser parser = new CSVParser(new StringReader(code)); String tmp = null; for (int i = 0; i < res.length; i++) { for (int j = 0; j < res[i].length; j++) { tmp = parser.nextValue(); assertEquals(res[i][j], tmp); } } tmp = parser.nextValue(); assertTrue(tmp == null); } public void testGetAllValues() throws IOException { CSVParser parser = new CSVParser(new StringReader(code)); String[][] tmp = parser.getAllValues(); assertEquals(res.length, tmp.length); assertTrue(tmp.length > 0); for (int i = 0; i < res.length; i++) { assertTrue(Arrays.equals(res[i], tmp[i])); } } public void testExcelStrategy1() throws IOException { String code = "value1,value2,value3,value4\r\na,b,c,d\r\n x,,," + "\r\n\r\n\"\"\"hello\"\"\",\" \"\"world\"\"\",\"abc\ndef\",\r\n"; String[][] res = { {"value1", "value2", "value3", "value4"}, {"a", "b", "c", "d"}, {" x", "", "", ""}, {""}, {"\"hello\"", " \"world\"", "abc\ndef", ""} }; CSVParser parser = new CSVParser(new StringReader(code), CSVStrategy.EXCEL_STRATEGY); String[][] tmp = parser.getAllValues(); assertEquals(res.length, tmp.length); assertTrue(tmp.length > 0); for (int i = 0; i < res.length; i++) { assertTrue(Arrays.equals(res[i], tmp[i])); } } public void testExcelStrategy2() throws Exception { String code = "foo,baar\r\n\r\nhello,\r\n\r\nworld,\r\n"; String[][] res = { {"foo", "baar"}, {""}, {"hello", ""}, {""}, {"world", ""} }; CSVParser parser = new CSVParser(new StringReader(code)); parser.setStrategy(CSVStrategy.EXCEL_STRATEGY); String[][] tmp = parser.getAllValues(); assertEquals(res.length, tmp.length); assertTrue(tmp.length > 0); for (int i = 0; i < res.length; i++) { assertTrue(Arrays.equals(res[i], tmp[i])); } } public void testEndOfFileBehaviourExcel() throws Exception { String[] codes = { "hello,\r\n\r\nworld,\r\n", "hello,\r\n\r\nworld,", "hello,\r\n\r\nworld,\"\"\r\n", "hello,\r\n\r\nworld,\"\"", "hello,\r\n\r\nworld,\n", "hello,\r\n\r\nworld,", "hello,\r\n\r\nworld,\"\"\n", "hello,\r\n\r\nworld,\"\"" }; String[][] res = { {"hello", ""}, {""}, // ExcelStrategy does not ignore empty lines {"world", ""} }; String code; for (int codeIndex = 0; codeIndex < codes.length; codeIndex++) { code = codes[codeIndex]; CSVParser parser = new CSVParser(new StringReader(code)); parser.setStrategy(CSVStrategy.EXCEL_STRATEGY); String[][] tmp = parser.getAllValues(); assertEquals(res.length, tmp.length); assertTrue(tmp.length > 0); for (int i = 0; i < res.length; i++) { assertTrue(Arrays.equals(res[i], tmp[i])); } } } public void testEndOfFileBehaviorCSV() throws Exception { String[] codes = { "hello,\r\n\r\nworld,\r\n", "hello,\r\n\r\nworld,", "hello,\r\n\r\nworld,\"\"\r\n", "hello,\r\n\r\nworld,\"\"", "hello,\r\n\r\nworld,\n", "hello,\r\n\r\nworld,", "hello,\r\n\r\nworld,\"\"\n", "hello,\r\n\r\nworld,\"\"" }; String[][] res = { {"hello", ""}, // CSV Strategy ignores empty lines {"world", ""} }; String code; for (int codeIndex = 0; codeIndex < codes.length; codeIndex++) { code = codes[codeIndex]; CSVParser parser = new CSVParser(new StringReader(code)); parser.setStrategy(CSVStrategy.DEFAULT_STRATEGY); String[][] tmp = parser.getAllValues(); assertEquals(res.length, tmp.length); assertTrue(tmp.length > 0); for (int i = 0; i < res.length; i++) { assertTrue(Arrays.equals(res[i], tmp[i])); } } } public void testEmptyLineBehaviourExcel() throws Exception { String[] codes = { "hello,\r\n\r\n\r\n", "hello,\n\n\n", "hello,\"\"\r\n\r\n\r\n", "hello,\"\"\n\n\n" }; String[][] res = { {"hello", ""}, {""}, // ExcelStrategy does not ignore empty lines {""} }; String code; for (int codeIndex = 0; codeIndex < codes.length; codeIndex++) { code = codes[codeIndex]; CSVParser parser = new CSVParser(new StringReader(code)); parser.setStrategy(CSVStrategy.EXCEL_STRATEGY); String[][] tmp = parser.getAllValues(); assertEquals(res.length, tmp.length); assertTrue(tmp.length > 0); for (int i = 0; i < res.length; i++) { assertTrue(Arrays.equals(res[i], tmp[i])); } } } public void testEmptyLineBehaviourCSV() throws Exception { String[] codes = { "hello,\r\n\r\n\r\n", "hello,\n\n\n", "hello,\"\"\r\n\r\n\r\n", "hello,\"\"\n\n\n" }; String[][] res = { {"hello", ""} // CSV Strategy ignores empty lines }; String code; for (int codeIndex = 0; codeIndex < codes.length; codeIndex++) { code = codes[codeIndex]; CSVParser parser = new CSVParser(new StringReader(code)); parser.setStrategy(CSVStrategy.DEFAULT_STRATEGY); String[][] tmp = parser.getAllValues(); assertEquals(res.length, tmp.length); assertTrue(tmp.length > 0); for (int i = 0; i < res.length; i++) { assertTrue(Arrays.equals(res[i], tmp[i])); } } } public void OLDtestBackslashEscaping() throws IOException { String code = "one,two,three\n" + "on\\\"e,two\n" + "on\"e,two\n" + "one,\"tw\\\"o\"\n" + "one,\"t\\,wo\"\n" + "one,two,\"th,ree\"\n" + "\"a\\\\\"\n" + "a\\,b\n" + "\"a\\\\,b\""; String[][] res = { { "one", "two", "three" }, { "on\\\"e", "two" }, { "on\"e", "two" }, { "one", "tw\"o" }, { "one", "t\\,wo" }, // backslash in quotes only escapes a delimiter (",") { "one", "two", "th,ree" }, { "a\\\\" }, // backslash in quotes only escapes a delimiter (",") { "a\\", "b" }, // a backslash must be returnd { "a\\\\,b" } // backslash in quotes only escapes a delimiter (",") }; CSVParser parser = new CSVParser(new StringReader(code)); String[][] tmp = parser.getAllValues(); assertEquals(res.length, tmp.length); assertTrue(tmp.length > 0); for (int i = 0; i < res.length; i++) { assertTrue(Arrays.equals(res[i], tmp[i])); } } public void testBackslashEscaping() throws IOException { // To avoid confusion over the need for escaping chars in java code, // We will test with a forward slash as the escape char, and a single // quote as the encapsulator. String code = "one,two,three\n" // 0 + "'',''\n" // 1) empty encapsulators + "/',/'\n" // 2) single encapsulators + "'/'','/''\n" // 3) single encapsulators encapsulated via escape + "'''',''''\n" // 4) single encapsulators encapsulated via doubling + "/,,/,\n" // 5) separator escaped + "//,//\n" // 6) escape escaped + "'//','//'\n" // 7) escape escaped in encapsulation + " 8 , \"quoted \"\" /\" // string\" \n" // don't eat spaces + "9, /\n \n" // escaped newline + ""; String[][] res = { { "one", "two", "three" }, // 0 { "", "" }, // 1 { "'", "'" }, // 2 { "'", "'" }, // 3 { "'", "'" }, // 4 { ",", "," }, // 5 { "/", "/" }, // 6 { "/", "/" }, // 7 { " 8 ", " \"quoted \"\" \" / string\" " }, { "9", " \n " }, }; CSVStrategy strategy = new CSVStrategy(',','\'',CSVStrategy.COMMENTS_DISABLED,'/',false,false,true,true); CSVParser parser = new CSVParser(new StringReader(code), strategy); String[][] tmp = parser.getAllValues(); assertTrue(tmp.length > 0); for (int i = 0; i < res.length; i++) { assertTrue(Arrays.equals(res[i], tmp[i])); } } public void testUnicodeEscape() throws IOException { String code = "abc,\\u0070\\u0075\\u0062\\u006C\\u0069\\u0063"; CSVParser parser = new CSVParser(new StringReader(code)); parser.getStrategy().setUnicodeEscapeInterpretation(true); String[] data = parser.getLine(); assertEquals(2, data.length); assertEquals("abc", data[0]); assertEquals("public", data[1]); } public void testCarriageReturnLineFeedEndings() throws IOException { String code = "foo\r\nbaar,\r\nhello,world\r\n,kanu"; CSVParser parser = new CSVParser(new StringReader(code)); String[][] data = parser.getAllValues(); assertEquals(4, data.length); } public void testIgnoreEmptyLines() throws IOException { String code = "\nfoo,baar\n\r\n,\n\n,world\r\n\n"; //String code = "world\r\n\n"; //String code = "foo;baar\r\n\r\nhello;\r\n\r\nworld;\r\n"; CSVParser parser = new CSVParser(new StringReader(code)); String[][] data = parser.getAllValues(); assertEquals(3, data.length); } public void testLineTokenConsistency() throws IOException { String code = "\nfoo,baar\n\r\n,\n\n,world\r\n\n"; CSVParser parser = new CSVParser(new StringReader(code)); String[][] data = parser.getAllValues(); parser = new CSVParser(new StringReader(code)); CSVParser parser1 = new CSVParser(new StringReader(code)); for (int i = 0; i < data.length; i++) { assertTrue(Arrays.equals(parser1.getLine(), data[i])); for (int j = 0; j < data[i].length; j++) { assertEquals(parser.nextValue(), data[i][j]); } } } // From SANDBOX-153 public void testDelimiterIsWhitespace() throws IOException { String code = "one\ttwo\t\tfour \t five\t six"; TestCSVParser parser = new TestCSVParser(new StringReader(code)); parser.setStrategy(CSVStrategy.TDF_STRATEGY); assertEquals(CSVParser.TT_TOKEN + ";one;", parser.testNextToken()); assertEquals(CSVParser.TT_TOKEN + ";two;", parser.testNextToken()); assertEquals(CSVParser.TT_TOKEN + ";;", parser.testNextToken()); assertEquals(CSVParser.TT_TOKEN + ";four;", parser.testNextToken()); assertEquals(CSVParser.TT_TOKEN + ";five;", parser.testNextToken()); assertEquals(CSVParser.TT_EOF + ";six;", parser.testNextToken()); } } ./NOTICE.txt0000644000175000017500000000025411061274763013417 0ustar janpascaljanpascalApache Commons CSV Copyright 2005-2006 The Apache Software Foundation This product includes software developed by The Apache Software Foundation (http://www.apache.org/).