cz.cvut.promod.EPC2XHTMLExport.ui.ExporterSettingsController.java Source code

Java tutorial

Introduction

Here is the source code for cz.cvut.promod.EPC2XHTMLExport.ui.ExporterSettingsController.java

Source

/****************************************************************************
** This file may be used under the terms of the MIT licence:
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and associated documentation files (the "Software"), to deal
** in the Software without restriction, including without limitation the rights
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
** copies of the Software, and to permit persons to whom the Software is
** furnished to do so, subject to the following conditions:
**
** The above copyright notice and this permission notice shall be included in
** all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
** THE SOFTWARE.
****************************************************************************/

package cz.cvut.promod.EPC2XHTMLExport.ui;

import com.jgoodies.binding.PresentationModel;
import cz.cvut.promod.EPC2XHTMLExport.EPC2XHTMLExportModule;
import cz.cvut.promod.EPC2XHTMLExport.engine.ExporterEngine;
import cz.cvut.promod.EPC2XHTMLExport.resources.Resources;
import cz.cvut.promod.epc.workspace.EPCWorkspaceData;
import cz.cvut.promod.gui.support.utils.NotationGuiHolder;
import cz.cvut.promod.plugin.notationSpecificPlugIn.DockableFrameData;
import cz.cvut.promod.services.ModelerSession;
import cz.cvut.promod.services.actionService.actionUtils.ProModAction;
import cz.cvut.promod.services.projectService.treeProjectNode.ProjectDiagram;
import cz.cvut.promod.services.projectService.treeProjectNode.ProjectRoot;
import org.apache.log4j.Logger;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

/**
 * Created by IntelliJ IDEA.
 * User: Vaclav Zuna
 * Date: Oct 6, 2010
 * Time: 4:05:38 PM
 *
 * This is the controller (see MVC pattern) of the only part of this module that interacts
 * with the user. The Exporter Settings dockable window gathers user input to alter the way
 * the diagram is exported. The controller creates the view and model part and serves as a
 * mean of communication between them and the ExporterEngine. It interprets the data the user
 * has given to the view class, saves it in the model and if the input is valid it is forwarded
 * to the ExporterEngine, which produces output.
 */
public class ExporterSettingsController extends ExporterSettingsView implements DockableFrameData, ActionListener {

    private static final Logger LOG = Logger.getLogger(ExporterSettingsController.class);

    private final static String FRAME_TITLE_RES = "epc.export.xhtml.framelabel";
    private final static String ERR_DIALOG_TITLE_RES = "epc.export.xhtml.error.title";
    private final static String ERR_DIALOG_MESSAGE_RES = "epc.export.xhtml.error.message";
    private final static String ERR_DIALOG_TITLE_OPEN_RES = "epc.export.xhtml.error.title.open";
    private final static String ERR_DIALOG_MESSAGE_OPEN_RES = "epc.export.xhtml.error.message.open";
    private final static String SUC_DIALOG_TITLE_RES = "epc.export.xhtml.success.title";
    private final static String SUC_DIALOG_MESSAGE_RES = "epc.export.xhtml.success.message";

    private final static String CONFIRM_DIALOG_MESSAGE_OVEWRITE = "epc.export.xhtml.confirm.message";
    private final static String CONFIRM_DIALOG_TITLE_OVEWRITE = "epc.export.xhtml.confirm.title";

    private static final String CFG_FORMAT_RES = "epc.export.xhtml.config.format";
    private static final String CFG_THEME_RES = "epc.export.xhtml.config.theme";
    private static final String CFG_NOTES_RES = "epc.export.xhtml.config.notes";
    private static final String CFG_OPENWITHCHOICE_RES = "epc.export.xhtml.config.openwithchoice";
    private static final String CFG_OPENWITHPATH_RES = "epc.export.xhtml.config.openwithpath";

    private String EPC2XHTML_EXPORT_ACTION_RES;

    private ExporterSettingsView view;
    private ExporterSettingsModel model;
    private final EPCWorkspaceData workspace;

    private ProModAction action;

    private final PresentationModel<ExporterSettingsModel> presentationModel;

    /**
     * The constructor creates the view component and registers as its listener, it also creates
     * the model component initializes the received actions.
     *
     * @param epcWorkspaceData - graph data
     * @param actions          - actions related to this module, includes the export action
     * @param EPC2XHTML_EXPORT_ACTION_RES - resource identifier of the export action
     */
    public ExporterSettingsController(final EPCWorkspaceData epcWorkspaceData,
            final Map<String, ProModAction> actions, final String EPC2XHTML_EXPORT_ACTION_RES) {

        this.EPC2XHTML_EXPORT_ACTION_RES = EPC2XHTML_EXPORT_ACTION_RES;

        model = new ExporterSettingsModel();
        view = new ExporterSettingsView();
        view.registerListener(this);
        workspace = epcWorkspaceData;

        presentationModel = new PresentationModel<ExporterSettingsModel>(model);

        initActions(actions);
    }

