package org.molgenis.data.excel;
import com.google.common.collect.Lists;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.molgenis.data.Entity;
import org.molgenis.data.MolgenisInvalidFormatException;
import org.molgenis.data.Repository;
import org.molgenis.data.meta.model.Attribute;
import org.molgenis.data.meta.model.AttributeFactory;
import org.molgenis.data.meta.model.EntityType;
import org.molgenis.data.meta.model.EntityTypeFactory;
import org.molgenis.data.processor.CellProcessor;
import org.molgenis.data.processor.TrimProcessor;
import org.molgenis.data.support.AbstractWritable.AttributeWriteMode;
import org.molgenis.data.support.FileRepositoryCollection;
import org.molgenis.data.support.GenericImporterExtensions;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.*;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;
/**
* Read an excel file and iterate through the sheets.
* <p>
* A sheet is exposed as a {@link org.molgenis.data.Repository} with the sheetname as the Repository name
*/
public class ExcelRepositoryCollection extends FileRepositoryCollection
{
public static final String NAME = "EXCEL";
private final String name;
private final Workbook workbook;
private EntityTypeFactory entityTypeFactory;
private AttributeFactory attributeFactory;
public ExcelRepositoryCollection(File file) throws IOException, MolgenisInvalidFormatException
{
this(file, new TrimProcessor());
}
public ExcelRepositoryCollection(File file, CellProcessor... cellProcessors)
throws IOException, MolgenisInvalidFormatException
{
this(file.getName(), new FileInputStream(file), cellProcessors);
}
public ExcelRepositoryCollection(String name, InputStream in, CellProcessor... cellProcessors)
throws IOException, MolgenisInvalidFormatException
{
super(GenericImporterExtensions.getExcel(), cellProcessors);
this.name = name;
try
{
workbook = WorkbookFactory.create(in);
}
catch (InvalidFormatException e)
{
throw new MolgenisInvalidFormatException(e.getMessage());
}
}
@Override
public void init() throws IOException
{
// no operation
}
@Override
public Iterable<String> getEntityNames()
{
int count = getNumberOfSheets();
List<String> sheetNames = Lists.newArrayListWithCapacity(count);
for (int i = 0; i < count; i++)
{
sheetNames.add(getSheetName(i));
}
return sheetNames;
}
@Override
public Repository<Entity> getRepository(String name)
{
Sheet poiSheet = workbook.getSheet(name);
if (poiSheet == null)
{
return null;
}
return new ExcelRepository(name, poiSheet, entityTypeFactory, attributeFactory, cellProcessors);
}
public int getNumberOfSheets()
{
return workbook.getNumberOfSheets();
}
public String getSheetName(int i)
{
return workbook.getSheetName(i);
}
public ExcelRepository getSheet(int i)
{
Sheet poiSheet = workbook.getSheetAt(i);
if (poiSheet == null)
{
return null;
}
return new ExcelRepository(name, poiSheet, entityTypeFactory, attributeFactory, cellProcessors);
}
public ExcelSheetWriter createWritable(String entityName, List<Attribute> attributes,
AttributeWriteMode attributeWriteMode)
{
Sheet sheet = workbook.createSheet(entityName);
return new ExcelSheetWriter(sheet, attributes, attributeWriteMode, cellProcessors);
}
public ExcelSheetWriter createWritable(String entityName, List<String> attributeNames)
{
List<Attribute> attributes = attributeNames != null ? attributeNames.stream().<Attribute>map(
attrName -> attributeFactory.create().setName(attrName)).collect(Collectors.toList()) : null;
return createWritable(entityName, attributes, AttributeWriteMode.ATTRIBUTE_NAMES);
}
public void save(OutputStream out) throws IOException
{
workbook.write(out);
}
@Override
public String getName()
{
return NAME;
}
@Override
public Iterator<Repository<Entity>> iterator()
{
return new Iterator<Repository<Entity>>()
{
Iterator<String> it = getEntityNames().iterator();
@Override
public boolean hasNext()
{
return it.hasNext();
}
@Override
public Repository<Entity> next()
{
return getRepository(it.next());
}
};
}
@Override
public boolean hasRepository(String name)
{
if (null == name) return false;
Iterator<String> entityNames = getEntityNames().iterator();
while (entityNames.hasNext())
{
if (entityNames.next().equals(name)) return true;
}
return false;
}
@Override
public boolean hasRepository(EntityType entityType)
{
return hasRepository(entityType.getName());
}
@Autowired
public void setEntityTypeFactory(EntityTypeFactory entityTypeFactory)
{
this.entityTypeFactory = entityTypeFactory;
}
@Autowired
public void setAttributeFactory(AttributeFactory attributeFactory)
{
this.attributeFactory = attributeFactory;
}
}