package comeon.core.extmetadata; import au.com.bytecode.opencsv.CSVReader; import au.com.bytecode.opencsv.bean.MappingStrategy; import net.sf.cglib.beans.BeanGenerator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; import java.io.IOException; import java.util.Arrays; import java.util.LinkedList; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; final class CGLibMappingStrategy implements MappingStrategy<Object> { private static final Logger LOGGER = LoggerFactory.getLogger(CGLibMappingStrategy.class); private Class<?> clazz; private final List<Optional<PropertyDescriptor>> properties; public CGLibMappingStrategy() { this.properties = new LinkedList<>(); } @Override public PropertyDescriptor findDescriptor(final int col) throws IntrospectionException { return properties.get(col).orElseThrow(() -> new IntrospectionException(String.format("Missing descriptor for column %1$s", col))); } @Override public Object createBean() throws InstantiationException, IllegalAccessException { return clazz.newInstance(); } @Override public void captureHeader(final CSVReader reader) throws IOException { final String[] columns = reader.readNext(); properties.clear(); final BeanGenerator generator = new BeanGenerator(); Arrays.stream(columns).forEach(c -> generator.addProperty(c, String.class)); this.clazz = (Class<?>) generator.createClass(); this.properties.addAll(Arrays.stream(columns).map(this::buildPropertyDescriptor).collect(Collectors.toList())); } private Optional<PropertyDescriptor> buildPropertyDescriptor(final String column) { try { return Optional.of(new PropertyDescriptor(column, clazz)); } catch (final IntrospectionException e) { LOGGER.warn("Could not build PropertyDescriptor for column {}", column, e); return Optional.empty(); } } }