diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..32e654e --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,21 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Inno Setup: Compile Script", + "type": "process", + "command": "ISCC.exe", + "args": [ + "${file}" + ], + "presentation": { + "reveal": "always", + "echo": false + }, + "group": { + "kind": "build", + "isDefault": true + } + } + ] +} \ No newline at end of file diff --git a/BackupManager_convert_to_exe_launch4j.xml b/BackupManager_convert_to_exe_launch4j.xml index d81f1d9..c106872 100644 --- a/BackupManager_convert_to_exe_launch4j.xml +++ b/BackupManager_convert_to_exe_launch4j.xml @@ -25,11 +25,11 @@ - 2.1.0.0 + 2.2.1.0 2.0.RC1 Backup management and automation utility Copyright © 2024 Shard - 2.1.0.0 + 2.2.1.0 2.0.RC1 Backup Manager Shard diff --git a/BackupManager_installer_inno_setup.iss b/BackupManager_installer_inno_setup.iss index ce350f8..3c2e8b6 100644 --- a/BackupManager_installer_inno_setup.iss +++ b/BackupManager_installer_inno_setup.iss @@ -4,14 +4,14 @@ [Setup] AppName=BackupManager -AppVersion=2.1.0 +AppVersion=2.2.1 AppPublisher=Shard AppPublisherURL=https://www.shardpc.it/ DefaultDirName={userdocs}\Shard\BackupManager DisableDirPage=yes DisableProgramGroupPage=no PrivilegesRequired=lowest -OutputBaseFilename=BackupManager_v2.1.0_Setup +OutputBaseFilename=BackupManager_v2.2.1_Setup SetupIconFile=src\main\resources\res\img\logo.ico SetupLogging=yes Compression=lzma diff --git a/README.md b/README.md index a037708..a371d76 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Each backup is carefully saved, and the program maintains a detailed log of all ## Code Ducumentation -$\rightarrow$ [Code tecnical documentation](./docs/code_documentation.md) +$\rightarrow$ [Code tecnical documentation](./code_documentation.md) ## Important Notes diff --git a/src/main/java/backupmanager/BackupOperations.java b/src/main/java/backupmanager/BackupOperations.java index aaa31ef..0d146c7 100644 --- a/src/main/java/backupmanager/BackupOperations.java +++ b/src/main/java/backupmanager/BackupOperations.java @@ -21,7 +21,6 @@ import backupmanager.Entities.ConfigurationBackup; import backupmanager.Entities.TimeInterval; import backupmanager.Entities.ZippingContext; -import backupmanager.Enums.BackupStatus; import backupmanager.Enums.BackupTriggerType; import backupmanager.Enums.ErrorType; import backupmanager.Enums.TranslationLoaderEnum.TranslationCategory; @@ -283,7 +282,7 @@ public static void deletePotentiallyIncompletedBackupsFromLastExecution() { for (BackupRequest request : requests) { boolean deleted = deletePartialBackup(request.outputPath()); if (deleted) { - BackupRequestRepository.updateRequestStatusByRequestId(request.backupRequestId(), BackupStatus.TERMINATED); + BackupHelper.forceBackupTermination(request.backupRequestId()); } } } diff --git a/src/main/java/backupmanager/Controllers/BackupEntryController.java b/src/main/java/backupmanager/Controllers/BackupEntryController.java new file mode 100644 index 0000000..8b0f1f7 --- /dev/null +++ b/src/main/java/backupmanager/Controllers/BackupEntryController.java @@ -0,0 +1,191 @@ +package backupmanager.Controllers; + +import java.time.LocalDateTime; + +import javax.swing.JOptionPane; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import backupmanager.BackupOperations; +import backupmanager.Entities.ConfigurationBackup; +import backupmanager.Entities.TimeInterval; +import backupmanager.Entities.ZippingContext; +import backupmanager.Enums.BackupTriggerType; +import backupmanager.Enums.TranslationLoaderEnum.TranslationCategory; +import backupmanager.Enums.TranslationLoaderEnum.TranslationKey; +import backupmanager.Exceptions.BackupAlreadyRunningException; +import backupmanager.Exceptions.InvalidTimeInterval; +import backupmanager.GUI.BackupManagerGUI; +import backupmanager.GUI.BackupProgressGUI; +import backupmanager.Helpers.BackupHelper; +import backupmanager.Table.BackupTable; +import backupmanager.database.Repositories.BackupRequestRepository; + +public class BackupEntryController { + private static final Logger logger = LoggerFactory.getLogger(BackupEntryController.class); + + private ConfigurationBackup currentBackup; + + public BackupEntryController(ConfigurationBackup currentBackup) { + this.currentBackup = currentBackup; + } + + public ConfigurationBackup getBackup(String name, String initialPath, String destinationPath, String notes, boolean autoBackup, int maxBackupsToKeep) { + LocalDateTime nextDateBackup = null; + TimeInterval timeInterval = currentBackup != null ? currentBackup.getTimeIntervalBackup() : null; + if (timeInterval != null){ + nextDateBackup = BackupHelper.getNexDateBackup(timeInterval); + } + + if (!autoBackup) { + timeInterval = null; + nextDateBackup = null; + } + + if (currentBackup == null) { + LocalDateTime lastBackup = null; + LocalDateTime creationDate = LocalDateTime.now(); + LocalDateTime lastUpdateDate = creationDate; + int backupCount = 0; + return new ConfigurationBackup(name, initialPath, destinationPath, lastBackup, autoBackup, nextDateBackup, timeInterval, notes, creationDate, lastUpdateDate, backupCount, maxBackupsToKeep); + } else { + int id = currentBackup.getId(); + LocalDateTime lastBackup = currentBackup.getLastBackupDate(); + LocalDateTime creationDate = currentBackup.getCreationDate(); + LocalDateTime lastUpdateDate = LocalDateTime.now(); + int backupCount = currentBackup.getCount(); + return new ConfigurationBackup(id, name, initialPath, destinationPath, lastBackup, autoBackup, nextDateBackup, timeInterval, notes, creationDate, lastUpdateDate, backupCount, maxBackupsToKeep); + } + } + + public TimeInterval handleTimePickerAction(javax.swing.JDialog dialog, String target, String destination) throws InvalidTimeInterval { + TimeInterval time = BackupHelper.openTimePicker(dialog, currentBackup.getTimeIntervalBackup()); + if (time == null) throw new InvalidTimeInterval(); + + LocalDateTime nextDateBackup = BackupHelper.getNexDateBackup(time); + + currentBackup.setTimeIntervalBackup(time); + currentBackup.setNextBackupDate(nextDateBackup); + currentBackup.setTargetPath(target); + currentBackup.setDestinationPath(destination); + + return time; + } + + public boolean canDisposeAfterOk(String name, String initialPath, String destinationPath, String notes, boolean autoBackup, int maxBackupsToKeep, boolean create) { + if (name.isBlank() || destinationPath.isBlank() || initialPath.isBlank()) + return false; + + currentBackup = getBackup(name, initialPath, destinationPath, notes, autoBackup, maxBackupsToKeep); + + if (create) { + if (ConfigurationBackup.getBackupByName(currentBackup.getName()) != null) { + int response = JOptionPane.showConfirmDialog(null, TranslationCategory.DIALOGS.getTranslation(TranslationKey.DUPLICATED_BACKUP_NAME_MESSAGE), TranslationCategory.DIALOGS.getTranslation(TranslationKey.CONFIRMATION_REQUIRED_TITLE), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); + if (response == JOptionPane.YES_OPTION) { + BackupHelper.removeBackup(currentBackup.getName()); + } else { + return false; + } + } + BackupHelper.newBackup(currentBackup); + } else { + BackupHelper.updateBackup(currentBackup); + } + + return true; + } + + public boolean toggleAutomaticBackup(String name, String initialPath, String destinationPath, String notes, boolean autoBackup, int maxBackupsToKeep) { + currentBackup = getBackup(name, initialPath, destinationPath, notes, autoBackup, maxBackupsToKeep); + currentBackup.setAutomatic(!currentBackup.isAutomatic()); + + ConfigurationBackup backup = BackupHelper.toggleAutomaticBackup(currentBackup); + + if (backup == null) + return false; + + currentBackup = backup; + + if (backup.getTimeIntervalBackup() != null) { + TimeInterval timeInterval = backup.getTimeIntervalBackup(); + currentBackup.setNextBackupDate(BackupHelper.getNexDateBackup(timeInterval)); + return true; + } + + return false; + } + + public void handleSingleBackupRequest(BackupTable backupTable, String name, String initialPath, String destinationPath, String notes, boolean autoBackup, int maxBackupsToKeep) throws BackupAlreadyRunningException { + if (BackupRequestRepository.isAnyBackupRunning()) { + JOptionPane.showMessageDialog(null, TranslationCategory.DIALOGS.getTranslation(TranslationKey.WARNING_BACKUP_ALREADY_IN_PROGRESS_MESSAGE), TranslationCategory.DIALOGS.getTranslation(TranslationKey.WARNING_GENERIC_TITLE), JOptionPane.WARNING_MESSAGE); + throw new BackupAlreadyRunningException(); + } + + // update currentBackup + if (currentBackup == null) { + currentBackup = getBackup(name, initialPath, destinationPath, notes, autoBackup, maxBackupsToKeep); + } + + singleBackup(initialPath, destinationPath, backupTable); + } + + private void singleBackup(String target, String destination, BackupTable backupTable) { + logger.info("Event --> single backup"); + + String path1 = target; + String path2 = destination; + + currentBackup.setTargetPath(path2); + + String temp = "\\"; + + if (!BackupOperations.checkInputCorrect(currentBackup.getName(), path1, path2, null)) return; + + LocalDateTime dateNow = LocalDateTime.now(); + + String name1; // folder name/initial file + String date = dateNow.format(BackupHelper.dateForfolderNameFormatter); + + //------------------------------SET ALL THE STRINGS------------------------------ + name1 = path1.substring(path1.length()-1, path1.length()-1); + + for(int i=path1.length()-1; i>=0; i--) { + if(path1.charAt(i) != temp.charAt(0)) name1 = path1.charAt(i) + name1; + else break; + } + + name1 = BackupOperations.removeExtension(name1); + path2 = path2 + "\\" + name1 + " (Backup " + date + ")"; + + //------------------------------COPY THE FILE OR DIRECTORY------------------------------ + logger.info("date backup: " + date); + + BackupManagerGUI.progressBar = new BackupProgressGUI(path1, path2); + BackupManagerGUI.progressBar.setVisible(true); + + ZippingContext context = ZippingContext.create(currentBackup, null, backupTable, BackupManagerGUI.progressBar, null, null); + + BackupOperations.executeBackup(context, BackupTriggerType.USER, path1, path2); + + //if current_file_opened is null it means they are not in a backup but it is a backup not registered + if (currentBackup.getName() != null && !currentBackup.getName().isEmpty()) { + currentBackup.setTargetPath(target); + currentBackup.setDestinationPath(destination); + currentBackup.setLastBackupDate(LocalDateTime.now()); + } + } + + public void handleOpenBackupActivationMessage(TimeInterval newtimeInterval, String target, String destination) { + currentBackup.setTimeIntervalBackup(newtimeInterval); + BackupHelper.showMessageActivationAutoBackup(newtimeInterval, target, destination); + } + + public ConfigurationBackup getCurrentBackup() { + return currentBackup; + } + + public void setCurrentBackup(ConfigurationBackup currentBackup) { + this.currentBackup = currentBackup; + } +} diff --git a/src/main/java/backupmanager/Controllers/BackupProgressController.java b/src/main/java/backupmanager/Controllers/BackupProgressController.java new file mode 100644 index 0000000..fa4d3b0 --- /dev/null +++ b/src/main/java/backupmanager/Controllers/BackupProgressController.java @@ -0,0 +1,9 @@ +package backupmanager.Controllers; + +import backupmanager.Services.ZippingThread; + +public class BackupProgressController { + public void cancelBackup() { + ZippingThread.stopExecutorService(1); + } +} diff --git a/src/main/java/backupmanager/Controllers/GuiController.java b/src/main/java/backupmanager/Controllers/GuiController.java new file mode 100644 index 0000000..fe23c7f --- /dev/null +++ b/src/main/java/backupmanager/Controllers/GuiController.java @@ -0,0 +1,13 @@ +package backupmanager.Controllers; + +import java.awt.Image; + +import javax.swing.ImageIcon; + +import backupmanager.Enums.ConfigKey; + +public class GuiController { + public static Image getIcon(Class obj) { + return new ImageIcon(obj.getResource(ConfigKey.LOGO_IMG.getValue())).getImage(); + } +} diff --git a/src/main/java/backupmanager/Controllers/PreferenceController.java b/src/main/java/backupmanager/Controllers/PreferenceController.java new file mode 100644 index 0000000..5990480 --- /dev/null +++ b/src/main/java/backupmanager/Controllers/PreferenceController.java @@ -0,0 +1,27 @@ +package backupmanager.Controllers; + +import java.io.IOException; +import java.util.Arrays; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import backupmanager.GUI.BackupManagerGUI; +import backupmanager.Managers.ExceptionManager; +import backupmanager.Services.PreferenceService; + +public record PreferenceController (PreferenceService service, BackupManagerGUI mainGui) { + private static final Logger logger = LoggerFactory.getLogger(PreferenceController.class); + + public void applyPreferences(String language, String theme) { + logger.info("Updating preferences -> Language: {}; Theme: ()", language, theme); + + try { + service.updatePreferences(language, theme); + mainGui.reloadPreferences(); + } catch (IOException ex) { + logger.error("An error occurred during applying preferences: " + ex.getMessage(), ex); + ExceptionManager.openExceptionMessage(ex.getMessage(), Arrays.toString(ex.getStackTrace())); + } + } +} diff --git a/src/main/java/backupmanager/Controllers/TrayController.java b/src/main/java/backupmanager/Controllers/TrayController.java index 36c2194..85a5a61 100644 --- a/src/main/java/backupmanager/Controllers/TrayController.java +++ b/src/main/java/backupmanager/Controllers/TrayController.java @@ -27,7 +27,6 @@ public class TrayController { private final Runnable onOpen; private final Runnable onExit; - public TrayController(Runnable onOpen, Runnable onExit) { this.onOpen = onOpen; this.onExit = onExit; diff --git a/src/main/java/backupmanager/Dialogs/BackupEntryDialog.java b/src/main/java/backupmanager/Dialogs/BackupEntryDialog.java index f53b678..21f04ea 100644 --- a/src/main/java/backupmanager/Dialogs/BackupEntryDialog.java +++ b/src/main/java/backupmanager/Dialogs/BackupEntryDialog.java @@ -4,27 +4,22 @@ import java.time.LocalDateTime; -import javax.swing.JOptionPane; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.formdev.flatlaf.FlatClientProperties; import backupmanager.BackupOperations; +import backupmanager.Controllers.BackupEntryController; import backupmanager.Entities.ConfigurationBackup; import backupmanager.Entities.TimeInterval; -import backupmanager.Entities.ZippingContext; -import backupmanager.Enums.BackupTriggerType; import backupmanager.Enums.ConfigKey; import backupmanager.Enums.TranslationLoaderEnum.TranslationCategory; import backupmanager.Enums.TranslationLoaderEnum.TranslationKey; -import backupmanager.GUI.BackupManagerGUI; -import backupmanager.GUI.BackupProgressGUI; +import backupmanager.Exceptions.BackupAlreadyRunningException; +import backupmanager.Exceptions.InvalidTimeInterval; import backupmanager.Helpers.BackupHelper; import backupmanager.Json.JSONConfigReader; -import backupmanager.Table.BackupTable; -import backupmanager.database.Repositories.BackupRequestRepository; public class BackupEntryDialog extends javax.swing.JDialog { @@ -34,12 +29,14 @@ public class BackupEntryDialog extends javax.swing.JDialog { private final boolean create; private String backupOnText; private String backupOffText; - private ConfigurationBackup currentBackup; - private TimeInterval timeInterval; + + private final BackupEntryController entryController; public BackupEntryDialog(java.awt.Frame parent, boolean modal) { super(parent, modal); + entryController = new BackupEntryController(null); + initializeDialog(); setAutoBackupOff(); this.create = true; @@ -49,7 +46,7 @@ public BackupEntryDialog(java.awt.Frame parent, boolean modal) { public BackupEntryDialog(java.awt.Frame parent, boolean modal, ConfigurationBackup currentBackup) { super(parent, modal); - this.currentBackup = currentBackup; + entryController = new BackupEntryController(currentBackup); initializeDialog(); updateCurrentFiedsByBackup(currentBackup); @@ -57,10 +54,33 @@ public BackupEntryDialog(java.awt.Frame parent, boolean modal, ConfigurationBack backupNameField.setEditable(false); backupNameField.setFocusable(false); this.create = false; - this.timeInterval = currentBackup.getTimeIntervalBackup(); okButton.setText(TranslationCategory.GENERAL.getTranslation(TranslationKey.SAVE_BUTTON)); } + private void setAutoBackupPreference(boolean option) { + ConfigurationBackup currentBackup = entryController.getCurrentBackup(); + currentBackup.setAutomatic(option); + + if (option) { + setAutoBackupOn(currentBackup); + } else { + disableAutoBackup(currentBackup); + } + } + + private void setStartPathField(String text) { + startPathField.setText(text); + } + private void setDestinationPathField(String text) { + destinationPathField.setText(text); + } + private void setCurrentBackupNotes(String notes) { + backupNoteTextArea.setText(notes); + } + private void setCurrentBackupMaxBackupsToKeep(int maxBackupsCount) { + maxBackupCountSpinner.setValue(maxBackupsCount); + } + private void initializeDialog() { initComponents(); @@ -79,6 +99,10 @@ private void setLastBackupLabel(LocalDateTime date) { else lastBackupLabel.setText(""); } + private void openBackupActivationMessage(TimeInterval newtimeInterval) { + entryController.handleOpenBackupActivationMessage(newtimeInterval, startPathField.getText(), destinationPathField.getText()); + } + private void updateCurrentFiedsByBackup(ConfigurationBackup backup) { setStartPathField(backup.getTargetPath()); setDestinationPathField(backup.getDestinationPath()); @@ -94,150 +118,18 @@ private void updateCurrentFiedsByBackup(ConfigurationBackup backup) { } } - private void openBackupActivationMessage(TimeInterval newtimeInterval) { - if (newtimeInterval == null) - throw new IllegalArgumentException("Time interval cannot be null"); - - // update current timeInterval with the new one - timeInterval = newtimeInterval; - - String startPath = startPathField.getText(); - String destinationPath = destinationPathField.getText(); - BackupHelper.showMessageActivationAutoBackup(timeInterval, startPath, destinationPath); - } - - public void setAutoBackupPreference(boolean option) { - currentBackup.setAutomatic(option); - - if (option) { - setAutoBackupOn(currentBackup); - } else { - disableAutoBackup(currentBackup); - } - } - - public ConfigurationBackup getBackup() { - String name = backupNameField.getText(); - String initialPath = startPathField.getText(); - String destinationPath = destinationPathField.getText(); - String notes = backupNoteTextArea.getText(); - boolean autoBackup = toggleAutoBackup.isSelected(); - int maxBackupsToKeep = (int) maxBackupCountSpinner.getValue(); - - LocalDateTime nextDateBackup = null; - if (timeInterval != null){ - nextDateBackup = BackupHelper.getNexDateBackup(timeInterval); - } - - if (!autoBackup) { - timeInterval = null; - nextDateBackup = null; - } - - if (currentBackup == null) { - LocalDateTime lastBackup = null; - LocalDateTime creationDate = LocalDateTime.now(); - LocalDateTime lastUpdateDate = creationDate; - int backupCount = 0; - return new ConfigurationBackup(name, initialPath, destinationPath, lastBackup, autoBackup, nextDateBackup, timeInterval, notes, creationDate, lastUpdateDate, backupCount, maxBackupsToKeep); + private void toggleAutomaticBackup() { + if (entryController.toggleAutomaticBackup(backupNameField.getText(), startPathField.getText(), destinationPathField.getText(), backupNoteTextArea.getText(), toggleAutoBackup.isSelected(), (int) maxBackupCountSpinner.getValue())) { + setAutoBackupOn(entryController.getCurrentBackup()); + toggleAutoBackup.setSelected(true); + btnTimePicker.setToolTipText(entryController.getCurrentBackup().getTimeIntervalBackup().toString()); + btnTimePicker.setEnabled(true); } else { - int id = currentBackup.getId(); - LocalDateTime lastBackup = currentBackup.getLastBackupDate(); - LocalDateTime creationDate = currentBackup.getCreationDate(); - LocalDateTime lastUpdateDate = LocalDateTime.now(); - int backupCount = currentBackup.getCount(); - return new ConfigurationBackup(id, name, initialPath, destinationPath, lastBackup, autoBackup, nextDateBackup, timeInterval, notes, creationDate, lastUpdateDate, backupCount, maxBackupsToKeep); - } - } - - public void setStartPathField(String text) { - startPathField.setText(text); - } - public void setDestinationPathField(String text) { - destinationPathField.setText(text); - } - private void setCurrentBackupNotes(String notes) { - backupNoteTextArea.setText(notes); - } - public void setCurrentBackupMaxBackupsToKeep(int maxBackupsCount) { - maxBackupCountSpinner.setValue(maxBackupsCount); - } - - public void singleBackup(String path1, String path2, BackupTable backupTable) { - logger.info("Event --> single backup"); - - currentBackup.setTargetPath(path2); - - String temp = "\\"; - - //------------------------------INPUT CONTROL ERRORS------------------------------ - if (!BackupOperations.checkInputCorrect(currentBackup.getName(), path1, path2, null)) return; - - //------------------------------TO GET THE CURRENT DATE------------------------------ - LocalDateTime dateNow = LocalDateTime.now(); - - //------------------------------SET ALL THE VARIABLES------------------------------ - String name1; // folder name/initial file - String date = dateNow.format(BackupHelper.dateForfolderNameFormatter); - - //------------------------------SET ALL THE STRINGS------------------------------ - name1 = path1.substring(path1.length()-1, path1.length()-1); - - for(int i=path1.length()-1; i>=0; i--) { - if(path1.charAt(i) != temp.charAt(0)) name1 = path1.charAt(i) + name1; - else break; - } - - name1 = BackupOperations.removeExtension(name1); - path2 = path2 + "\\" + name1 + " (Backup " + date + ")"; - - //------------------------------COPY THE FILE OR DIRECTORY------------------------------ - logger.info("date backup: " + date); - - BackupManagerGUI.progressBar = new BackupProgressGUI(path1, path2); - BackupManagerGUI.progressBar.setVisible(true); - - ZippingContext context = ZippingContext.create(currentBackup, null, backupTable, BackupManagerGUI.progressBar, null, null); - - BackupOperations.executeBackup(context, BackupTriggerType.USER, path1, path2); - - //if current_file_opened is null it means they are not in a backup but it is a backup with no associated json file - if (currentBackup.getName() != null && !currentBackup.getName().isEmpty()) { - currentBackup.setTargetPath(startPathField.getText()); - currentBackup.setDestinationPath(destinationPathField.getText()); - currentBackup.setLastBackupDate(LocalDateTime.now()); - } - } - - private boolean toggleAutomaticBackup() { - currentBackup = getBackup(); - currentBackup.setAutomatic(!currentBackup.isAutomatic()); - - ConfigurationBackup backup = BackupHelper.toggleAutomaticBackup(currentBackup); - - if (backup == null) { + setAutoBackupOff(); toggleAutoBackup.setSelected(false); - return false; - } - - currentBackup = backup; - - if (backup.getTimeIntervalBackup() != null) { - timeInterval = backup.getTimeIntervalBackup(); - currentBackup.setNextBackupDate(BackupHelper.getNexDateBackup(timeInterval)); - btnTimePicker.setToolTipText(timeInterval.toString()); - btnTimePicker.setEnabled(true); - setAutoBackupOn(currentBackup); - toggleAutoBackup.setSelected(true); - return true; } - - setAutoBackupOff(); - toggleAutoBackup.setSelected(false); - return false; } - private void setAutoBackupOn(ConfigurationBackup backup) { toggleAutoBackup.setSelected(true); toggleAutoBackup.setText(backupOnText); @@ -254,6 +146,11 @@ private void setAutoBackupOff() { disableTimePickerButton(); } + private void disableTimePickerButton() { + btnTimePicker.setToolTipText(TranslationCategory.BACKUP_ENTRY.getTranslation(TranslationKey.TIME_PICKER_TOOLTIP)); + btnTimePicker.setEnabled(false); + } + private void enableTimePickerButton(ConfigurationBackup backup) { if (backup.getTimeIntervalBackup() != null) { btnTimePicker.setToolTipText(backup.getTimeIntervalBackup().toString()); @@ -263,11 +160,6 @@ private void enableTimePickerButton(ConfigurationBackup backup) { } } - private void disableTimePickerButton() { - btnTimePicker.setToolTipText(TranslationCategory.BACKUP_ENTRY.getTranslation(TranslationKey.TIME_PICKER_TOOLTIP)); - btnTimePicker.setEnabled(false); - } - private void disableAutoBackup(ConfigurationBackup backup) { logger.info("Event --> auto backup disabled"); @@ -577,17 +469,19 @@ private void btnPathSearch2ActionPerformed(java.awt.event.ActionEvent evt) {//GE }//GEN-LAST:event_btnPathSearch2ActionPerformed private void SingleBackupActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SingleBackupActionPerformed - if (BackupRequestRepository.isAnyBackupRunning()) { - JOptionPane.showMessageDialog(null, TranslationCategory.DIALOGS.getTranslation(TranslationKey.WARNING_BACKUP_ALREADY_IN_PROGRESS_MESSAGE), TranslationCategory.DIALOGS.getTranslation(TranslationKey.WARNING_GENERIC_TITLE), JOptionPane.WARNING_MESSAGE); - return; - } - - // update currentBackup - if (currentBackup == null) { - currentBackup = getBackup(); + try { + entryController.handleSingleBackupRequest( + backupTable, + backupNameField.getText(), + startPathField.getText(), + destinationPathField.getText(), + backupNoteTextArea.getText(), + toggleAutoBackup.isSelected(), + (int) maxBackupCountSpinner.getValue() + ); + } catch (BackupAlreadyRunningException e) { + // no handle } - - singleBackup(startPathField.getText(), destinationPathField.getText(), backupTable); }//GEN-LAST:event_SingleBackupActionPerformed private void toggleAutoBackupActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_toggleAutoBackupActionPerformed @@ -596,18 +490,13 @@ private void toggleAutoBackupActionPerformed(java.awt.event.ActionEvent evt) {// }//GEN-LAST:event_toggleAutoBackupActionPerformed private void btnTimePickerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnTimePickerActionPerformed - TimeInterval time = BackupHelper.openTimePicker(this, currentBackup.getTimeIntervalBackup()); - if (time == null) return; - - btnTimePicker.setToolTipText(time.toString()); - LocalDateTime nextDateBackup = BackupHelper.getNexDateBackup(time); - - currentBackup.setTimeIntervalBackup(time); - currentBackup.setNextBackupDate(nextDateBackup); - currentBackup.setTargetPath(startPathField.getText()); - currentBackup.setDestinationPath(destinationPathField.getText()); - - openBackupActivationMessage(time); + try { + TimeInterval time = entryController.handleTimePickerAction(this, startPathField.getText(), destinationPathField.getText()); + btnTimePicker.setToolTipText(time.toString()); + openBackupActivationMessage(time); + } catch (InvalidTimeInterval e) { + // no actions + } }//GEN-LAST:event_btnTimePickerActionPerformed private void maxBackupCountSpinnerStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_maxBackupCountSpinnerStateChanged @@ -623,27 +512,8 @@ private void closeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-F }//GEN-LAST:event_closeButtonActionPerformed private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed - if (backupNameField.getText().isBlank() || destinationPathField.getText().isBlank() || startPathField.getText().isBlank()) { - return; - } - - currentBackup = getBackup(); - - if (create) { - if (ConfigurationBackup.getBackupByName(currentBackup.getName()) != null) { - int response = JOptionPane.showConfirmDialog(null, TranslationCategory.DIALOGS.getTranslation(TranslationKey.DUPLICATED_BACKUP_NAME_MESSAGE), TranslationCategory.DIALOGS.getTranslation(TranslationKey.CONFIRMATION_REQUIRED_TITLE), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); - if (response == JOptionPane.YES_OPTION) { - BackupHelper.removeBackup(currentBackup.getName()); - } else { - return; - } - } - BackupHelper.newBackup(currentBackup); - } else { - BackupHelper.updateBackup(currentBackup); - } - - this.dispose(); + if (entryController.canDisposeAfterOk(backupNameField.getText(), startPathField.getText(), destinationPathField.getText(), backupNoteTextArea.getText(), toggleAutoBackup.isSelected(), (int) maxBackupCountSpinner.getValue(), create)) + this.dispose(); }//GEN-LAST:event_okButtonActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables diff --git a/src/main/java/backupmanager/Dialogs/EntryUserDialog.java b/src/main/java/backupmanager/Dialogs/EntryUserDialog.java index 699da8c..3c6edcb 100644 --- a/src/main/java/backupmanager/Dialogs/EntryUserDialog.java +++ b/src/main/java/backupmanager/Dialogs/EntryUserDialog.java @@ -150,7 +150,6 @@ private void okBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:e return; } - // save user to the file user = new User(name, surname, email); this.dispose(); diff --git a/src/main/java/backupmanager/Dialogs/PreferencesDialog.java b/src/main/java/backupmanager/Dialogs/PreferencesDialog.java index 1723b05..8ad5e30 100644 --- a/src/main/java/backupmanager/Dialogs/PreferencesDialog.java +++ b/src/main/java/backupmanager/Dialogs/PreferencesDialog.java @@ -1,39 +1,32 @@ package backupmanager.Dialogs; +import backupmanager.Controllers.GuiController; +import backupmanager.Controllers.PreferenceController; import backupmanager.Entities.Confingurations; -import backupmanager.Enums.ConfigKey; import backupmanager.Enums.LanguagesEnum; import backupmanager.Enums.ThemesEnum; -import backupmanager.Enums.TranslationLoaderEnum; import backupmanager.Enums.TranslationLoaderEnum.TranslationCategory; import backupmanager.Enums.TranslationLoaderEnum.TranslationKey; -import backupmanager.Managers.ExceptionManager; import backupmanager.Managers.ThemeManager; +import backupmanager.Services.PreferenceService; import backupmanager.GUI.BackupManagerGUI; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.awt.Image; -import java.io.IOException; -import java.util.Arrays; -import javax.swing.ImageIcon; public class PreferencesDialog extends javax.swing.JDialog { - private static final Logger logger = LoggerFactory.getLogger(PreferencesDialog.class); - private final BackupManagerGUI mainGui; + + private final PreferenceController preferenceController; public PreferencesDialog(java.awt.Frame parent, boolean modal, BackupManagerGUI mainGui) { super(parent, modal); - this.mainGui = mainGui; + + preferenceController = new PreferenceController(new PreferenceService(), mainGui); initComponents(); - // logo application - Image icon = new ImageIcon(this.getClass().getResource(ConfigKey.LOGO_IMG.getValue())).getImage(); - this.setIconImage(icon); + this.setIconImage(GuiController.getIcon(this.getClass())); ThemeManager.updateThemeDialog(this); + setLanguages(); setThemes(); setTranslations(); @@ -133,27 +126,12 @@ private void themesComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GE }//GEN-LAST:event_themesComboBoxActionPerformed private void applyBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_applyBtnActionPerformed - String selectedLanguage = (String) languagesComboBox.getSelectedItem(); - String selectedTheme = (String) themesComboBox.getSelectedItem(); - - logger.info("Updating preferences -> Language: " + selectedLanguage + "; Theme: " + selectedTheme); - - try { - // translactions - Confingurations.setLanguageByLanguageName(selectedLanguage); - TranslationLoaderEnum.loadTranslations(ConfigKey.LANGUAGES_DIRECTORY_STRING.getValue() + Confingurations.getLanguage().getFileName()); - setTranslations(); - - // theme - Confingurations.setTheme(selectedTheme); - ThemeManager.updateThemeDialog(this); - - // update globally - mainGui.reloadPreferences(); - } catch (IOException ex) { - logger.error("An error occurred during applying preferences: " + ex.getMessage(), ex); - ExceptionManager.openExceptionMessage(ex.getMessage(), Arrays.toString(ex.getStackTrace())); - } + preferenceController.applyPreferences( + (String) languagesComboBox.getSelectedItem(), + (String) themesComboBox.getSelectedItem() + ); + setTranslations(); + ThemeManager.updateThemeDialog(this); }//GEN-LAST:event_applyBtnActionPerformed private void closeBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeBtnActionPerformed diff --git a/src/main/java/backupmanager/Dialogs/TimePicker.java b/src/main/java/backupmanager/Dialogs/TimePicker.java index 48b9537..bae9f9e 100644 --- a/src/main/java/backupmanager/Dialogs/TimePicker.java +++ b/src/main/java/backupmanager/Dialogs/TimePicker.java @@ -1,12 +1,10 @@ package backupmanager.Dialogs; -import backupmanager.Enums.ConfigKey; import backupmanager.Enums.TranslationLoaderEnum.TranslationCategory; import backupmanager.Enums.TranslationLoaderEnum.TranslationKey; +import backupmanager.Controllers.GuiController; import backupmanager.Entities.TimeInterval; -import java.awt.Image; -import javax.swing.ImageIcon; import javax.swing.JOptionPane; public class TimePicker extends javax.swing.JDialog { @@ -28,9 +26,7 @@ public TimePicker(java.awt.Dialog parent, TimeInterval timeInterval, boolean mod minutesSpinner.setValue(timeInterval.minutes()); } - // logo application - Image icon = new ImageIcon(this.getClass().getResource(ConfigKey.LOGO_IMG.getValue())).getImage(); - this.setIconImage(icon); + this.setIconImage(GuiController.getIcon(this.getClass())); setTranslations(); } diff --git a/src/main/java/backupmanager/Exceptions/BackupAlreadyRunningException.java b/src/main/java/backupmanager/Exceptions/BackupAlreadyRunningException.java new file mode 100644 index 0000000..7eba5d6 --- /dev/null +++ b/src/main/java/backupmanager/Exceptions/BackupAlreadyRunningException.java @@ -0,0 +1,20 @@ +package backupmanager.Exceptions; + +public class BackupAlreadyRunningException extends Exception { + + public BackupAlreadyRunningException() { + super(); + } + + public BackupAlreadyRunningException(String message) { + super(message); + } + + public BackupAlreadyRunningException(String message, Throwable cause) { + super(message, cause); + } + + public BackupAlreadyRunningException(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/backupmanager/Exceptions/InvalidTimeInterval.java b/src/main/java/backupmanager/Exceptions/InvalidTimeInterval.java new file mode 100644 index 0000000..5b5cf72 --- /dev/null +++ b/src/main/java/backupmanager/Exceptions/InvalidTimeInterval.java @@ -0,0 +1,20 @@ +package backupmanager.Exceptions; + +public class InvalidTimeInterval extends Exception { + + public InvalidTimeInterval() { + super(); + } + + public InvalidTimeInterval(String message) { + super(message); + } + + public InvalidTimeInterval(String message, Throwable cause) { + super(message, cause); + } + + public InvalidTimeInterval(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/backupmanager/GUI/BackupManagerGUI.java b/src/main/java/backupmanager/GUI/BackupManagerGUI.java index 6209b71..91fb32b 100644 --- a/src/main/java/backupmanager/GUI/BackupManagerGUI.java +++ b/src/main/java/backupmanager/GUI/BackupManagerGUI.java @@ -1,7 +1,6 @@ package backupmanager.GUI; import java.awt.Dimension; -import java.awt.Image; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; @@ -13,7 +12,6 @@ import javax.swing.AbstractAction; import javax.swing.ActionMap; -import javax.swing.ImageIcon; import javax.swing.InputMap; import javax.swing.JComponent; import javax.swing.JOptionPane; @@ -28,6 +26,7 @@ import com.formdev.flatlaf.FlatClientProperties; +import backupmanager.Controllers.GuiController; import backupmanager.Dialogs.EntryUserDialog; import backupmanager.Email.EmailSender; import backupmanager.Entities.ConfigurationBackup; @@ -72,20 +71,16 @@ public final class BackupManagerGUI extends javax.swing.JFrame { public static BackupTableModel tableModel; public static BackupProgressGUI progressBar; private Integer selectedRow; - private final String currentVersion; private final SideMenuPanel sp; public BackupManagerGUI() { ThemeManager.updateThemeFrame(this); initComponents(); - currentVersion = ConfigKey.VERSION.getValue(); sp = new SideMenuPanel(this); - // logo application - Image icon = new ImageIcon(this.getClass().getResource(ConfigKey.LOGO_IMG.getValue())).getImage(); - this.setIconImage(icon); + this.setIconImage(GuiController.getIcon(this.getClass())); initializeMenuItems(); setScreenSize(); @@ -1161,7 +1156,7 @@ private void setTranslations() { displayBackupList(); // general - jLabel3.setText(TranslationCategory.GENERAL.getTranslation(TranslationKey.VERSION) + " " + currentVersion); + jLabel3.setText(TranslationCategory.GENERAL.getTranslation(TranslationKey.VERSION) + " " + ConfigKey.VERSION.getValue()); // menu jMenu1.setText(TranslationCategory.MENU.getTranslation(TranslationKey.FILE)); @@ -1344,4 +1339,4 @@ private void initializeMenuItems() { private javax.swing.JLabel totalSpaceTitleLabel; private javax.swing.JPanel totalSpaceUsedPanel; // End of variables declaration//GEN-END:variables -} \ No newline at end of file +} diff --git a/src/main/java/backupmanager/GUI/BackupProgressGUI.java b/src/main/java/backupmanager/GUI/BackupProgressGUI.java index efe7b5f..fa52a31 100644 --- a/src/main/java/backupmanager/GUI/BackupProgressGUI.java +++ b/src/main/java/backupmanager/GUI/BackupProgressGUI.java @@ -2,22 +2,22 @@ import javax.swing.JOptionPane; -import java.awt.Image; -import javax.swing.ImageIcon; - -import backupmanager.Enums.ConfigKey; +import backupmanager.Controllers.BackupProgressController; +import backupmanager.Controllers.GuiController; import backupmanager.Enums.TranslationLoaderEnum.TranslationCategory; import backupmanager.Enums.TranslationLoaderEnum.TranslationKey; -import backupmanager.Services.ZippingThread; public class BackupProgressGUI extends javax.swing.JDialog { + + private final BackupProgressController progressController; + public BackupProgressGUI(String initialPath, String destinationPath) { initComponents(); - // logo application - Image icon = new ImageIcon(this.getClass().getResource(ConfigKey.LOGO_IMG.getValue())).getImage(); - this.setIconImage(icon); + progressController = new BackupProgressController(); + + this.setIconImage(GuiController.getIcon(this.getClass())); initialPathLabel.setText(initialPath); destinationPathLabel.setText(destinationPath); @@ -155,7 +155,7 @@ private void closeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-F private void CancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_CancelButtonActionPerformed int response = JOptionPane.showConfirmDialog(null, TranslationCategory.DIALOGS.getTranslation(TranslationKey.INTERRUPT_BACKUP_PROCESS_MESSAGE), TranslationCategory.DIALOGS.getTranslation(TranslationKey.CONFIRMATION_REQUIRED_TITLE), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); if (response == JOptionPane.YES_OPTION) { - ZippingThread.stopExecutorService(1); + progressController.cancelBackup(); this.dispose(); } }//GEN-LAST:event_CancelButtonActionPerformed diff --git a/src/main/java/backupmanager/Helpers/BackupHelper.java b/src/main/java/backupmanager/Helpers/BackupHelper.java index fc34558..9a61b44 100644 --- a/src/main/java/backupmanager/Helpers/BackupHelper.java +++ b/src/main/java/backupmanager/Helpers/BackupHelper.java @@ -2,7 +2,6 @@ import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; -import java.util.Arrays; import java.util.List; import javax.swing.JOptionPane; @@ -15,14 +14,15 @@ import backupmanager.Dialogs.TimePicker; import backupmanager.Entities.ConfigurationBackup; import backupmanager.Entities.TimeInterval; +import backupmanager.Enums.BackupStatus; import backupmanager.Enums.TranslationLoaderEnum.TranslationCategory; import backupmanager.Enums.TranslationLoaderEnum.TranslationKey; import backupmanager.GUI.BackupManagerGUI; import backupmanager.GUI.BackupProgressGUI; -import backupmanager.Managers.ExceptionManager; import backupmanager.Table.BackupTable; import backupmanager.Table.TableDataManager; import backupmanager.database.Repositories.BackupConfigurationRepository; +import backupmanager.database.Repositories.BackupRequestRepository; public class BackupHelper { @@ -71,16 +71,11 @@ public static void updateBackup(ConfigurationBackup updatedBackup) { throw new IllegalArgumentException("Backup is null!"); } - if (updatedBackup.getId() == 0) { - String errorMsg = "Cannot update backup: ID is 0."; - logger.error(errorMsg); - ExceptionManager.openExceptionMessage(errorMsg, Arrays.toString(Thread.currentThread().getStackTrace())); - return; + if (updatedBackup.getId() != 0) { + logger.info("Updating backup: " + updatedBackup.getName()); + BackupConfigurationRepository.updateBackup(updatedBackup); } - logger.info("Updating backup: " + updatedBackup.getName()); - - BackupConfigurationRepository.updateBackup(updatedBackup); updateBackupTable(); } @@ -142,6 +137,11 @@ public static void deleteBackup(int selectedRow, BackupTable backupTable) { } } + public static void forceBackupTermination(int requestId) { + BackupRequestRepository.updateRequestStatusByRequestId(requestId, BackupStatus.TERMINATED); + updateBackupTable(); + } + public static void removeBackup(String backupName) { ConfigurationBackup backup = ConfigurationBackup.getBackupByName(backupName); removeBackup(backup); @@ -158,7 +158,6 @@ private static void updateBackupTable() { TableDataManager.updateTableWithNewBackupList(getBackupList(), formatter); } - // returns the new time inteval public static ConfigurationBackup toggleAutomaticBackup(ConfigurationBackup backup) { logger.info("Event --> automatic backup"); @@ -176,10 +175,12 @@ public static ConfigurationBackup toggleAutomaticBackup(ConfigurationBackup back logger.info("Automatic backup turned off"); updateBackup(backup); + return backup; } - if(!BackupOperations.checkInputCorrect(backup.getName(), backup.getTargetPath(), backup.getDestinationPath(), null)) return null; + if(!BackupOperations.checkInputCorrect(backup.getName(), backup.getTargetPath(), backup.getDestinationPath(), null)) + return null; // if the file has not been saved you need to save it before setting the auto backup if(!backup.isAutomatic() || backup.getNextBackupDate() == null || backup.getTimeIntervalBackup() == null) { @@ -201,6 +202,8 @@ public static ConfigurationBackup toggleAutomaticBackup(ConfigurationBackup back showMessageActivationAutoBackup(timeInterval, backup.getTargetPath(), backup.getDestinationPath()); + updateBackup(backup); + return backup; } diff --git a/src/main/java/backupmanager/Services/PreferenceService.java b/src/main/java/backupmanager/Services/PreferenceService.java new file mode 100644 index 0000000..de92149 --- /dev/null +++ b/src/main/java/backupmanager/Services/PreferenceService.java @@ -0,0 +1,16 @@ +package backupmanager.Services; + + +import java.io.IOException; + +import backupmanager.Entities.Confingurations; +import backupmanager.Enums.ConfigKey; +import backupmanager.Enums.TranslationLoaderEnum; + +public class PreferenceService { + public void updatePreferences(String language, String theme) throws IOException { + Confingurations.setLanguageByLanguageName(language); + Confingurations.setTheme(theme); + TranslationLoaderEnum.loadTranslations(ConfigKey.LANGUAGES_DIRECTORY_STRING.getValue() + Confingurations.getLanguage().getFileName()); + } +} diff --git a/src/main/java/backupmanager/Services/RunningBackupService.java b/src/main/java/backupmanager/Services/RunningBackupService.java index 6cf72c4..96872fd 100644 --- a/src/main/java/backupmanager/Services/RunningBackupService.java +++ b/src/main/java/backupmanager/Services/RunningBackupService.java @@ -7,6 +7,7 @@ import backupmanager.Entities.BackupRequest; import backupmanager.Entities.ConfigurationBackup; import backupmanager.Enums.BackupStatus; +import backupmanager.Helpers.BackupHelper; import backupmanager.Helpers.SqlHelper; import backupmanager.Utils.FolderUtils; import backupmanager.database.Repositories.BackupConfigurationRepository; @@ -31,7 +32,7 @@ public static void updateBackupZippedFolderSizeById(int requestId, String pathFo public static void updateBackupStatusAfterForceTerminationByBackupConfigurationId(int backupConfigurationId) { BackupRequest request = BackupRequestRepository.getLastBackupInProgressByConfigurationId(backupConfigurationId); - BackupRequestRepository.updateRequestStatusByRequestId(request.backupRequestId(), BackupStatus.TERMINATED); + BackupHelper.forceBackupTermination(request.backupRequestId()); } public static void updateBackupStatusAfterCompletitionByBackupConfigurationId(int backupConfigurationId) { diff --git a/src/main/resources/res/config/config.json b/src/main/resources/res/config/config.json index fbba5d0..13fec9a 100644 --- a/src/main/resources/res/config/config.json +++ b/src/main/resources/res/config/config.json @@ -12,7 +12,7 @@ "EMAIL": "assistenza@shardpc.it", "SHARD_WEBSITE": "https://www.shardpc.it/", "LOGO_IMG": "/res/img/logo.png", - "VERSION": "2.2.0", + "VERSION": "2.2.1", "GUI_WIDTH": "982", "GUI_HEIGHT": "715",