// Path: admin-offline/src/main/java/ch/ge/ve/offlineadmin/controller/InterruptibleProcessController.java
// public abstract class InterruptibleProcessController {
//     public static final String PROCESS_INTERRUPTED_MESSAGE = "Process interrupted";
// 
//     protected abstract ResourceBundle getResourceBundle();
// 
//     /**
//      * Default handling of the exception, displays information in an alert dialog.
//      *
//      * @param e the exception
//      */
//     public void handleInterruption(ProcessInterruptedException e) {
//         if (Platform.isFxApplicationThread()) {
//             showAlert(e);
//         } else {
//             Platform.runLater(() -> showAlert(e));
//         }
//     }
// 
//     private void showAlert(ProcessInterruptedException e) {
//         Alert alert = new Alert(Alert.AlertType.ERROR);
//         ResourceBundle resources = getResourceBundle();
//         alert.setTitle(resources.getString("exception_alert.title"));
//         alert.setHeaderText(resources.getString("exception_alert.header"));
//         alert.setContentText(e.getMessage());
// 
//         StringWriter sw = new StringWriter();
//         PrintWriter pw = new PrintWriter(sw);
//         e.printStackTrace(pw);
//         String exceptionText = sw.toString();
// 
//         Label stackTraceLabel = new Label(resources.getString("exception_alert.label"));
//         TextArea stackTraceTextArea = new TextArea(exceptionText);
//         stackTraceTextArea.setEditable(false);
//         stackTraceTextArea.setWrapText(true);
//         GridPane.setVgrow(stackTraceTextArea, Priority.ALWAYS);
//         GridPane.setHgrow(stackTraceTextArea, Priority.ALWAYS);
// 
//         GridPane expandableContent = new GridPane();
//         expandableContent.setPrefSize(400, 400);
//         expandableContent.setMaxWidth(Double.MAX_VALUE);
//         expandableContent.add(stackTraceLabel, 0, 0);
//         expandableContent.add(stackTraceTextArea, 0, 1);
// 
//         alert.getDialogPane().setExpandableContent(expandableContent);
//         // Dirty Linux only fix...
//         // Expandable zones cause the dialog not to resize correctly
//         if (System.getProperty("os.name").matches(".*[Ll]inux.*")) {
//             alert.getDialogPane().setPrefSize(600, 400);
//             alert.setResizable(true);
//             alert.getDialogPane().setExpanded(true);
//         }
// 
//         alert.showAndWait();
//     }
// }
// 
// Path: admin-offline/src/main/java/ch/ge/ve/offlineadmin/exception/ProcessInterruptedException.java
// public class ProcessInterruptedException extends Exception {
//     /**
//      * Constructor usually used when the interruption was caused by a user action
//      *
//      * @param message the message explaining the interruption
//      */
//     public ProcessInterruptedException(String message) {
//         super(message);
//     }
// 
//     /**
//      * Contructor used when the interruption is caused by a previous exception
//      *
//      * @param message the message explaining the interruption
//      * @param cause   the cause of the interruption
//      */
//     public ProcessInterruptedException(String message, Throwable cause) {
//         super(message, cause);
//     }
// }
// 
// Path: admin-offline/src/main/java/ch/ge/ve/offlineadmin/util/SecurityConstants.java
// public static final String PROPERTIES_LOG4J = "log4j.properties";


import org.apache.log4j.PropertyConfigurator;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.Security;
import java.util.ResourceBundle;
import static ch.ge.ve.offlineadmin.util.SecurityConstants.PROPERTIES_LOG4J;
import ch.ge.ve.offlineadmin.controller.InterruptibleProcessController;
import ch.ge.ve.offlineadmin.exception.ProcessInterruptedException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
package ch.ge.ve.offlineadmin;

/*-
 * #%L
 * Admin offline
 * %%
 * Copyright (C) 2015 - 2016 République et Canton de Genève
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * #L%
 */





/**
 * Main class
 */
public class OfflineAdminApp extends Application {
    /**
     * @param args the arguments passed
     */
    public static void main(String[] args) {
        Security.addProvider(new BouncyCastleProvider());
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        PropertyConfigurator.configure(getLog4jProperties());
        ResourceBundle resourceBundle = getBundle();

        initializeDefaultExceptionHandler(resourceBundle);

        primaryStage.setTitle(resourceBundle.getString("primaryStage.title"));
        primaryStage.getIcons().add(new Image(OfflineAdminApp.class.getResourceAsStream("images/icon.gif")));

        BorderPane rootLayout = initRootLayout(resourceBundle);
        Scene mainScene = new Scene(rootLayout);
        mainScene.getStylesheets().add(getStyleSheet().toExternalForm());

        primaryStage.setScene(mainScene);
        primaryStage.show();
    }

