/*
* GeotoolKit - An Open source Java GIS Toolkit
* http://geotoolkit.org
*
* (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.geotoolkit.data.shapefile;
import java.io.File;
import java.io.FileOutputStream;
import java.nio.charset.Charset;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.geotoolkit.ShapeTestData;
import org.geotoolkit.data.dbf.DbaseFieldFormatter;
import org.geotoolkit.data.dbf.DbaseFileHeader;
import org.geotoolkit.data.dbf.DbaseFileReader;
import org.geotoolkit.data.dbf.DbaseFileWriter;
import org.geotoolkit.data.shapefile.lock.AccessManager;
import org.geotoolkit.data.shapefile.lock.ShpFiles;
import org.junit.After;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
/**
*
* @version $Id$
* @author Ian Schneider
* @author James Macgill
* @module
*/
public class DbaseFileTest extends AbstractTestCaseSupport {
private static final Logger LOGGER = org.apache.sis.util.logging.Logging
.getLogger("org.geotoolkit.data.shapefile");
static final String TEST_FILE = "shapes/statepop.dbf";
private DbaseFileReader dbf = null;
private ShpFiles shpFiles;
@Before
public void setUp() throws Exception {
shpFiles = new ShpFiles(ShapeTestData.url(TEST_FILE));
final AccessManager locker = shpFiles.createLocker();
dbf = locker.getDBFReader(false, ShapefileFeatureStore.DEFAULT_STRING_CHARSET);
}
@Test
public void testNumberofColsLoaded() {
assertEquals("Number of attributes found incorect", 252, dbf
.getHeader().getNumFields());
}
@Override
@After
public void tearDown() throws Exception {
dbf.close();
super.tearDown();
}
@Test
public void testNumberofRowsLoaded() {
assertEquals("Number of rows", 49, dbf.getHeader().getNumRecords());
}
@Test
public void testDataLoaded() throws Exception {
Object[] attrs = new Object[dbf.getHeader().getNumFields()];
dbf.next().readAll(attrs);
assertEquals("Value of Column 0 is wrong", "Illinois", attrs[0]);
assertEquals("Value of Column 4 is wrong", 143986.61,
((Double) attrs[4]).doubleValue(), 0.001);
}
@Test
public void testRowVsEntry() throws Exception {
Object[] attrs = new Object[dbf.getHeader().getNumFields()];
final AccessManager locker = shpFiles.createLocker();
DbaseFileReader dbf2 = locker.getDBFReader(false, ShapefileFeatureStore.DEFAULT_STRING_CHARSET);
while (dbf.hasNext()) {
final DbaseFileReader.Row r1 = dbf.next();
final DbaseFileReader.Row r2 = dbf2.next();
r1.readAll(attrs);
for (int i = 0, ii = attrs.length; i < ii; i++) {
assertNotNull(attrs[i]);
assertNotNull(r2.read(i));
assertEquals(attrs[i], r2.read(i));
}
}
dbf2.close();
}
@Test
public void testHeader() throws Exception {
DbaseFileHeader header = new DbaseFileHeader();
Level before = LOGGER.getLevel();
try {
LOGGER.setLevel(Level.INFO);
header.addColumn("emptyString", 'C', 20, 0);
header.addColumn("emptyInt", 'N', 20, 0);
header.addColumn("emptyDouble", 'N', 20, 5);
header.addColumn("emptyFloat", 'F', 20, 5);
header.addColumn("emptyLogical", 'L', 1, 0);
header.addColumn("emptyDate", 'D', 20, 0);
int length = header.getRecordLength();
header.removeColumn("emptyDate");
assertTrue(length != header.getRecordLength());
header.addColumn("emptyDate", 'D', 20, 0);
assertTrue(length == header.getRecordLength());
header.removeColumn("billy");
assertTrue(length == header.getRecordLength());
} finally {
LOGGER.setLevel(before);
}
}
@Test
public void testAddColumn() throws Exception {
DbaseFileHeader header = new DbaseFileHeader();
Level before = LOGGER.getLevel();
try {
LOGGER.setLevel(Level.INFO);
header.addColumn("emptyInt", 'N', 9, 0);
assertSame(Integer.class, header.getFieldClass(0));
assertEquals(9, header.getFieldLength(0));
header.addColumn("emptyString", 'C', 20, 0);
assertSame(String.class, header.getFieldClass(1));
assertEquals(20, header.getFieldLength(1));
} finally {
LOGGER.setLevel(before);
}
}
@Test
public void testEmptyFields() throws Exception {
DbaseFileHeader header = new DbaseFileHeader();
header.addColumn("emptyString", 'C', 20, 0);
header.addColumn("emptyInt", 'N', 20, 0);
header.addColumn("emptyDouble", 'N', 20, 5);
header.addColumn("emptyFloat", 'F', 20, 5);
header.addColumn("emptyLogical", 'L', 1, 0);
header.addColumn("emptyDate", 'D', 20, 0);
header.setNumRecords(20);
File f = new File(System.getProperty("java.io.tmpdir"),
"scratchDBF.dbf");
f.deleteOnExit();
FileOutputStream fout = new FileOutputStream(f);
DbaseFileWriter dbf = new DbaseFileWriter(header, fout.getChannel(), Charset.defaultCharset());
for (int i = 0; i < header.getNumRecords(); i++) {
dbf.write(new Object[]{String.valueOf(900+i),null,null,null,null,null});
}
dbf.close();
final ShpFiles tempShpFiles = new ShpFiles(f);
final AccessManager locker = tempShpFiles.createLocker();
DbaseFileReader r = locker.getDBFReader(false, ShapefileFeatureStore.DEFAULT_STRING_CHARSET);
int cnt = 0;
while (r.hasNext()) {
cnt++;
Object[] o = r.next().readAll(null);
assertTrue(o.length == r.getHeader().getNumFields());
}
assertEquals("Bad number of records", cnt, 20);
r.close(); // make sure the channel is closed
f.delete();
}
@Test
public void testFieldFormatter() throws Exception {
DbaseFieldFormatter formatter = new DbaseFieldFormatter(Charset.defaultCharset());
String stringWithInternationChars = "hello " + '\u20ac';
// if (verbose) {
// System.out.println(stringWithInternationChars);
// }
String formattedString = formatter.getFieldString(10,
stringWithInternationChars);
assertEquals(" ".getBytes().length,
formattedString.getBytes().length);
// test when the string is too big.
stringWithInternationChars = '\u20ac' + "1234567890";
formattedString = formatter.getFieldString(10,
stringWithInternationChars);
assertEquals(" ".getBytes().length,
formattedString.getBytes().length);
}
}