org.craftercms.social.migration.controllers.MainController.java Source code

Java tutorial

Introduction

Here is the source code for org.craftercms.social.migration.controllers.MainController.java

Source

/*
 * Copyright (C) 2007-2014 Crafter Software Corporation.
 *
 *     This program is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU 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 General Public License
 *     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.craftercms.social.migration.controllers;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Paths;
import java.security.CodeSource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.ResourceBundle;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import javax.xml.transform.TransformerException;

import javafx.application.Platform;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Scene;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.MenuItem;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.RadioButton;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;
import javafx.util.Callback;
import org.apache.commons.io.IOUtils;
import org.craftercms.social.migration.MigrationTool;
import org.craftercms.social.migration.util.MigrationException;
import org.craftercms.social.migration.util.UserLogEntry;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 */
public class MainController implements Initializable {

    private Logger log = LoggerFactory.getLogger(MainController.class);

    @FXML
    private VBox main;

    @FXML
    private MenuItem saveLog;
    @FXML
    private TableView logTable;

    @FXML
    private MenuItem mnuStart;

    @FXML
    private TextField dstHost;
    @FXML
    private TextField dstPort;
    @FXML
    private TextField dstDb;

    @FXML
    private TextField srcHost;
    @FXML
    private TextField srcPort;
    @FXML
    private TextField srcDb;
    @FXML
    private RadioButton rbtMigrateProfile;
    @FXML
    private RadioButton rbtMigrateSocial;
    @FXML
    private MenuItem mnuQuit;
    @FXML
    private ListView lstProfileScripts;
    @FXML
    private ListView lstSocialScripts;
    @FXML
    private MenuItem ctxClearLog;
    @FXML
    private MenuItem ctxReloadProfileScrp;
    @FXML
    private MenuItem ctxReloadSocialScrp;

    @FXML
    private MenuItem ctxClearSocialSelection;

    @FXML
    private MenuItem ctxClearProfileSelection;
    @FXML
    private ProgressBar pgbTaskProgress;

    private MigrationPipeService currentTask;

    private Scene scene;

    private boolean inProgress = false;

