mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Extract CsvReader - move DefaultCsvCallback and add module-info
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
package io.ebean.csv.reader;
|
||||
|
||||
import io.ebean.Database;
|
||||
|
||||
/**
|
||||
* Provides callback methods for customisation of CSV processing.
|
||||
* <p>
|
||||
* You can provide your own CsvCallback implementation to customise the CSV
|
||||
* processing. It is expected that the DefaultCsvCallback provides a good base
|
||||
* class that you can extend.
|
||||
*/
|
||||
public interface CsvCallback<T> {
|
||||
|
||||
/**
|
||||
* The processing is about to begin.
|
||||
* <p>
|
||||
* Typically the callback will create a transaction, set batch mode, batch
|
||||
* size etc.
|
||||
* </p>
|
||||
*/
|
||||
void begin(Database database);
|
||||
|
||||
/**
|
||||
* Read the header row.
|
||||
* <p>
|
||||
* This is only called if {@link CsvReader#setHasHeader(boolean, boolean)} has
|
||||
* been set to true.
|
||||
* </p>
|
||||
*
|
||||
* @param line the header line content.
|
||||
*/
|
||||
void readHeader(String[] line);
|
||||
|
||||
/**
|
||||
* Check that the row should be processed - return true to process the row or
|
||||
* false to ignore the row. Gives ability to handle bad data... empty rows etc
|
||||
* and ignore it rather than fail.
|
||||
*/
|
||||
boolean processLine(int row, String[] line);
|
||||
|
||||
/**
|
||||
* Called for each bean after it has been loaded from the CSV content.
|
||||
* <p>
|
||||
* This allows you to process the bean however you like.
|
||||
* </p>
|
||||
* <p>
|
||||
* When you use a CsvCallback the CsvReader *WILL NOT* create a transaction
|
||||
* and will not save the bean for you. You have complete control and must do
|
||||
* these things yourself (if that is want you want).
|
||||
* </p>
|
||||
*
|
||||
* @param row the index of the content being processed
|
||||
* @param line the content that has been used to load the bean
|
||||
* @param bean the entity bean after it has been loaded from the csv content
|
||||
*/
|
||||
void processBean(int row, String[] line, T bean);
|
||||
|
||||
/**
|
||||
* The processing has ended successfully.
|
||||
* <p>
|
||||
* Typically the callback will commit the transaction.
|
||||
* </p>
|
||||
*/
|
||||
void end(int row);
|
||||
|
||||
/**
|
||||
* The processing has ended due to an error.
|
||||
* <p>
|
||||
* This gives the callback the opportunity to rollback the transaction if one
|
||||
* was created.
|
||||
* </p>
|
||||
*
|
||||
* @param row the row that the error has occurred on
|
||||
* @param e the error that occurred
|
||||
*/
|
||||
void endWithError(int row, Exception e);
|
||||
|
||||
}
|
||||
+4
-8
@@ -1,4 +1,4 @@
|
||||
package io.ebeaninternal.server.text.csv;
|
||||
package io.ebean.csv.reader;
|
||||
|
||||
import io.ebean.Database;
|
||||
import io.ebean.bean.EntityBean;
|
||||
@@ -6,9 +6,6 @@ import io.ebean.plugin.BeanType;
|
||||
import io.ebean.plugin.ExpressionPath;
|
||||
import io.ebean.text.StringParser;
|
||||
import io.ebean.text.TextException;
|
||||
import io.ebean.text.csv.CsvCallback;
|
||||
import io.ebean.text.csv.CsvReader;
|
||||
import io.ebean.text.csv.DefaultCsvCallback;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.sql.Types;
|
||||
@@ -24,7 +21,7 @@ import java.util.Locale;
|
||||
/**
|
||||
* Implementation of the CsvReader
|
||||
*/
|
||||
public class TCsvReader<T> {//implements CsvReader<T> {
|
||||
public class CsvReader<T> {
|
||||
|
||||
private static final TimeStringParser TIME_PARSER = new TimeStringParser();
|
||||
|
||||
@@ -52,9 +49,9 @@ public class TCsvReader<T> {//implements CsvReader<T> {
|
||||
|
||||
private boolean addPropertiesFromHeader;
|
||||
|
||||
public TCsvReader(Database server, BeanType<T> descriptor) {
|
||||
public CsvReader(Database server, Class<T> type) {
|
||||
this.server = server;
|
||||
this.descriptor = descriptor;
|
||||
this.descriptor = server.pluginApi().beanType(type);
|
||||
}
|
||||
|
||||
////@Override
|
||||
@@ -229,7 +226,6 @@ public class TCsvReader<T> {//implements CsvReader<T> {
|
||||
private void addPropertiesFromHeader(String[] line) {
|
||||
for (String aLine : line) {
|
||||
ExpressionPath elProp = descriptor.expressionPath(aLine);
|
||||
//ElPropertyValue elProp = descriptor.elGetValue(aLine);
|
||||
if (elProp == null) {
|
||||
throw new TextException("Property [" + aLine + "] not found");
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package io.ebeaninternal.server.text.csv;
|
||||
package io.ebean.csv.reader;
|
||||
|
||||
// Original name: au.com.bytecode.opencsv.CSVReader
|
||||
// rbygrave: Made some Java Generics tweaks to remove warnings
|
||||
@@ -0,0 +1,197 @@
|
||||
package io.ebean.csv.reader;
|
||||
|
||||
import io.ebean.Database;
|
||||
import io.ebean.EbeanVersion;
|
||||
import io.ebean.Transaction;
|
||||
|
||||
import static java.lang.System.Logger.Level.DEBUG;
|
||||
import static java.lang.System.Logger.Level.INFO;
|
||||
|
||||
/**
|
||||
* Provides the default implementation of CsvCallback.
|
||||
* <p>
|
||||
* This handles transaction creation (if no current transaction existed) and
|
||||
* transaction commit or rollback on error.
|
||||
* </p>
|
||||
* <p>
|
||||
* For customising the processing you can extend this object and override the
|
||||
* appropriate methods.
|
||||
* </p>
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
public class DefaultCsvCallback<T> implements CsvCallback<T> {
|
||||
|
||||
private static final System.Logger log = EbeanVersion.log;
|
||||
|
||||
/**
|
||||
* The transaction to use (if not using CsvCallback).
|
||||
*/
|
||||
protected Transaction transaction;
|
||||
|
||||
/**
|
||||
* Flag set when we created the transaction.
|
||||
*/
|
||||
protected boolean createdTransaction;
|
||||
|
||||
/**
|
||||
* The EbeanServer used to save the beans.
|
||||
*/
|
||||
protected Database server;
|
||||
|
||||
/**
|
||||
* Used to log a message to indicate progress through large files.
|
||||
*/
|
||||
protected final int logInfoFrequency;
|
||||
|
||||
/**
|
||||
* The batch size used when saving the beans.
|
||||
*/
|
||||
protected final int persistBatchSize;
|
||||
|
||||
protected boolean getGeneratedKeys = true;
|
||||
/**
|
||||
* The time the process started.
|
||||
*/
|
||||
protected long startTime;
|
||||
|
||||
/**
|
||||
* The execution time of the process.
|
||||
*/
|
||||
protected long exeTime;
|
||||
|
||||
/**
|
||||
* Construct with a default batch size of 30 and logging info messages every
|
||||
* 1000 rows.
|
||||
*/
|
||||
public DefaultCsvCallback() {
|
||||
this(30, 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct with explicit batch size and logging info frequency.
|
||||
*/
|
||||
public DefaultCsvCallback(int persistBatchSize, int logInfoFrequency) {
|
||||
this.persistBatchSize = persistBatchSize;
|
||||
this.logInfoFrequency = logInfoFrequency;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a transaction if required.
|
||||
*/
|
||||
@Override
|
||||
public void begin(Database server) {
|
||||
this.server = server;
|
||||
this.startTime = System.currentTimeMillis();
|
||||
initTransactionIfRequired();
|
||||
}
|
||||
|
||||
/**
|
||||
* Override to read the heading line.
|
||||
* <p>
|
||||
* This is only called if {@link CsvReader#setHasHeader(boolean, boolean)} is
|
||||
* set to true.
|
||||
* <p>
|
||||
* By default this does nothing (effectively ignoring the heading).
|
||||
*/
|
||||
@Override
|
||||
public void readHeader(String[] line) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that the content is valid and return false if the row should be
|
||||
* ignored.
|
||||
* <p>
|
||||
* By default this just returns true.
|
||||
* </p>
|
||||
* <p>
|
||||
* Override this to add custom validation logic returning false if you want
|
||||
* the row to be ignored. For example, if all the content is empty return
|
||||
* false to ignore the row (rather than having the processing fail with some
|
||||
* error).
|
||||
* </p>
|
||||
*/
|
||||
@Override
|
||||
public boolean processLine(int row, String[] line) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will save the bean.
|
||||
* <p>
|
||||
* Override this method to customise the bean (set additional properties etc)
|
||||
* or to control the saving of other related beans (when you can't/don't want
|
||||
* to use Cascade.PERSIST etc).
|
||||
* </p>
|
||||
*/
|
||||
@Override
|
||||
public void processBean(int row, String[] line, T bean) {
|
||||
// assumes single bean or Cascade.PERSIST will save any
|
||||
// related beans (e.g. customer -> customer.billingAddress
|
||||
server.save(bean, transaction);
|
||||
if (logInfoFrequency > 0 && (row % logInfoFrequency == 0)) {
|
||||
log.log(DEBUG, "processed {0} rows", row);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit the transaction if one was created.
|
||||
*/
|
||||
@Override
|
||||
public void end(int row) {
|
||||
commitTransactionIfCreated();
|
||||
exeTime = System.currentTimeMillis() - startTime;
|
||||
log.log(INFO, "Csv finished, rows[{0}] exeMillis[{1}]", row, exeTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rollback the transaction if one was created.
|
||||
*/
|
||||
@Override
|
||||
public void endWithError(int row, Exception e) {
|
||||
rollbackTransactionIfCreated(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a transaction if one is not already active and set its batch mode
|
||||
* and batch size.
|
||||
*/
|
||||
protected void initTransactionIfRequired() {
|
||||
transaction = server.currentTransaction();
|
||||
if (transaction == null || !transaction.isActive()) {
|
||||
transaction = server.beginTransaction();
|
||||
createdTransaction = true;
|
||||
if (persistBatchSize > 1) {
|
||||
transaction.setBatchMode(true);
|
||||
transaction.setBatchSize(persistBatchSize);
|
||||
transaction.setGetGeneratedKeys(getGeneratedKeys);
|
||||
} else {
|
||||
// explicitly turn off JDBC batching in case
|
||||
// is has been turned on globally
|
||||
transaction.setBatchMode(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If we created a transaction commit it. We have successfully processed all
|
||||
* the rows.
|
||||
*/
|
||||
protected void commitTransactionIfCreated() {
|
||||
if (createdTransaction) {
|
||||
transaction.commit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rollback the transaction if we where not successful in processing all the
|
||||
* rows.
|
||||
*/
|
||||
protected void rollbackTransactionIfCreated(Throwable e) {
|
||||
if (createdTransaction) {
|
||||
transaction.rollback(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package io.ebeaninternal.server.text.csv;
|
||||
package io.ebean.csv.reader;
|
||||
|
||||
import io.ebean.text.StringParser;
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
module io.ebean.csv.reader {
|
||||
|
||||
requires io.ebean.api;
|
||||
|
||||
exports io.ebean.csv.reader;
|
||||
}
|
||||
Reference in New Issue
Block a user