    private void initActions(final Map<String, ProModAction> actions) {
        action = new ProModAction(Resources.getStrRes(EPC2XHTML_EXPORT_ACTION_RES), null, null) {

            public void actionPerformed(ActionEvent event) {
                export();
            }
        };
        actions.put(EPC2XHTML_EXPORT_ACTION_RES, action);
    }

    /**
     * @obsolete
     */
    public String getDockableFrameName() {
        return "epc.xhtml.export.xyz";
    }

    /**
     * @return the view component for display purposes
     */
    public JComponent getDockableFrameComponent() {
        return view;
    }

    /**
     * @return the initial position of the dockable frame in which the view component resides
     */
    public NotationGuiHolder.Position getInitialPosition() {
        return NotationGuiHolder.Position.BOTTOM;
    }

    /**
     * @return whether the windows is maximalizable or not
     */
    public boolean isMaximizable() {
        return false;
    }

    /**
     * @return all available docking positions of the dockable frame
     */
    public Set<NotationGuiHolder.Position> getAllowedDockableFramePositions() {
        final Set<NotationGuiHolder.Position> positions = new HashSet<NotationGuiHolder.Position>();
        positions.add(NotationGuiHolder.Position.BOTTOM);
        positions.add(NotationGuiHolder.Position.TOP);

        return positions;
    }

    /**
     * @returns the InitialState (visibility) of the dockable frame
     */
    public InitialState getInitialState() {
        return InitialState.HIDDEN;
    }

    /**
     * @return the title of the dockable frame
     */
    public String getDockableFrameTitle() {
        return Resources.getStrRes(FRAME_TITLE_RES);
    }

    public Icon getButtonIcon() {
        return null;
    }

    public PresentationModel<ExporterSettingsModel> getPresentationModel() {
        return presentationModel;
    }

    /**
     * Callback from the view component when the user chooses to initiate the export action.
     * This saves the state of the gui, saving the choices of the user for future use (this
     * persists even through application restart). The export can fail for many reasons, and
     * and all results are handled to the user via dialog messages. The post export action
     * (e.g. opening the exported document using the default application) is also handled here.
     */
    public void actionPerformed(ActionEvent e) {
        export();
    }

    private void export() {
        saveConfig();

        model.setPath(view.getDir() + System.getProperty("file.separator"));
        model.setName(view.getName());
        model.setNotes(view.getNotes());
        model.setFormat(view.getFormat());
        model.setTheme(view.getTheme());
        model.setOpenWithChoice(view.getOpenWithChoice());
        model.setOpenWithPath(view.getOpenWithPath());

        ProjectDiagram diagram = ModelerSession.getProjectService().getSelectedDiagram();
        if (diagram == null)
            model.setTitle("null");
        else
            model.setTitle(diagram.getDisplayName());

        ExporterEngine engine = new ExporterEngine(workspace, model);

        // test whether the file already exists
        if (engine.isColliding()) {
            LOG.info("epc to xhtml export detected existing file(s) collision");

            if (JOptionPane.showConfirmDialog(view, Resources.getStrRes(CONFIRM_DIALOG_MESSAGE_OVEWRITE),
                    Resources.getStrRes(CONFIRM_DIALOG_TITLE_OVEWRITE), JOptionPane.YES_NO_OPTION,
                    JOptionPane.QUESTION_MESSAGE) == JOptionPane.NO_OPTION) {
                LOG.info("epc to xhtml export canceled because of existing file(s) collision");
                return;
            }
            LOG.info("epc to xhtml export continues");
        }

        // attempts to export the diagram using previously chosen settings
        try {
            engine.export();
        } catch (IOException ex) {
            String message = ex.getMessage();
            if (message == null || message.isEmpty())
                message = Resources.getStrRes(ERR_DIALOG_MESSAGE_RES);
            JOptionPane.showMessageDialog(view, message, Resources.getStrRes(ERR_DIALOG_TITLE_RES),
                    JOptionPane.ERROR_MESSAGE);
            LOG.error("epc to xhtml export failed");
            return;
        }

        int open = view.getOpenWithChoice();
        String url = model.getPath() + model.getName();

        switch (model.getFormat()) {
        case eXHTMLFolder:
            url += ".html";
            break;
        case eDokuWiki:
            url += ".txt";
            break;
        case eLaTeXFolder:
            url += ".tex";
            break;
        }

        // performs the post export action
        if (open == 0) {
            JOptionPane.showMessageDialog(view, Resources.getStrRes(SUC_DIALOG_MESSAGE_RES),
                    Resources.getStrRes(SUC_DIALOG_TITLE_RES), JOptionPane.INFORMATION_MESSAGE);
        } else if (open == 1) {
            boolean success = false;
            try {
                if (Desktop.isDesktopSupported()) {
                    Desktop dt = Desktop.getDesktop();
                    if (dt.isSupported(Desktop.Action.OPEN)) {
                        dt.open(new File(url));
                        success = true;
                    }
                }
            } catch (IOException ioe) {
            }
            if (!success) {
                JOptionPane.showMessageDialog(view, Resources.getStrRes(ERR_DIALOG_MESSAGE_OPEN_RES),
                        Resources.getStrRes(ERR_DIALOG_TITLE_OPEN_RES), JOptionPane.ERROR_MESSAGE);
                LOG.error("could not open default the file in the default application!");
            }
        } else {
            String osName = System.getProperty("os.name");

            try {
                if (osName.startsWith("Mac OS")) {
                    // NOT TESTED
                    Runtime.getRuntime().exec(view.getOpenWithPath() + " \"" + url + "\"");
                } else if (osName.startsWith("Windows")) {
                    // TESTED WITH firefox, chrome
                    Runtime.getRuntime().exec(view.getOpenWithPath() + " \"" + url + "\"");
                } else { //assume Unix or Linux
                    // NOT TESTED
                    Runtime.getRuntime().exec(view.getOpenWithPath() + " \"" + url + "\"");
                }
            } catch (IOException ioe) {
                JOptionPane.showMessageDialog(view, Resources.getStrRes(ERR_DIALOG_MESSAGE_OPEN_RES),
                        Resources.getStrRes(ERR_DIALOG_TITLE_OPEN_RES), JOptionPane.ERROR_MESSAGE);
                LOG.error("could not open url with specified application");
            }
        }
        LOG.info("epc to xhtml export succeeded");

    }

