src/main/java/org/embulk/parser/jsonpath/ColumnVisitorImpl.java in embulk-parser-jsonpath-0.1.3 vs src/main/java/org/embulk/parser/jsonpath/ColumnVisitorImpl.java in embulk-parser-jsonpath-0.2.0

- old
+ new

@@ -1,31 +1,46 @@ package org.embulk.parser.jsonpath; +import com.fasterxml.jackson.databind.JsonNode; import com.google.common.base.Optional; +import com.google.common.collect.ImmutableList; import org.embulk.parser.jsonpath.JsonpathParserPlugin.PluginTask; import org.embulk.parser.jsonpath.JsonpathParserPlugin.TypecastColumnOption; - import org.embulk.spi.Column; import org.embulk.spi.ColumnConfig; import org.embulk.spi.ColumnVisitor; import org.embulk.spi.PageBuilder; import org.embulk.spi.Schema; import org.embulk.spi.SchemaConfig; +import org.embulk.spi.json.JsonParseException; +import org.embulk.spi.json.JsonParser; import org.embulk.spi.time.Timestamp; import org.embulk.spi.time.TimestampParser; import org.msgpack.core.MessageTypeException; -import org.msgpack.value.Value; -public class ColumnVisitorImpl implements ColumnVisitor +import java.util.List; + +import static java.lang.String.format; +import static org.msgpack.value.ValueFactory.newBoolean; +import static org.msgpack.value.ValueFactory.newFloat; +import static org.msgpack.value.ValueFactory.newInteger; +import static org.msgpack.value.ValueFactory.newString; + +public class ColumnVisitorImpl + implements ColumnVisitor { + private static final JsonParser JSON_PARSER = new JsonParser(); + private static final List<String> BOOL_TRUE_STRINGS = ImmutableList.of("true", "1", "yes", "on", "y", "t"); + private static final List<String> BOOL_FALSE_STRINGS = ImmutableList.of("false", "0", "no", "off", "n", "f"); + protected final PluginTask task; protected final Schema schema; protected final PageBuilder pageBuilder; protected final TimestampParser[] timestampParsers; protected final Boolean[] autoTypecasts; - protected Value value; + protected JsonNode value; public ColumnVisitorImpl(PluginTask task, Schema schema, PageBuilder pageBuilder, TimestampParser[] timestampParsers) { this.task = task; this.schema = schema; @@ -39,58 +54,75 @@ { for (Column column : schema.getColumns()) { this.autoTypecasts[column.getIndex()] = task.getDefaultTypecast(); } -// Optional<SchemaConfig> schemaConfig = task.getColumns(); - SchemaConfig schemaConfig = task.getSchemaConfig(); + // typecast option supports `columns` only. + Optional<SchemaConfig> schemaConfig = task.getSchemaConfig(); -// if (schemaConfig.isPresent()) { - for (ColumnConfig columnConfig : schemaConfig.getColumns()) { - TypecastColumnOption columnOption = columnConfig.getOption().loadConfig(TypecastColumnOption.class); - Boolean autoTypecast = columnOption.getTypecast().or(task.getDefaultTypecast()); - Column column = schema.lookupColumn(columnConfig.getName()); - this.autoTypecasts[column.getIndex()] = autoTypecast; + if (schemaConfig.isPresent()) { + for (ColumnConfig columnConfig : schemaConfig.get().getColumns()) { + TypecastColumnOption columnOption = columnConfig.getOption().loadConfig(TypecastColumnOption.class); + Boolean autoTypecast = columnOption.getTypecast().or(task.getDefaultTypecast()); + Column column = schema.lookupColumn(columnConfig.getName()); + this.autoTypecasts[column.getIndex()] = autoTypecast; + } } -// } } - public void setValue(Value value) + public void setValue(JsonNode value) { this.value = value; } @Override public void booleanColumn(Column column) { if (isNil(value)) { pageBuilder.setNull(column); + return; } + + final boolean val; + if (value.isBoolean()) { + val = value.asBoolean(); + } else { - try { - boolean booleanValue = autoTypecasts[column.getIndex()] ? ColumnCaster.asBoolean(value) : value.asBooleanValue().getBoolean(); - pageBuilder.setBoolean(column, booleanValue); + String stringValue = valueAsString().toLowerCase(); + if (BOOL_TRUE_STRINGS.contains(stringValue)) { + val = true; } - catch (MessageTypeException e) { - throw new JsonRecordValidateException(String.format("failed to get \"%s\" as Boolean", value), e); + else if (BOOL_FALSE_STRINGS.contains(stringValue)) { + val = false; } + else { + throw new JsonRecordValidateException(format("can not convert '%s' to Boolean", value)); + } } + + try { + boolean booleanValue = autoTypecasts[column.getIndex()] ? ColumnCaster.asBoolean(newBoolean(val)) : val; + pageBuilder.setBoolean(column, booleanValue); + } + catch (MessageTypeException e) { + throw new JsonRecordValidateException(format("failed to get \"%s\" as Boolean", value), e); + } } @Override public void longColumn(Column column) { if (isNil(value)) { pageBuilder.setNull(column); } else { try { - long longValue = autoTypecasts[column.getIndex()] ? ColumnCaster.asLong(value) : value.asIntegerValue().toLong(); + long longValue = autoTypecasts[column.getIndex()] ? ColumnCaster.asLong(newInteger(value.asLong())) : value.asLong(); pageBuilder.setLong(column, longValue); } catch (MessageTypeException e) { - throw new JsonRecordValidateException(String.format("failed to get \"%s\" as Long", value), e); + throw new JsonRecordValidateException(format("failed to get \"%s\" as Long", value), e); } } } @Override @@ -99,15 +131,15 @@ if (isNil(value)) { pageBuilder.setNull(column); } else { try { - double doubleValue = autoTypecasts[column.getIndex()] ? ColumnCaster.asDouble(value) : value.asFloatValue().toDouble(); + double doubleValue = autoTypecasts[column.getIndex()] ? ColumnCaster.asDouble(newFloat(value.asDouble())) : value.asDouble(); pageBuilder.setDouble(column, doubleValue); } catch (MessageTypeException e) { - throw new JsonRecordValidateException(String.format("failed get \"%s\" as Double", value), e); + throw new JsonRecordValidateException(format("failed get \"%s\" as Double", value), e); } } } @Override @@ -115,16 +147,17 @@ { if (isNil(value)) { pageBuilder.setNull(column); } else { + final String stringValue = valueAsString(); try { - String string = autoTypecasts[column.getIndex()] ? ColumnCaster.asString(value) : value.asStringValue().toString(); + String string = autoTypecasts[column.getIndex()] ? ColumnCaster.asString(newString(stringValue)) : stringValue; pageBuilder.setString(column, string); } catch (MessageTypeException e) { - throw new JsonRecordValidateException(String.format("failed to get \"%s\" as String", value), e); + throw new JsonRecordValidateException(format("failed to get \"%s\" as String", value), e); } } } @Override @@ -133,15 +166,15 @@ if (isNil(value)) { pageBuilder.setNull(column); } else { try { - Timestamp timestamp = ColumnCaster.asTimestamp(value, timestampParsers[column.getIndex()]); + Timestamp timestamp = ColumnCaster.asTimestamp(newString(value.asText()), timestampParsers[column.getIndex()]); pageBuilder.setTimestamp(column, timestamp); } catch (MessageTypeException e) { - throw new JsonRecordValidateException(String.format("failed to get \"%s\" as Timestamp", value), e); + throw new JsonRecordValidateException(format("failed to get \"%s\" as Timestamp", value), e); } } } @Override @@ -150,18 +183,23 @@ if (isNil(value)) { pageBuilder.setNull(column); } else { try { - pageBuilder.setJson(column, value); + pageBuilder.setJson(column, JSON_PARSER.parse(valueAsString())); } - catch (MessageTypeException e) { - throw new JsonRecordValidateException(String.format("failed to get \"%s\" as Json", value), e); + catch (MessageTypeException | JsonParseException e) { + throw new JsonRecordValidateException(format("failed to get \"%s\" as Json", value), e); } } } - protected boolean isNil(Value v) + protected boolean isNil(JsonNode v) { - return v == null || v.isNilValue(); + return v == null || v.isNull(); + } + + private String valueAsString() + { + return value.isTextual() ? value.asText() : value.toString(); } }