diff --git a/ebean-api/src/main/java/io/ebean/text/StringFormatter.java b/ebean-api/src/main/java/io/ebean/text/StringFormatter.java index a7aa2631b..613e97129 100644 --- a/ebean-api/src/main/java/io/ebean/text/StringFormatter.java +++ b/ebean-api/src/main/java/io/ebean/text/StringFormatter.java @@ -6,6 +6,7 @@ package io.ebean.text; * Basic interface to support CSV, JSON and XML processing. *

*/ +@FunctionalInterface public interface StringFormatter { /** diff --git a/ebean-api/src/main/java/io/ebean/text/StringParser.java b/ebean-api/src/main/java/io/ebean/text/StringParser.java index f76421944..4fe51abe8 100644 --- a/ebean-api/src/main/java/io/ebean/text/StringParser.java +++ b/ebean-api/src/main/java/io/ebean/text/StringParser.java @@ -5,6 +5,7 @@ package io.ebean.text; *

* Basic interface to support CSV, JSON and XML processing. */ +@FunctionalInterface public interface StringParser { /** diff --git a/ebean-csv-reader/pom.xml b/ebean-csv-reader/pom.xml index 147b10ea9..d9f69a67c 100644 --- a/ebean-csv-reader/pom.xml +++ b/ebean-csv-reader/pom.xml @@ -23,12 +23,14 @@ io.ebean ebean-api 13.8.2-SNAPSHOT + provided io.ebean ebean-core 13.8.2-SNAPSHOT + test diff --git a/ebean-csv-reader/src/main/java/io/ebean/csv/reader/CsvReader.java b/ebean-csv-reader/src/main/java/io/ebean/csv/reader/CsvReader.java index 1e40db770..98193e197 100644 --- a/ebean-csv-reader/src/main/java/io/ebean/csv/reader/CsvReader.java +++ b/ebean-csv-reader/src/main/java/io/ebean/csv/reader/CsvReader.java @@ -8,23 +8,15 @@ import io.ebean.text.StringParser; import io.ebean.text.TextException; import java.io.Reader; -import java.sql.Types; -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; -import java.util.Date; import java.util.List; -import java.util.Locale; /** * Implementation of the CsvReader */ public class CsvReader { - private static final TimeStringParser TIME_PARSER = new TimeStringParser(); - private final Database server; private final BeanType descriptor; @@ -37,11 +29,6 @@ public class CsvReader { private int logInfoFrequency = 1000; - private String defaultTimeFormat = "HH:mm:ss"; - private String defaultDateFormat = "yyyy-MM-dd"; - private String defaultTimestampFormat = "yyyy-MM-dd hh:mm:ss.fffffffff"; - private Locale defaultLocale = Locale.getDefault(); - /** * The batch size used for JDBC statement batching. */ @@ -54,102 +41,37 @@ public class CsvReader { this.descriptor = server.pluginApi().beanType(type); } - ////@Override - public void setDefaultLocale(Locale defaultLocale) { - this.defaultLocale = defaultLocale; - } - - ////@Override - public void setDefaultTimeFormat(String defaultTimeFormat) { - this.defaultTimeFormat = defaultTimeFormat; - } - - ////@Override - public void setDefaultDateFormat(String defaultDateFormat) { - this.defaultDateFormat = defaultDateFormat; - } - - ////@Override - public void setDefaultTimestampFormat(String defaultTimestampFormat) { - this.defaultTimestampFormat = defaultTimestampFormat; - } - - ////@Override public void setPersistBatchSize(int persistBatchSize) { this.persistBatchSize = persistBatchSize; } - ////@Override public void setIgnoreHeader() { setHasHeader(true, false); } - ////@Override public void setAddPropertiesFromHeader() { setHasHeader(true, true); } - //@Override public void setHasHeader(boolean hasHeader, boolean addPropertiesFromHeader) { this.hasHeader = hasHeader; this.addPropertiesFromHeader = addPropertiesFromHeader; } - //@Override public void setLogInfoFrequency(int logInfoFrequency) { this.logInfoFrequency = logInfoFrequency; } - //@Override public void addIgnore() { columnList.add(ignoreColumn); } - //@Override public void addProperty(String propertyName) { addProperty(propertyName, null); } - //@Override - public void addDateTime(String propertyName, String dateTimeFormat) { - addDateTime(propertyName, dateTimeFormat, Locale.getDefault()); - } - //@Override - public void addDateTime(String propertyName, String dateTimeFormat, Locale locale) { - ExpressionPath elProp = descriptor.expressionPath(propertyName); - if (dateTimeFormat == null) { - dateTimeFormat = getDefaultDateTimeFormat(elProp.jdbcType()); - } - - if (locale == null) { - locale = defaultLocale; - } - - SimpleDateFormat sdf = new SimpleDateFormat(dateTimeFormat, locale); - DateTimeParser parser = new DateTimeParser(sdf, dateTimeFormat, elProp); - - CsvColumn column = new CsvColumn(elProp, parser); - columnList.add(column); - } - - private String getDefaultDateTimeFormat(int jdbcType) { - switch (jdbcType) { - case Types.TIME: - return defaultTimeFormat; - case Types.DATE: - return defaultDateFormat; - case Types.TIMESTAMP: - return defaultTimestampFormat; - - default: - throw new RuntimeException("Expected java.sql.Types TIME,DATE or TIMESTAMP but got [" + jdbcType + "]"); - } - } - - //@Override public void addProperty(String propertyName, StringParser parser) { - ExpressionPath elProp = descriptor.expressionPath(propertyName); if (parser == null) { parser = elProp.stringParser(); @@ -158,15 +80,12 @@ public class CsvReader { columnList.add(column); } - //@Override public void process(Reader reader) throws Exception { DefaultCsvCallback callback = new DefaultCsvCallback<>(persistBatchSize, logInfoFrequency); process(reader, callback); } - //@Override public void process(Reader reader, CsvCallback callback) throws Exception { - if (reader == null) { throw new NullPointerException("reader is null?"); } @@ -224,43 +143,22 @@ public class CsvReader { } private void addPropertiesFromHeader(String[] line) { - for (String aLine : line) { - ExpressionPath elProp = descriptor.expressionPath(aLine); + for (String headerElement : line) { + ExpressionPath elProp = descriptor.expressionPath(headerElement); if (elProp == null) { - throw new TextException("Property [" + aLine + "] not found"); - } - - if (Types.TIME == elProp.jdbcType()) { - addProperty(aLine, TIME_PARSER); - - } else if (isDateTimeType(elProp.jdbcType())) { - addDateTime(aLine, null, null); - -// } else if (elProp.isAssocProperty()) { -// BeanPropertyAssocOne assocOne = (BeanPropertyAssocOne) elProp.beanProperty(); -// String idProp = assocOne.descriptor().idBinder().getIdProperty(); -// addProperty(aLine + "." + idProp); - } else { - addProperty(aLine); + throw new TextException("Property [" + headerElement + "] not found"); } + addProperty(headerElement); } } - private boolean isDateTimeType(int t) { - return t == Types.TIMESTAMP || t == Types.DATE || t == Types.TIME; - } - - @SuppressWarnings("unchecked") protected T buildBeanFromLineContent(int row, String[] line) { - try { T bean = descriptor.createBean(); - EntityBean entityBean = (EntityBean)bean; - + EntityBean entityBean = (EntityBean) bean; for (int columnPos = 0; columnPos < line.length; columnPos++) { convertAndSetColumn(columnPos, line[columnPos], entityBean); } - return bean; } catch (RuntimeException e) { @@ -270,13 +168,10 @@ public class CsvReader { } protected void convertAndSetColumn(int columnPos, String strValue, EntityBean bean) { - strValue = strValue.trim(); - if (strValue.isEmpty()) { return; } - CsvColumn c = columnList.get(columnPos); c.convertAndSet(strValue, bean); } @@ -309,7 +204,6 @@ public class CsvReader { * Convert the string to the appropriate value and set it to the bean. */ public void convertAndSet(String strValue, EntityBean bean) { - if (parser != null && path != null) { Object value = parser.parse(strValue); path.pathSet(bean, value); @@ -317,32 +211,4 @@ public class CsvReader { } } - /** - * A StringParser for converting custom date/time/datetime strings into - * appropriate java types (Date, Calendar, SQL Date, Time, Timestamp, JODA - * etc). - */ - private static class DateTimeParser implements StringParser { - - private final DateFormat dateFormat; - private final ExpressionPath path; - private final String format; - - DateTimeParser(DateFormat dateFormat, String format, ExpressionPath path) { - this.dateFormat = dateFormat; - this.path = path; - this.format = format; - } - - //@Override - public Object parse(String value) { - try { - Date dt = dateFormat.parse(value); - return path.parseDateTime(dt.getTime()); - } catch (ParseException e) { - throw new TextException("Error parsing [{}] using format[" + format + "]", value, e); - } - } - - } } diff --git a/ebean-csv-reader/src/test/java/io/ebean/csv/reader/CsvReaderTest.java b/ebean-csv-reader/src/test/java/io/ebean/csv/reader/CsvReaderTest.java index 642f453c0..8a871a62d 100644 --- a/ebean-csv-reader/src/test/java/io/ebean/csv/reader/CsvReaderTest.java +++ b/ebean-csv-reader/src/test/java/io/ebean/csv/reader/CsvReaderTest.java @@ -9,10 +9,13 @@ import org.junit.jupiter.api.Test; import java.io.Reader; import java.net.URL; -import java.util.Locale; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; class CsvReaderTest { + final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd-MMM-yyyy"); + @Test void test() throws Exception { @@ -29,15 +32,16 @@ class CsvReaderTest { Database database = DB.getDefault(); CsvReader csvReader = new CsvReader<>(database, Customer.class); - //CsvReader csvReader = DB.getDefault().createCsvReader(Customer.class); csvReader.setPersistBatchSize(2); csvReader.addIgnore(); - // csvReader.addProperty("id"); csvReader.addProperty("status"); csvReader.addProperty("name"); - csvReader.addDateTime("anniversary", "dd-MMM-yyyy", Locale.ENGLISH); + + // supplier a StringParser for custom date, time, dateTime formats + csvReader.addProperty("anniversary", (String content) -> LocalDate.parse(content, dateFormatter)); + // OLD WAY: csvReader.addDateTime("anniversary", "dd-MMM-yyyy", Locale.ENGLISH); csvReader.addProperty("billingAddress.line1"); csvReader.addProperty("billingAddress.city"); csvReader.addProperty("billingAddress.country.code");