diff options
Diffstat (limited to 'dozentenmodul/src/main/java/ftp/DownloadTask.java')
| -rw-r--r-- | dozentenmodul/src/main/java/ftp/DownloadTask.java | 126 |
1 files changed, 95 insertions, 31 deletions
diff --git a/dozentenmodul/src/main/java/ftp/DownloadTask.java b/dozentenmodul/src/main/java/ftp/DownloadTask.java index 17becc52..f040e20d 100644 --- a/dozentenmodul/src/main/java/ftp/DownloadTask.java +++ b/dozentenmodul/src/main/java/ftp/DownloadTask.java @@ -1,16 +1,23 @@ package ftp; -import gui.image.FTPEditDownloader_GUI; -import gui.intro.Login_GUI; - import java.io.File; import java.io.FileOutputStream; +import java.io.IOException; import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.Map; import javax.swing.JOptionPane; import javax.swing.SwingWorker; +import models.Image; + +import org.apache.commons.io.FileUtils; import org.apache.log4j.Logger; +import org.apache.thrift.TException; + +import config.Config; +import util.ResourceLoader; /** * Execute file download in a background thread and update the progress. @@ -24,9 +31,11 @@ public class DownloadTask extends SwingWorker<Void, Void> { * Logger instance for this class. */ private final static Logger LOGGER = Logger.getLogger(DownloadTask.class); - - // 8MB buffer + private static final int BUFFER_SIZE = 8 * 1024 * 1024; + private static final double UPDATE_INTERVAL_SECONDS = 0.6; + private static final double UPDATE_INTERVAL_MS = UPDATE_INTERVAL_SECONDS * 1000; + private static final double BYTES_PER_MIB = 1024 * 1024; private String host; private int port; @@ -44,7 +53,6 @@ public class DownloadTask extends SwingWorker<Void, Void> { this.password = password; this.downloadPath = downloadPath; this.saveDir = saveDir; - } /** @@ -56,40 +64,47 @@ public class DownloadTask extends SwingWorker<Void, Void> { try { util.connect(); - byte[] buffer = new byte[BUFFER_SIZE]; - int bytesRead = -1; - long totalBytesRead = 0; - percentCompleted = 0; - long start = System.nanoTime(); - final double NANOS_PER_SECOND = 1000000000.0; - final double BYTES_PER_MIB = 1024 * 1024; + // show filesize in the GUI long fileSize = util.getFileSize(downloadPath); - // gui.setFileSize(fileSize); + firePropertyChange("filesize", 0, fileSize); + util.downloadFile(downloadPath); + // prepare the input/output streams String fileName = new File(downloadPath).getName(); - File downloadFile = new File(saveDir + File.separator + fileName); FileOutputStream outputStream = new FileOutputStream(downloadFile); - - util.downloadFile(downloadPath); InputStream inputStream = util.getInputStream(); - while ((bytesRead = inputStream.read(buffer)) != -1 - && isCancelled() == false) { + // initialize the counters needed for speed calculations + percentCompleted = 0; + byte[] buffer = new byte[BUFFER_SIZE]; + int bytesRead = -1; + long totalBytesRead = 0; + long lastUpdate = 0; + long lastBytes = 0; + long currentBytes = 0; + while ((bytesRead = inputStream.read(buffer)) != -1 && !isCancelled()) { outputStream.write(buffer, 0, bytesRead); + currentBytes += bytesRead; totalBytesRead += bytesRead; - double speed = NANOS_PER_SECOND / BYTES_PER_MIB - * totalBytesRead / (System.nanoTime() - start + 1); - percentCompleted = (int) (totalBytesRead * 100 / fileSize); - setProgress(percentCompleted); - firePropertyChange("speed", 0, speed); - firePropertyChange("filesize", 0, fileSize); - firePropertyChange("bytesread", 0, totalBytesRead); - + long now = System.currentTimeMillis(); + if (lastUpdate + UPDATE_INTERVAL_MS < now) { + percentCompleted = (int) ((totalBytesRead * 100) / fileSize); + setProgress(percentCompleted); + lastBytes = (lastBytes * 2 + currentBytes) / 3; + final double speed = lastBytes / UPDATE_INTERVAL_SECONDS; + firePropertyChange("speed", 0, speed / BYTES_PER_MIB); + firePropertyChange("bytesread", 0, totalBytesRead); + lastUpdate = now; + currentBytes = 0; + } } - + // finalize the download by updating the progress bar one last time + // (in case we didn't get to do it because of the time interval) + percentCompleted = (int) ((totalBytesRead * 100) / fileSize); + setProgress(percentCompleted); + firePropertyChange("bytesread", 0, totalBytesRead); outputStream.close(); - util.finish(); } catch (FTPException ex) { JOptionPane.showMessageDialog(null, @@ -112,8 +127,10 @@ public class DownloadTask extends SwingWorker<Void, Void> { protected void done() { if (!isCancelled() && percentCompleted==100) { LOGGER.info("Datei erfolgreich heruntergeladen."); + String vmxResult = ""; + vmxResult = generateVmx() ? "Passende VMX generiert." : "Keine passende VMX generiert!"; JOptionPane.showMessageDialog(null, - "Datei erfolgreich heruntergeladen.", "Message", + "Datei erfolgreich heruntergeladen. " + vmxResult, "Message", JOptionPane.INFORMATION_MESSAGE); } else if(!isCancelled() && percentCompleted != 100){ LOGGER.error("Datei wurde unvollständig heruntergeladen."); @@ -122,4 +139,51 @@ public class DownloadTask extends SwingWorker<Void, Void> { JOptionPane.INFORMATION_MESSAGE); } } -}
\ No newline at end of file + /** + * Helper to generate the vmx for the downloaded image + * @return true|false indicating the success of the file creation + */ + private boolean generateVmx() { + String vmxTemplate = ResourceLoader.getTextFile("/txt/vmx_template"); + // TODO: sanity checks on vmxTemplate would be good here... just to be safe + + // now we replace the placeholder variables with the real data + // for this, we first need to get the image information from the server + LOGGER.debug("Image's ID: " + Image.image.getImageId()); + Map<String, String> imageData = null; + try { + imageData = models.Client.clientcon.getClient().getImageData(Image.image.getImageId(), Image.image.getVersion()); + } catch (TException e) { + LOGGER.error("Thrift exception during transfer, see trace: ", e); + return false; + } + + // sanity check, shouldn't happen. + if (imageData == null) { + LOGGER.error("Could not query the image information from the server!"); + LOGGER.error("Image's ID: " + Image.image.getImageId()); + LOGGER.error("Image's version: " + Image.image.getVersion()); + return false; + } + // TODO: sanity checks on the content of imageData would be good here... + // use the information we received about the image + vmxTemplate = vmxTemplate.replace("%VM_DISPLAY_NAME%", imageData.get("name")); + vmxTemplate = vmxTemplate.replace("%VM_GUEST_OS%", imageData.get("os")); + vmxTemplate = vmxTemplate.replace("%VM_CPU_COUNT%", imageData.get("cpu")); + vmxTemplate = vmxTemplate.replace("%VM_RAM_SIZE%", String.valueOf(Integer.valueOf(imageData.get("ram")) * 1024)); + vmxTemplate = vmxTemplate.replace("%VM_DISK_PATH%", imageData.get("path").replaceFirst("^prod/", "")); + + // build filename for the vmx, basicly the same as the path of the vmdk + // just without the leading "prod/" and "vmx" instead of "vmdk" at the end. + String targetFilename = Config.getLastDownloadPath() + File.separator + + imageData.get("path").replaceFirst("^prod/", "").replaceFirst("\\.vmdk$", "") + ".vmx"; + try { + // try to write it to file + FileUtils.writeStringToFile(new File(targetFilename), vmxTemplate, StandardCharsets.UTF_8); + } catch (IOException e) { + LOGGER.error("Could not write vmx-template to '" + targetFilename + "'. See trace: ", e); + return false; + } + return true; + } +} |
