package org.openslx.dozmod.thrift;
import java.awt.Frame;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.swing.JFileChooser;
import org.apache.log4j.Logger;
import org.apache.thrift.TException;
import org.openslx.bwlp.thrift.iface.TransferInformation;
import org.openslx.dozmod.Config;
import org.openslx.dozmod.filetransfer.DownloadTask;
import org.openslx.dozmod.gui.Gui;
import org.openslx.dozmod.gui.Gui.GuiCallable;
import org.openslx.dozmod.gui.MainWindow;
import org.openslx.dozmod.gui.helper.MessageType;
import org.openslx.dozmod.gui.helper.QFileChooser;
import org.openslx.thrifthelper.ThriftManager;
import org.openslx.util.QuickTimer;
import org.openslx.util.QuickTimer.Task;
public class ThriftActions {
private static final Logger LOGGER = Logger.getLogger(ThriftActions.class);
/********************************************************************************
*
* DOWNLOAD ACTION
*
* Download image version action composed of the interface 'DownloadCallback'
* and the actual static method 'initDownload' to start the download.
*
********************************************************************************/
/**
* The callback interface to inform the GUI about the status of the operation
*/
public interface DownloadCallback {
void downloadInitialized(boolean success);
}
/**
* Initializes the download of the given imageVersionId saving it to the given
* imageName
*
* @param frame caller of this method
* @param imageVersionId image version id to download
* @param imageName destination file name
* @param virtualizerId id of the virtualizer
* @param imageSize size in bytes of the image to be downloaded
* @param callback callback function to return status of this operation to the GUI
*/
public static void initDownload(final Frame frame, final String imageVersionId, final String imageName,
final String virtualizerId, final long imageSize, final DownloadCallback callback) {
QFileChooser fc = new QFileChooser(Config.getDownloadPath(), true);
fc.setDialogTitle("Bitte wählen Sie einen Speicherort");
int action = fc.showSaveDialog(frame);
final File file = fc.getSelectedFile();
if (action != JFileChooser.APPROVE_OPTION || file == null)
return;
QuickTimer.scheduleOnce(new Task() {
@Override
public void fire() {
final TransferInformation transInf;
try {
transInf = ThriftManager.getSatClient()
.requestDownload(Session.getSatelliteToken(), imageVersionId);
} catch (TException e) {
ThriftError.showMessage(frame, LOGGER, e, "Die Download-Anfrage ist gescheitert");
if (callback != null)
callback.downloadInitialized(false);
return;
}
File df = null;
try {
file.getAbsoluteFile().mkdirs();
df = new File(file.getAbsolutePath(), generateFilename(imageName, virtualizerId));
df.createNewFile();
} catch (IOException e) {
LOGGER.warn("Cannot prepare download destination", e);
}
final File destFile = df;
if (destFile.exists()) {
Boolean confirmed = Gui.syncExec(new GuiCallable<Boolean>() {
@Override
public Boolean run() {
return Gui.showMessageBox(frame, "Datei existiert bereits, wollen Sie sie überschreiben?", MessageType.QUESTION_YESNO, LOGGER, null);
}
});
if (!confirmed) {
// TODO potentially ask him a new path?
return;
}
}
final DownloadTask dlTask;
try {
dlTask = new DownloadTask(Session.getSatelliteAddress(), transInf.getPlainPort(), transInf
.getToken(), destFile, imageSize, null);
} catch (final FileNotFoundException e) {
Gui.asyncMessageBox("Konnte Download nicht vorbereiten: Der gewählte Zielort ist nicht beschreibbar",
MessageType.ERROR, LOGGER, e);
if (callback != null)
callback.downloadInitialized(false);
return;
}
new Thread(dlTask).start();
Gui.asyncExec(new Runnable() {
@Override
public void run() {
Config.setDownloadPath(file.getAbsolutePath());
MainWindow.addDownload(imageName, destFile.getName(), dlTask);
if (callback != null)
callback.downloadInitialized(true);
}
});
}
});
}
/**
* Generates a filename based on the given imageName and with the proper extension
* depending on the virtualizer
*
* @param imageName
* @param virtualizerId
* @return the generated name as String
*/
private static String generateFilename(String imageName, String virtualizerId) {
String fileName = imageName.replaceAll("[^a-zA-Z0-9_\\.\\-]+", "_");
if (fileName.length() > 50) {
fileName = fileName.substring(0, 50);
}
if ("vmware".equals(virtualizerId)) {
fileName += ".vmdk";
} else if ("virtualbox".equals(virtualizerId)) {
fileName += ".vdi";
} else {
fileName += ".img";
}
return fileName;
}
public interface DeleteCallback {
void isDeleted(boolean success);
}
/********************************************************************************
*
* DELETE ACTION
*
* Deletes a specific image version
*
********************************************************************************/
public static void deleteImageVersion(final Frame frame, final String imageBaseId,
final String imageVersionId, final DeleteCallback callback) {
// requires confirmation of the user
if (!Gui.showMessageBox(frame, "Wollen Sie diese Image-Version wirklich löschen?",
MessageType.QUESTION_YESNO, LOGGER, null))
return;
// try to actually delete this version of the image
QuickTimer.scheduleOnce(new Task() {
boolean success = false;
@Override
public void fire() {
try {
ThriftManager.getSatClient().deleteImageVersion(Session.getSatelliteToken(),
imageVersionId);
LOGGER.info("Deleted version '" + imageVersionId + "' of image '" + imageBaseId + "'.");
success = true;
} catch (TException e) {
ThriftError.showMessage(frame, LOGGER, e, "Das Löschen der Version ist gescheitert");
if (callback != null)
callback.isDeleted(success);
return;
}
Gui.asyncExec(new Runnable() {
@Override
public void run() {
if (callback != null)
callback.isDeleted(success);
}
});
}
});
}
}