package marubinotto.piggydb.ui.page;
import java.io.File;
import java.io.InputStream;
import java.sql.SQLException;
import marubinotto.piggydb.impl.PigDump;
import marubinotto.piggydb.impl.db.DatabaseSchema;
import marubinotto.piggydb.impl.db.SequenceAdjusterList;
import marubinotto.piggydb.model.enums.Role;
import marubinotto.piggydb.ui.page.common.AbstractBorderPage;
import marubinotto.piggydb.ui.page.common.DatabaseSpecificBeans;
import marubinotto.util.RdbUtils;
import marubinotto.util.procedure.Procedure;
import marubinotto.util.web.WebUtils;
import net.sf.click.control.FileField;
import net.sf.click.control.Form;
import net.sf.click.control.Submit;
import org.apache.commons.fileupload.FileItem;
import org.dbunit.DatabaseUnitException;
import org.dbunit.dataset.DataSetException;
public class RestorePage extends AbstractBorderPage {
private DatabaseSpecificBeans dbSpecificBeans;
private SequenceAdjusterList sequenceAdjusterList;
public SequenceAdjusterList getSequenceAdjusterList() {
return this.sequenceAdjusterList;
}
public void setSequenceAdjusterList(SequenceAdjusterList sequenceAdjusterList) {
this.sequenceAdjusterList = sequenceAdjusterList;
}
@Override
protected String[] getAuthorizedRoles() {
return new String[]{Role.OWNER.getName()};
}
//
// Control
//
public Form restoreForm = new Form();
private FileField dataFileField = new FileField("dataFile", true);
@Override
public void onInit() {
super.onInit();
initControls();
this.dbSpecificBeans = new DatabaseSpecificBeans(getApplicationContext());
}
private void initControls() {
this.dataFileField.setLabel(getMessage("RestorePage-data-file") + " (*.xml/*.pig)");
this.dataFileField.setSize(50);
this.restoreForm.add(this.dataFileField);
this.restoreForm.add(new Submit("restore", getMessage("RestorePage-restore"), this, "onRestoreClick"));
}
public boolean onRestoreClick() throws Exception {
if (!this.restoreForm.isValid()) {
return true;
}
try {
doRestore();
}
catch (DataSetException e) { // XML error
this.dataFileField.setError(getMessage("RestorePage-invalid-file"));
return true;
}
catch (InvalidPigDumpException e) {
this.dataFileField.setError(getMessage("RestorePage-invalid-file"));
return true;
}
setRedirectWithMessage(HomePage.class, getMessage("RestorePage-database-restored"));
return false;
}
/**
* The database version (global_setting/database.version) won't be changed
* since the version belongs to the current schema, not the data.
*/
private void doRestore() throws Exception {
final DatabaseSchema schema = this.dbSpecificBeans.getDatabaseSchema();
final FileItem fileItem = this.dataFileField.getFileItem();
getDomain().getTransaction().execute(new Procedure() {
public Object execute(Object input) throws Exception {
int currentVersion = schema.getVersion();
getLogger().info("currentVersion : " + currentVersion);
cleanTables();
if (fileItem.getName().toLowerCase().endsWith(".xml")) {
restoreWithXml();
}
else {
File uploadedFile = WebUtils.forceGetFile(fileItem);
getLogger().debug("uploadedFile: " + uploadedFile.getAbsolutePath());
if (!getPigDump().checkDumpFile(uploadedFile)) {
throw new InvalidPigDumpException();
}
getPigDump().restore(uploadedFile);
}
schema.setVersion(currentVersion); // preserve the version
getSequenceAdjusterList().adjust();
return null;
}
});
}
private void cleanTables() throws DatabaseUnitException, SQLException {
getLogger().info("Cleaning all tables ...");
for (String tableName : PigDump.TABLES) {
RdbUtils.deleteAll(this.dbSpecificBeans.getJdbcConnection(), tableName);
}
}
private void restoreWithXml() throws Exception {
getLogger().info("Restoring with xml ...");
InputStream dataInput = null;
try {
dataInput = this.dataFileField.getFileItem().getInputStream();
RdbUtils.cleanImportXml(this.dbSpecificBeans.getJdbcConnection(), dataInput);
}
finally {
dataInput.close();
}
getDomain().getFileRepository().clear();
}
private PigDump getPigDump() {
return (PigDump) getBean("pigDump");
}
private static class InvalidPigDumpException extends Exception {
}
}