Installer.java
package no.ntnu.idatt1002.demo.view;
import java.io.File;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.jar.JarFile;
import java.util.prefs.Preferences;
import org.apache.commons.io.FileUtils;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.stage.DirectoryChooser;
import no.ntnu.idatt1002.demo.ConfigLoader;
import no.ntnu.idatt1002.demo.Logger;
import no.ntnu.idatt1002.demo.Main;
import no.ntnu.idatt1002.demo.view.components.PrimaryButton;
/**
* The installer page.
*
* <p>
* If the application is not installed, e.g. the installed_path property is not
* set in the app.config file, the installer page is shown.
* </p>
*/
public class Installer extends VBox {
private String installationPath;
private onInstalled cb;
public interface onInstalled {
void cb();
}
public Installer(onInstalled cb) {
super();
this.cb = cb;
VBox.setVgrow(this, Priority.ALWAYS);
this.setSpacing(20);
this.getStyleClass().add("centered");
showFolderSelection();
}
private void showFolderSelection() {
this.getChildren().clear();
HBox welcomeContainer = new HBox();
this.getChildren().add(welcomeContainer);
welcomeContainer.getStyleClass().add("centered");
Text welcomeText = new Text("Welcome to " + ConfigLoader.getProperties().getProperty("app_name"));
welcomeText.getStyleClass().add("welcome-text");
welcomeContainer.getChildren().add(welcomeText);
HBox welcomeSubTextContainer = new HBox();
welcomeSubTextContainer.getStyleClass().add("centered");
this.getChildren().add(welcomeSubTextContainer);
Text welcomeSubText = new Text("Where should we install the application?");
welcomeSubText.getStyleClass().add("welcome-sub-text");
welcomeSubTextContainer.getChildren().add(welcomeSubText);
HBox pathContainer = new HBox();
pathContainer.getStyleClass().add("centered");
this.getChildren().add(pathContainer);
PrimaryButton selectPathButton = new PrimaryButton("Select path");
selectPathButton.setPrefSize(200, 65);
selectPathButton.setOnAction(e -> {
DirectoryChooser directoryChooser = new DirectoryChooser();
directoryChooser.setTitle("Select installation path");
File selectedDirectory = directoryChooser.showDialog(null);
if (selectedDirectory != null) {
installationPath = selectedDirectory.getAbsolutePath();
install();
}
});
pathContainer.getChildren().add(selectPathButton);
}
public void install() {
this.getChildren().clear();
HBox progressbarContainer = new HBox();
progressbarContainer.getStyleClass().add("centered");
this.getChildren().add(progressbarContainer);
ProgressBar progressBar = new ProgressBar();
progressBar.setPrefWidth(400);
progressbarContainer.getChildren().add(progressBar);
HBox progressTextContainer = new HBox();
progressTextContainer.getStyleClass().add("centered");
this.getChildren().add(progressTextContainer);
Text progressText = new Text("Installing...");
progressText.getStyleClass().add("welcome-sub-text");
progressTextContainer.getChildren().add(progressText);
// Install the application
Logger.info("Installing application to: " + installationPath);
progressText.setText("Makind directories");
// Make directories
File basedir = new File(
installationPath
+ "/"
+ ConfigLoader.getProperties().getProperty("app_name")
+ "/");
if (!basedir.exists()) {
basedir.mkdirs();
}
progressBar.setProgress(0.5);
progressText.setText("Copying database");
// Copy database
File dbFile = new File(basedir.getAbsolutePath() + "/database/database.sqlite");
if (!dbFile.exists()) {
Logger.info("Copying database from resources to: " + dbFile.getAbsolutePath());
// Copy database file
try {
FileUtils.copyURLToFile(
getClass().getResource("/no/ntnu/idatt1002/database/database.sqlite"),
dbFile);
} catch (Exception e) {
Logger.fatal("Error copying database file: " + e.getMessage());
System.exit(1);
}
}
progressBar.setProgress(0.9);
progressText.setText("Copying images");
// Copy images
File imagesDir = new File(basedir.getAbsolutePath() + "/images");
if (!imagesDir.exists()) {
imagesDir.mkdirs();
}
try {
// Copy image not fund file
Files.copy(getClass().getResourceAsStream("/no/ntnu/idatt1002/images/image-not-found.png"),
new File(imagesDir.getAbsolutePath() + File.separator + "image-not-found.png").toPath(),
StandardCopyOption.REPLACE_EXISTING);
File itemsFolder = new File(imagesDir.getAbsolutePath() + File.separator + "items");
if (!itemsFolder.exists()) {
itemsFolder.mkdirs();
}
File recipesFolder = new File(imagesDir.getAbsolutePath() + File.separator + "recipes");
if (!recipesFolder.exists()) {
recipesFolder.mkdirs();
}
// Get all images from resources
JarFile jarFile = new JarFile(
new File(getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath()));
// Stream all files in the jar
jarFile.stream().forEach(jarEntry -> {
// Check if the file is an image file
if (jarEntry.getName().startsWith("no/ntnu/idatt1002/images/")
&& !jarEntry.getName().equals("no/ntnu/idatt1002/images/image-not-found.png")
&& !jarEntry.getName().equals("no/ntnu/idatt1002/images/")
&& !jarEntry.getName().equals("no/ntnu/idatt1002/images/items/")
&& !jarEntry.getName().equals("no/ntnu/idatt1002/images/recipes/")) {
// Copy the image file
try {
Logger.info("Copying image file: " + jarEntry.getName());
String imageDirectory = jarEntry.getName().substring(
"no/ntnu/idatt1002/images/".length(),
jarEntry.getName().lastIndexOf(File.separator));
Files.copy(getClass().getResourceAsStream("/" + jarEntry.getName()),
new File(imagesDir.getAbsolutePath() + File.separator
+ imageDirectory + File.separator
+ jarEntry.getName().substring(
jarEntry.getName().lastIndexOf("/") + 1))
.toPath(),
StandardCopyOption.REPLACE_EXISTING);
} catch (Exception e) {
Logger.fatal("Error copying image file: " + e.getMessage());
System.exit(1);
}
}
});
jarFile.close();
} catch (Exception e) {
Logger.fatal("Error copying image file: " + e.getMessage());
System.exit(1);
}
progressBar.setProgress(0.99);
progressText.setText("Finishing up");
// Set the installed path
Preferences preferences = Preferences.userNodeForPackage(Main.class);
preferences.put("install_path", installationPath
+ "/"
+ ConfigLoader.getProperties().getProperty("app_name"));
HBox finishContainer = new HBox();
finishContainer.getStyleClass().add("centered");
this.getChildren().add(finishContainer);
PrimaryButton finishButton = new PrimaryButton("Finish");
finishButton.setPrefSize(200, 65);
finishButton.setOnAction(e -> {
this.cb.cb();
});
this.getChildren().add(finishButton);
progressBar.setProgress(1);
progressText.setText("Done! The application has been installed to " + installationPath);
}
}