    @Override
    public void initialize(final URL location, final ResourceBundle resources) {
        configTable();
        mnuQuit.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(final ActionEvent actionEvent) {
                stopTasks();
                Platform.exit();
            }
        });
        ctxClearLog.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(final ActionEvent actionEvent) {
                logTable.getItems().clear();
            }
        });
        ctxClearProfileSelection.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(final ActionEvent actionEvent) {
                lstProfileScripts.getSelectionModel().clearSelection();
            }
        });
        ctxClearSocialSelection.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(final ActionEvent actionEvent) {
                lstSocialScripts.getSelectionModel().clearSelection();
            }
        });

        lstProfileScripts.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
        lstSocialScripts.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
        lstProfileScripts.setCellFactory(new Callback<ListView, ListCell>() {
            @Override
            public ListCell call(final ListView listView) {
                return new FileListCell();
            }
        });
        lstSocialScripts.setCellFactory(new Callback<ListView, ListCell>() {
            @Override
            public ListCell call(final ListView listView) {
                return new FileListCell();
            }
        });
        ctxReloadProfileScrp.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(final ActionEvent actionEvent) {
                lstProfileScripts.getItems().clear();
                try {
                    extractBuildInScripts("profile", lstProfileScripts);
                } catch (MigrationException e) {
                    log.error("Unable to extract BuildIn scripts");
                }
                loadScripts(MigrationTool.systemProperties.getString("crafter.migration.profile.scripts"),
                        lstProfileScripts);
            }
        });
        ctxReloadSocialScrp.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(final ActionEvent actionEvent) {
                lstSocialScripts.getItems().clear();
                try {
                    extractBuildInScripts("profile", lstSocialScripts);
                } catch (MigrationException e) {
                    log.error("Unable to extract BuildIn scripts");
                }
                loadScripts(MigrationTool.systemProperties.getString("crafter.migration.social.scripts"),
                        lstSocialScripts);
            }
        });
        final MigrationSelectionAction selectionEventHandler = new MigrationSelectionAction();
        rbtMigrateProfile.setOnAction(selectionEventHandler);
        rbtMigrateSocial.setOnAction(selectionEventHandler);
        loadScripts();
        loadDefaultValues();
        saveLog.setAccelerator(new KeyCodeCombination(KeyCode.S, KeyCombination.CONTROL_DOWN));
        saveLog.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(final ActionEvent event) {
                FileChooser fileChooser = new FileChooser();
                fileChooser.setTitle("Save Migration Log");
                fileChooser.setInitialFileName("Crafter-Migration-"
                        + new SimpleDateFormat("yyyy-MM-dd@HH_mm").format(new Date()) + ".html");
                final File savedFile = fileChooser.showSaveDialog(scene.getWindow());
                if (savedFile == null) {
                    return;
                }
                try {
                    getHtml(new FileWriter(savedFile));
                    log.info("Saved Html log file");
                } catch (IOException | TransformerException ex) {
                    log.error("Unable to save file", ex);
                }
            }
        });
        mnuStart.setAccelerator(new KeyCodeCombination(KeyCode.F5));
        mnuStart.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(final ActionEvent event) {

                if (currentTask == null || !currentTask.isRunning()) {
                    ObservableList scriptsToRun;
                    if (rbtMigrateProfile.isSelected()) {
                        scriptsToRun = lstProfileScripts.getSelectionModel().getSelectedItems();
                    } else {
                        scriptsToRun = lstSocialScripts.getSelectionModel().getSelectedItems();
                    }
                    currentTask = new MigrationPipeService(logTable, pgbTaskProgress, srcHost.getText(),
                            srcPort.getText(), srcDb.getText(), dstHost.getText(), dstPort.getText(),
                            dstDb.getText(), scriptsToRun);
                }
                if (!currentTask.isRunning()) {
                    final Thread t = new Thread(currentTask, "Migration Task");
                    t.start();
                }
            }
        });
    }

    public void stopTasks() {
        if (currentTask != null && currentTask.isRunning()) {
            currentTask.cancel();
        }
    }

    private void configTable() {

        TableColumn dateCol = new TableColumn("Date");
        TableColumn messageCol = new TableColumn("Message");
        TableColumn sourceCol = new TableColumn("Source");
        dateCol.setMaxWidth(200);
        dateCol.setPrefWidth(200);
        dateCol.setCellValueFactory(new PropertyValueFactory<UserLogEntry, String>("date"));
        messageCol.setMaxWidth(675);
        messageCol.setPrefWidth(675);
        messageCol.setCellValueFactory(new PropertyValueFactory<UserLogEntry, String>("message"));
        messageCol.setCellFactory(TextFieldTableCell.forTableColumn());
        sourceCol.setMaxWidth(150);
        sourceCol.setPrefWidth(150);
        sourceCol.setCellValueFactory(new PropertyValueFactory<UserLogEntry, String>("source"));
        logTable.getColumns().addAll(dateCol, messageCol, sourceCol);

    }

    private void loadScripts() {
        try {
            extractBuildInScripts("profile", lstProfileScripts);
            extractBuildInScripts("social", lstSocialScripts);
        } catch (MigrationException ex) {
            log.error("Unable to extract Migration Scripts", ex);
        }
        loadScripts(MigrationTool.systemProperties.getString("crafter.migration.profile.scripts"),
                lstProfileScripts);
        loadScripts(MigrationTool.systemProperties.getString("crafter.migration.social.scripts"), lstSocialScripts);
    }

    private void loadBuildInScripts(final String application, final ListView listToAdd) {
        URL profileInternalScriptPath = getClass().getResource("/migration/scripts/" + application);
        if (profileInternalScriptPath != null) {
            loadScripts(profileInternalScriptPath.getFile(), listToAdd);
        } else {
            log.error("Unable to find build in profile scripts");
        }
    }

    protected void loadDefaultValues() {
        dstHost.setText(MigrationTool.systemProperties.getString("crafter.migration.defaultDstHost"));
        dstPort.setText(MigrationTool.systemProperties.getString("crafter.migration.defaultDstPort"));
        /** SRC **/
        srcHost.setText(MigrationTool.systemProperties.getString("crafter.migration.defaultSrcHost"));
        srcPort.setText(MigrationTool.systemProperties.getString("crafter.migration.defaultSrcPort"));
        new MigrationSelectionAction().handle(null);
    }

    protected void extractBuildInScripts(String application, ListView lstToAdd) throws MigrationException {
        CodeSource src = getClass().getProtectionDomain().getCodeSource();
        List<String> list = new ArrayList<String>();
        byte[] buffer = new byte[1024];
        if (src != null) {
            try {
                URL jar = src.getLocation();
                ZipInputStream zip = new ZipInputStream(jar.openStream());
                ZipEntry ze = zip.getNextEntry();
                if (ze == null) {
                    //Running from IDE or Exploded Jar no need to extract!
                    log.debug("Loading files from FS ");
                    loadScripts(getClass().getResource("/" + application).getFile(), lstToAdd);
                } else {
                    while (ze != null) {
                        String entryName = ze.getName();
                        if (entryName.startsWith(application) && entryName.endsWith(".js")) {
                            log.debug("Extracting {} ", entryName);
                            final File extractFile = Paths.get(Paths
                                    .get(MigrationTool.systemProperties
                                            .getString("crafter" + "" + ".migration.profile.scripts"))
                                    .toFile().getParent(), entryName).toFile();
                            if (!extractFile.exists()) {
                                extractFile.createNewFile();
                                FileOutputStream fos = new FileOutputStream(extractFile);
                                int len;
                                while ((len = zip.read(buffer)) > 0) {
                                    fos.write(buffer, 0, len);
                                }
                                fos.close();

                            }
                        }
                        ze = zip.getNextEntry();
                    }
                }
            } catch (IOException ex) {
                log.debug("Unable to load build in scripts", ex);
            }
        } else {
            loadBuildInScripts(application, lstToAdd);
        }
    }

    protected void loadScripts(final String path, final ListView whereToAdd) {

        log.info("Loading migration Scripts from {}", path);
        if (path != null) {
            File profileScriptPath = new File(path);
            if (!profileScriptPath.isDirectory()) {
                log.error("Profile Loading Path {} is not a directory");
                return;
            }
            final File[] scripts = profileScriptPath.listFiles(new FilenameFilter() {
                @Override
                public boolean accept(final File dir, final String name) {
                    return name.endsWith(".js");
                }
            });
            whereToAdd.getItems().addAll(scripts);
        } else {
            log.info("Property is not set using Default Scripts");
            return;
        }
    }

    private String loadTemplateHtml() {
        URL templateUrl = getClass().getResource(
                MigrationTool.systemProperties.getString("crafter.migration" + "" + ".loggerTemplate"));
        if (templateUrl != null) {
            try {
                final InputStream io = getClass().getResourceAsStream(
                        MigrationTool.systemProperties.getString("crafter.migration" + "" + ".loggerTemplate"));
                if (io == null) {
                    return "<h1>Logging template can't be loaded</h1><br/> ";
                }
                return IOUtils.toString(io, "UTF-8");
            } catch (IOException e) {
                return "<h1>Logging template can't be loaded</h1><br/> " + e.toString();
            }
        }
        return "<h1>Logging template can't be loaded</h1>";
    }

    protected void getHtml(final FileWriter writer) throws TransformerException, IOException {
        final URL in = getClass().getResource(
                MigrationTool.systemProperties.getString("crafter" + ".migration" + "" + ".loggerTemplate"));
        if (in == null) {
            log.error("Unable to find {} "
                    + MigrationTool.systemProperties.getString("crafter" + ".migration" + "" + ".loggerTemplate"));
        }
        final Document loggingDoc = Jsoup.parse(IOUtils.toString(in));
        final Element logs = loggingDoc.getElementById("logs");
        for (Object o : logTable.getItems()) {
            if (o instanceof UserLogEntry) {
                UserLogEntry userLogEntry = (UserLogEntry) o;
                String dateFormat = new SimpleDateFormat("yyyy MM dd hh:mm:ss zzz").format(userLogEntry.getDate());
                final Element tr = loggingDoc.createElement("tr");
                tr.attr("class", userLogEntry.getLevel().getCssClass());
                final Element tmigrator = loggingDoc.createElement("td");
                final Element tdate = loggingDoc.createElement("td");
                final Element tmessage = loggingDoc.createElement("td");
                tmessage.attr("class", "text-center");
                tmessage.text(userLogEntry.getMessage());
                tdate.text(dateFormat);
                tmigrator.text(userLogEntry.getSource());
                tr.appendChild(tmigrator);
                tr.appendChild(tdate);
                tr.appendChild(tmessage);
                logs.appendChild(tr);
            }
        }
        IOUtils.write(loggingDoc.toString(), writer);
        //        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        //        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
        //        transformer.setOutputProperty(OutputKeys.METHOD, "xml");
        //        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        //        transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
        //        transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
        //        transformer.transform(new DOMSource(loggingDoc), new StreamResult(writer));
        writer.flush();
        writer.close();
    }

    public void setScene(final Scene scene) {
        this.scene = scene;
    }

    class MigrationSelectionAction implements EventHandler<ActionEvent> {

        @Override
        public void handle(final ActionEvent actionEvent) {
            if (rbtMigrateProfile.isSelected()) {
                srcDb.setText(MigrationTool.systemProperties.getString("crafter.migration.profile.defaultSrcDb"));
            } else {
                srcDb.setText(MigrationTool.systemProperties.getString("crafter.migration.social.defaultSrcDb"));
            }
            if (rbtMigrateProfile.isSelected()) {
                dstDb.setText(MigrationTool.systemProperties.getString("crafter.migration.profile.defaultDstDb"));
            } else {
                dstDb.setText(MigrationTool.systemProperties.getString("crafter.migration.social.defaultDstDb"));
            }
        }
    }

    class FileListCell extends ListCell<File> {
        @Override
        protected void updateItem(final File file, final boolean b) {
            super.updateItem(file, b);
            if (file != null) {
                setText(file.getName());
            }
        }
    }

}