/**
*
*/
package net.frontlinesms.ui.handler.importexport;
import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import net.frontlinesms.csv.CsvExporter;
import net.frontlinesms.data.domain.Contact;
import net.frontlinesms.data.domain.FrontlineMessage;
import net.frontlinesms.data.domain.Keyword;
import net.frontlinesms.ui.UiGeneratorController;
import net.frontlinesms.ui.i18n.InternationalisationUtils;
/**
* @author aga
*/
public abstract class ExportDialogHandler<T> extends ImportExportDialogHandler {
/** UI XML File Path: This is the outline for the dialog for EXPORTING */
private static final String UI_FILE_EXPORT_WIZARD_FORM = "/ui/core/importexport/exportWizardForm.xml";
/** i18n Text Key: "A file with this name already exists. Would you like to overwrite it?" */
private static final String MESSAGE_CONFIRM_FILE_OVERWRITE = "message.file.overwrite.confirm";
/** i18n Text Key: "The directory you entered doesn't exist" */
private static final String MESSAGE_BAD_DIRECTORY = "message.bad.directory";
/** I18n Text Key: TODO document */
private static final String MESSAGE_EXPORT_TASK_FAILED = "message.export.failed";
/** I18n Text Key: TODO document */
protected static final String MESSAGE_NO_FIELD_SELECTED = "message.no.field.selected";
/** I18n Text Key: TODO document */
protected static final String MESSAGE_EXPORT_TASK_SUCCESSFUL = "message.export.successful";
//> INSTANCE PROPERTIES
private Class<T> exportClass;
/** The objects we are exporting - a selection of thinlet components with attached {@link Contact}s, {@link Keyword}s or {@link FrontlineMessage}s */
protected Object attachedObject;
/** Used to store the confirmation dialog while it is being displayed, so that we can remove it later. */
private Object confirmationDialog;
//> CONSTRUCTORS
public ExportDialogHandler(Class<T> exportClass, UiGeneratorController ui) {
super(ui);
this.exportClass = exportClass;
}
//> ACCESSORS
@Override
String getDialogFile() {
return UI_FILE_EXPORT_WIZARD_FORM;
}
//> PUBLIC METHODS
/**
* Shows the export wizard dialog, according to the supplied type.
* @param export
* @param list The list to get selected items from.
*/
public void showWizard(Object list){
Object[] selected = uiController.getSelectedItems(list);
if (selected.length == 0) {
// If there are no highlighted items to export, don't do anything
return;
}
this.attachedObject = selected;
super._showWizard();
uiController.setAttachedObject(this.wizardDialog, attachedObject);
}
//> UI EVENT METHODS
/**
* Executes the export action.
* @param dataPath The path to the file to export data to.
*/
public void handleDoExport(String dataPath) {
log.trace("ENTER");
// Check if the file already exists. If it does, show a warning.
if (!dataPath.contains(File.separator) || !(new File(dataPath.substring(0, dataPath.lastIndexOf(File.separator))).isDirectory())) {
this.uiController.alert(InternationalisationUtils.getI18nString(MESSAGE_BAD_DIRECTORY));
} else if (dataPath.substring(dataPath.lastIndexOf(File.separator), dataPath.length()).equals(File.separator)) {
this.uiController.alert(InternationalisationUtils.getI18nString(MESSAGE_NO_FILENAME));
} else {
log.debug("Filename is [" + dataPath + "] before [" + CsvExporter.CSV_EXTENSION + "] check.");
if (!dataPath.endsWith(CsvExporter.CSV_EXTENSION)) {
dataPath += CsvExporter.CSV_EXTENSION;
}
log.debug("Filename is [" + dataPath + "] after [" + CsvExporter.CSV_EXTENSION + "] check.");
File csvFile = new File(dataPath);
if(csvFile.exists() && csvFile.isFile()) {
// show confirmation dialog
this.confirmationDialog = uiController.showConfirmationDialog("doExport('" + dataPath + "')",
this, MESSAGE_CONFIRM_FILE_OVERWRITE);
} else {
doExport(dataPath);
}
}
}
public void doExport(String dataPath) {
if(this.confirmationDialog != null) {
uiController.remove(this.confirmationDialog);
this.confirmationDialog = null;
}
try {
if (this.attachedObject != null) {
log.debug("Exporting selected objects...");
doSpecialExport(dataPath,
getSelected(this.exportClass, ((Object[])this.attachedObject)));
} else doSpecialExport(dataPath);
uiController.removeDialog(wizardDialog);
} catch(IOException ex) {
log.debug(InternationalisationUtils.getI18nString(MESSAGE_EXPORT_TASK_FAILED), ex);
uiController.alert(InternationalisationUtils.getI18nString(MESSAGE_EXPORT_TASK_FAILED) + ": " + ex.getMessage());
} finally {
log.trace("EXIT");
}
}
public final void columnCheckboxChanged() {
// FIXME If possible, remove this empty method!
}
protected abstract void doSpecialExport(String dataPath) throws IOException;
protected abstract void doSpecialExport(String dataPath, List<T> selected) throws IOException;
/**
* Gets the objects attached to the selected Thinlet components.
* @param <T> Class of the selected objects
* @param selectedClass Class of the selected Objects
* @param selected Array of selected Thinlet components
* @return List of the attached objects from the selected components
*/
@SuppressWarnings("unchecked")
private List<T> getSelected(Class<T> selectedClass, Object[] selected) {
List<T> objects = new LinkedList<T>();
for (Object o : selected) {
objects.add((T) this.uiController.getAttachedObject(o));
}
return objects;
}
}