package org.jcommons.db.load; import java.sql.SQLException; import javax.sql.DataSource; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jcommons.db.column.ColumnDataProvider; import org.jcommons.db.load.meta.MetaTable; import org.jcommons.io.sheet.Sheet; import org.jcommons.message.Message; /** * Loads a single sheet into the database. * * @author Thorsten Goeckeler */ public class SheetLoader { private static final Log LOG = LogFactory.getLog(SheetLoader.class); private DataSource dataSource; /** @return the currently used data source */ public DataSource getDataSource() { return dataSource; } /** * Inject the data source to be used to load the data. * * @param dataSource the database connection to use to load the data * @return this to allow chaining */ public SheetLoader setDataSource(final DataSource dataSource) { this.dataSource = dataSource; return this; } /** * Load the given sheet into the given database, either insert or update the data. * * Will actually only load the mandatory fields into the database. * * @param sheet the data set to load into the database * @throws SQLException if load cannot be performed */ public void load(final Sheet sheet) throws SQLException { if (sheet == null) return; if (getDataSource() == null) { StringBuilder log = new StringBuilder("Cannot import sheet ").append(defaultName(sheet)); log.append("as no database connection can be established."); LOG.error(log.toString()); return; } if (LOG.isInfoEnabled()) { StringBuilder log = new StringBuilder("Importing sheet ").append(defaultName(sheet)); log.append("with ").append(sheet.getTable().size()).append(" records into the database."); LOG.info(log.toString()); } // everything else is logging, now really import the data loadSheet(sheet, false); if (LOG.isInfoEnabled()) { StringBuilder log = new StringBuilder("Imported sheet ").append(defaultName(sheet)); log.append("with ").append(sheet.getTable().size()).append(" records into the database."); LOG.info(log.toString()); } } /** * Determine the name of the sheet for debug messages * * @param sheet the currently inspected book * @return the quoted name of the sheet or the empty string if it has no name */ private String defaultName(final Sheet sheet) { StringBuilder text = new StringBuilder(); if (sheet != null && StringUtils.isNotBlank(sheet.getName())) { text.append("\"").append(sheet.getName()).append("\" "); } return text.toString(); } /** * Load the given sheet into the given database, either insert or update the data. * * @param sheet the data set to load into the database, never null * @param update true if the non-mandatory fields shall be updated, false to load mandatory fields only * @throws SQLException if load cannot be performed */ protected void loadSheet(final Sheet sheet, final boolean update) throws SQLException { if (StringUtils.isBlank(sheet.getName())) return; if (sheet.getDataProvider() == null) { ColumnDataProvider dataProvider = new ColumnDataProvider(); dataProvider.setMetaColumns(MetaTable.getMetaData(getDataSource(), sheet.getName())); dataProvider.setTable(sheet.getName()); dataProvider.setHeaders(sheet.getTable().getColumns().toArray(new String[0])); sheet.setDataProvider(dataProvider); } Message errors = sheet.getDataProvider().validateTable(); if (errors.isEmpty()) { if (update) { // update all mandatory data with non-mandatory table data // TODO : DO SOMETHING TO UPDATE DATA } else { // load mandatory table data // TODO : DO SOMETHING TO LOAD DATA } } else { StringBuffer log = new StringBuffer("Cannot load sheet ").append(defaultName(sheet)); log.append(" due to the following errors: ").append(errors.getText()); LOG.error(log.toString()); } } /** * Update the given database from the given sheet, update all data. * * Will actually only update all non-mandatory fields in the database. * * @param sheet the data set to load into the database * @throws SQLException if load cannot be performed */ public void update(final Sheet sheet) throws SQLException { if (sheet == null) return; if (getDataSource() == null) { StringBuilder log = new StringBuilder("Cannot update from sheet ").append(defaultName(sheet)); log.append("as no database connection can be established."); LOG.error(log.toString()); return; } if (LOG.isInfoEnabled()) { StringBuilder log = new StringBuilder("Updating from sheet ").append(defaultName(sheet)); log.append("with ").append(sheet.getTable().size()).append(" records."); LOG.info(log.toString()); } // everything else is logging, now really update the data loadSheet(sheet, true); if (LOG.isInfoEnabled()) { StringBuilder log = new StringBuilder("Updated from sheet ").append(defaultName(sheet)); log.append("with ").append(sheet.getTable().size()).append(" records."); LOG.info(log.toString()); } } }