package org.embulk.parser.poi_excel.visitor; import java.text.MessageFormat; import java.util.Collection; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; import java.util.TreeSet; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Color; import org.embulk.parser.poi_excel.bean.PoiExcelColumnBean; import org.embulk.parser.poi_excel.visitor.embulk.CellVisitor; import org.embulk.spi.Column; import org.embulk.spi.PageBuilder; import org.embulk.spi.type.StringType; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; public abstract class AbstractPoiExcelCellAttributeVisitor { protected final PoiExcelVisitorValue visitorValue; protected final PageBuilder pageBuilder; public AbstractPoiExcelCellAttributeVisitor(PoiExcelVisitorValue visitorValue) { this.visitorValue = visitorValue; this.pageBuilder = visitorValue.getPageBuilder(); } public void visit(PoiExcelColumnBean bean, Cell cell, CellVisitor visitor) { A source = getAttributeSource(bean, cell); if (source == null) { Column column = bean.getColumn(); pageBuilder.setNull(column); return; } String suffix = bean.getValueTypeSuffix(); if (suffix != null) { visitKey(bean, suffix, cell, source, visitor); } else { visitJson(bean, cell, source, visitor); } } protected abstract A getAttributeSource(PoiExcelColumnBean bean, Cell cell); private void visitKey(PoiExcelColumnBean bean, String key, Cell cell, A source, CellVisitor visitor) { Column column = bean.getColumn(); Object value = getAttributeValue(column, cell, source, key); if (value == null) { pageBuilder.setNull(column); } else if (value instanceof String) { visitor.visitCellValueString(column, source, (String) value); } else if (value instanceof Long) { visitor.visitValueLong(column, source, (Long) value); } else if (value instanceof Boolean) { visitor.visitCellValueBoolean(column, source, (Boolean) value); } else if (value instanceof Double) { visitor.visitCellValueNumeric(column, source, (Double) value); } else if (value instanceof Map) { visitor.visitCellValueString(column, source, convertJsonString(value)); } else { throw new IllegalStateException(MessageFormat.format("unsupported conversion. type={0}, value={1}", value .getClass().getName(), value)); } } private void visitJson(PoiExcelColumnBean bean, Cell cell, A source, CellVisitor visitor) { Column column = bean.getColumn(); Map result; List list = bean.getAttributeName(); if (!list.isEmpty()) { result = getSpecifiedValues(column, cell, source, list); } else { result = getAllValues(column, cell, source); } String json = convertJsonString(result); visitor.visitCellValueString(column, cell, json); } protected final Map getSpecifiedValues(Column column, Cell cell, A source, List keyList) { Map result = new LinkedHashMap<>(); for (String key : keyList) { Object value = getAttributeValue(column, cell, source, key); result.put(key, value); } return result; } protected final Map getAllValues(Column column, Cell cell, A source) { Map result = new TreeMap<>(); Collection keys = getAttributeSupplierMap().keySet(); for (String key : keys) { if (acceptKey(key)) { Object value = getAttributeValue(column, cell, source, key); result.put(key, value); } } return result; } protected boolean acceptKey(String key) { return true; } protected final Object getAttributeValue(Column column, Cell cell, A source, String key) { Map> map = getAttributeSupplierMap(); AttributeSupplier supplier = map.get(key.toLowerCase()); if (supplier == null) { throw new UnsupportedOperationException(MessageFormat.format( "unsupported attribute name={0}, choose in {1}", key, new TreeSet<>(map.keySet()))); } Object value = supplier.get(column, cell, source); if (value instanceof Color) { int rgb = PoiExcelColorVisitor.getRGB((Color) value); if (rgb < 0) { return null; } if (column.getType() instanceof StringType) { value = String.format("%06x", rgb); } else { value = (long) rgb; } } return value; } // @FunctionalInterface protected static interface AttributeSupplier { public Object get(Column column, Cell cell, A source); } protected abstract Map> getAttributeSupplierMap(); protected final String convertJsonString(Object result) { try { ObjectMapper mapper = new ObjectMapper(); return mapper.writeValueAsString(result); } catch (JsonProcessingException e) { throw new RuntimeException(e); } } }