/** * Licensed to JumpMind Inc under one or more contributor * license agreements. See the NOTICE file distributed * with this work for additional information regarding * copyright ownership. JumpMind Inc licenses this file * to you under the GNU General Public License, version 3.0 (GPLv3) * (the "License"); you may not use this file except in compliance * with the License. * * You should have received a copy of the GNU General Public License, * version 3.0 (GPLv3) along with this library; if not, see * <http://www.gnu.org/licenses/>. * * 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.jumpmind.symmetric.io.data.reader; import java.io.BufferedReader; import java.io.File; import java.io.InputStream; import java.io.Reader; import java.io.StringReader; import java.util.HashMap; import java.util.Map; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.jumpmind.db.model.Table; import org.jumpmind.db.util.BinaryEncoding; import org.jumpmind.symmetric.io.data.Batch; import org.jumpmind.symmetric.io.data.CsvData; import org.jumpmind.symmetric.io.data.DataContext; import org.jumpmind.symmetric.io.data.DataEventType; import org.jumpmind.symmetric.io.data.IDataReader; import org.jumpmind.util.Statistics; /** * A data reader that knows it will be reading a single batch and a single * table. */ abstract public class AbstractTableDataReader extends AbstractDataReader implements IDataReader { public static final String CTX_LINE_NUMBER = AbstractTableDataReader.class.getSimpleName() + ".lineNumber"; protected Reader reader; protected Statistics statistics = new Statistics(); protected DataContext context; protected Batch batch; protected Table table; protected int lineNumber = 0; protected boolean readDataBeforeTable = false; protected boolean readingBatch = false; protected boolean readingTable = false; public AbstractTableDataReader(Batch batch, String catalogName, String schemaName, String tableName, StringBuilder input) { this(batch, catalogName, schemaName, tableName, new BufferedReader(new StringReader( input.toString()))); } public AbstractTableDataReader(Batch batch, String catalogName, String schemaName, String tableName, InputStream is) { this(batch, catalogName, schemaName, tableName, toReader(is)); } public AbstractTableDataReader(Batch batch, String catalogName, String schemaName, String tableName, String input) { this(batch, catalogName, schemaName, tableName, new BufferedReader(new StringReader(input))); } public AbstractTableDataReader(Batch batch, String catalogName, String schemaName, String tableName, File file) { this(batch, catalogName, schemaName, toTableName(tableName, file), toReader(file)); } public AbstractTableDataReader(Batch batch, String catalogName, String schemaName, String tableName, Reader reader) { this.reader = reader; this.batch = batch; if (StringUtils.isNotBlank(tableName)) { this.table = new Table(catalogName, schemaName, tableName); } } public AbstractTableDataReader(BinaryEncoding binaryEncoding, String catalogName, String schemaName, String tableName, Reader reader) { this(toBatch(binaryEncoding), catalogName, schemaName, tableName, reader); } public AbstractTableDataReader(BinaryEncoding binaryEncoding, String catalogName, String schemaName, String tableName, InputStream is) { this(toBatch(binaryEncoding), catalogName, schemaName, tableName, is); } protected static String toTableName(String tableName, File file) { if (StringUtils.isBlank(tableName)) { tableName = file.getName(); if (tableName.lastIndexOf(".") > 0) { tableName = tableName.substring(0, tableName.lastIndexOf(".")); } } return tableName; } public void open(DataContext context) { this.lineNumber = 0; this.context = context; this.init(); } abstract protected void init(); abstract protected CsvData readNext(); abstract protected void finish(); protected CsvData buildCsvData(String[] tokens, DataEventType dml) { statistics.increment(DataReaderStatistics.READ_BYTE_COUNT, logDebugAndCountBytes(tokens)); return new CsvData(dml, tokens); } public CsvData nextData() { if (readDataBeforeTable || readingTable) { CsvData data = readNext(); if (data != null) { lineNumber++; context.put(CTX_LINE_NUMBER, lineNumber); return data; } else { batch.setComplete(true); } } return null; } public Batch nextBatch() { if (!readingBatch) { readingBatch = true; return batch; } else { return null; } } public Table nextTable() { if (!readingTable) { readingTable = true; return table; } else { return null; } } public void close() { IOUtils.closeQuietly(reader); finish(); } public Map<Batch, Statistics> getStatistics() { Map<Batch, Statistics> map = new HashMap<Batch, Statistics>(1); map.put(batch, statistics); return map; } }