    private void initializeDefaultExceptionHandler(ResourceBundle resourceBundle) {
        InterruptibleProcessController interruptibleProcessController = new InterruptibleProcessController() {
            @Override
            protected ResourceBundle getResourceBundle() {
                return resourceBundle;
            }
        };
        Thread.currentThread().setUncaughtExceptionHandler((t, e) -> {
// Path: admin-offline/src/main/java/ch/ge/ve/offlineadmin/controller/InterruptibleProcessController.java
// public abstract class InterruptibleProcessController {
//     public static final String PROCESS_INTERRUPTED_MESSAGE = "Process interrupted";
// 
//     protected abstract ResourceBundle getResourceBundle();
// 
//     /**
//      * Default handling of the exception, displays information in an alert dialog.
//      *
//      * @param e the exception
//      */
//     public void handleInterruption(ProcessInterruptedException e) {
//         if (Platform.isFxApplicationThread()) {
//             showAlert(e);
//         } else {
//             Platform.runLater(() -> showAlert(e));
//         }
//     }
// 
//     private void showAlert(ProcessInterruptedException e) {
//         Alert alert = new Alert(Alert.AlertType.ERROR);
//         ResourceBundle resources = getResourceBundle();
//         alert.setTitle(resources.getString("exception_alert.title"));
//         alert.setHeaderText(resources.getString("exception_alert.header"));
//         alert.setContentText(e.getMessage());
// 
//         StringWriter sw = new StringWriter();
//         PrintWriter pw = new PrintWriter(sw);
//         e.printStackTrace(pw);
//         String exceptionText = sw.toString();
// 
//         Label stackTraceLabel = new Label(resources.getString("exception_alert.label"));
//         TextArea stackTraceTextArea = new TextArea(exceptionText);
//         stackTraceTextArea.setEditable(false);
//         stackTraceTextArea.setWrapText(true);
//         GridPane.setVgrow(stackTraceTextArea, Priority.ALWAYS);
//         GridPane.setHgrow(stackTraceTextArea, Priority.ALWAYS);
// 
//         GridPane expandableContent = new GridPane();
//         expandableContent.setPrefSize(400, 400);
//         expandableContent.setMaxWidth(Double.MAX_VALUE);
//         expandableContent.add(stackTraceLabel, 0, 0);
//         expandableContent.add(stackTraceTextArea, 0, 1);
// 
//         alert.getDialogPane().setExpandableContent(expandableContent);
//         // Dirty Linux only fix...
//         // Expandable zones cause the dialog not to resize correctly
//         if (System.getProperty("os.name").matches(".*[Ll]inux.*")) {
//             alert.getDialogPane().setPrefSize(600, 400);
//             alert.setResizable(true);
//             alert.getDialogPane().setExpanded(true);
//         }
// 
//         alert.showAndWait();
//     }
// }
// 
// Path: admin-offline/src/main/java/ch/ge/ve/offlineadmin/exception/ProcessInterruptedException.java
// public class ProcessInterruptedException extends Exception {
//     /**
//      * Constructor usually used when the interruption was caused by a user action
//      *
//      * @param message the message explaining the interruption
//      */
//     public ProcessInterruptedException(String message) {
//         super(message);
//     }
// 
//     /**
//      * Contructor used when the interruption is caused by a previous exception
//      *
//      * @param message the message explaining the interruption
//      * @param cause   the cause of the interruption
//      */
//     public ProcessInterruptedException(String message, Throwable cause) {
//         super(message, cause);
//     }
// }
// 
// Path: admin-offline/src/main/java/ch/ge/ve/offlineadmin/util/SecurityConstants.java
// public static final String PROPERTIES_LOG4J = "log4j.properties";


// Path: admin-offline/src/main/java/ch/ge/ve/offlineadmin/OfflineAdminApp.java
import org.apache.log4j.PropertyConfigurator;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.Security;
import java.util.ResourceBundle;
import static ch.ge.ve.offlineadmin.util.SecurityConstants.PROPERTIES_LOG4J;
import ch.ge.ve.offlineadmin.controller.InterruptibleProcessController;
import ch.ge.ve.offlineadmin.exception.ProcessInterruptedException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

package ch.ge.ve.offlineadmin;

/*-
 * #%L
 * Admin offline
 * %%
 * Copyright (C) 2015 - 2016 République et Canton de Genève
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * #L%
 */





/**
 * Main class
 */
public class OfflineAdminApp extends Application {
    /**
     * @param args the arguments passed
     */
    public static void main(String[] args) {
        Security.addProvider(new BouncyCastleProvider());
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        PropertyConfigurator.configure(getLog4jProperties());
        ResourceBundle resourceBundle = getBundle();

        initializeDefaultExceptionHandler(resourceBundle);

        primaryStage.setTitle(resourceBundle.getString("primaryStage.title"));
        primaryStage.getIcons().add(new Image(OfflineAdminApp.class.getResourceAsStream("images/icon.gif")));

        BorderPane rootLayout = initRootLayout(resourceBundle);
        Scene mainScene = new Scene(rootLayout);
        mainScene.getStylesheets().add(getStyleSheet().toExternalForm());

        primaryStage.setScene(mainScene);
        primaryStage.show();
    }

    private void initializeDefaultExceptionHandler(ResourceBundle resourceBundle) {
        InterruptibleProcessController interruptibleProcessController = new InterruptibleProcessController() {
            @Override
            protected ResourceBundle getResourceBundle() {
                return resourceBundle;
            }
        };
        Thread.currentThread().setUncaughtExceptionHandler((t, e) -> {
            final ProcessInterruptedException processInterruptedException = new ProcessInterruptedException(resourceBundle.getString("exception_alert.generic-message"), e);