    /**
     * Loads persistent GUI data from the properties file. This mean that the user
     * will not have to choose the same choices all over again when (s)he needs to repeat a task.
     */
    public void loadConfig() {
        // not sure if this actually returns information about the selected or opened project/diagram
        // it does not work as expected for now (configs do, just the project/diagram part does not)
        ProjectRoot project = ModelerSession.getProjectService().getSelectedProject();
        ProjectDiagram diagram = ModelerSession.getProjectService().getSelectedDiagram();

        if (project != null)
            view.setDir(project.getProjectLocation());
        else
            view.setDir(System.getProperty("user.home"));

        if (project != null && diagram != null)
            view.setName(project.getDisplayName() + "_" + diagram.getDisplayName());
        else
            view.setName("epcdiagram");

        String cfg;
        int i;
        Properties properties = EPC2XHTMLExportModule.properties;

        cfg = properties.getProperty(CFG_FORMAT_RES);
        if (cfg != null && !cfg.isEmpty()) {
            i = (int) cfg.charAt(0) - 48;
            ExporterSettingsModel.ExportFormat formats[] = ExporterSettingsModel.ExportFormat.values();
            if (i < 0 || i > formats.length)
                LOG.error("ERROR: invalid property '" + CFG_FORMAT_RES + "' value '" + i + "'");
            else
                view.setFormat(formats[i]);
        }

        cfg = properties.getProperty(CFG_THEME_RES);
        if (cfg != null && !cfg.isEmpty()) {
            i = (int) cfg.charAt(0) - 48;
            if (i > 0 && i < 2)
                view.setTheme(i);
        }

        cfg = properties.getProperty(CFG_NOTES_RES);
        if (cfg != null && !cfg.isEmpty()) {
            i = (int) cfg.charAt(0) - 48;
            if (i == 0)
                view.setNotes(false);
            if (i == 1)
                view.setNotes(true);
        }

        cfg = properties.getProperty(CFG_OPENWITHCHOICE_RES);
        if (cfg != null && !cfg.isEmpty()) {
            i = (int) cfg.charAt(0) - 48;
            view.setOpenWithChoice(i);
        }

        cfg = properties.getProperty(CFG_OPENWITHPATH_RES);
        if (cfg != null && !cfg.isEmpty())
            view.setOpenWithPath(cfg);
    }

    /**
     * Saves the persistent GUI data, @see loadConfig() 
     */
    public void saveConfig() {

        Properties properties = EPC2XHTMLExportModule.properties;

        String cfg;

        switch (view.getFormat()) {
        case eXHTMLFolder:
            cfg = "0";
            break;
        case eDokuWiki:
            cfg = "1";
            break;
        default:
            cfg = "2";
            break;
        }
        properties.setProperty(CFG_FORMAT_RES, cfg);

        switch (view.getTheme()) {
        case eClassicBlack:
            cfg = "0";
            break;
        default:
            cfg = "3";
            break;
        }
        properties.setProperty(CFG_THEME_RES, cfg);

        cfg = view.getNotes() ? "1" : "0";
        properties.setProperty(CFG_NOTES_RES, cfg);

        cfg = Integer.toString(view.getOpenWithChoice());
        properties.setProperty(CFG_OPENWITHCHOICE_RES, cfg);

        cfg = view.getOpenWithPath();
        if (cfg.isEmpty())
            cfg = "Choose an application...";
        properties.setProperty(CFG_OPENWITHPATH_RES, cfg);

        try {
            properties.store(new FileOutputStream(EPC2XHTMLExportModule.propertiesFile), "");
        } catch (Exception e) {
            LOG.error("failed to store config!");
        }
    }
}