com.rapid_i.deployment.update.client.ConfirmLicensesDialog.java Source code

Java tutorial

Introduction

Here is the source code for com.rapid_i.deployment.update.client.ConfirmLicensesDialog.java

Source

/*
 *  RapidMiner
 *
 *  Copyright (C) 2001-2014 by RapidMiner and the contributors
 *
 *  Complete list of developers available at our web site:
 *
 *       http://rapidminer.com
 *
 *  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 Affero 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/.
 */
package com.rapid_i.deployment.update.client;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JEditorPane;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import com.itextpdf.text.Font;
import com.rapidminer.deployment.client.wsimport.PackageDescriptor;
import com.rapidminer.deployment.client.wsimport.UpdateService;
import com.rapidminer.gui.tools.ExtendedJScrollPane;
import com.rapidminer.gui.tools.ResourceAction;
import com.rapidminer.gui.tools.ResourceLabel;
import com.rapidminer.gui.tools.SwingTools;
import com.rapidminer.gui.tools.dialogs.ButtonDialog;
import com.rapidminer.tools.I18N;
import com.rapidminer.tools.RMUrlHandler;

/**
 * @author Venkatesh Umaashankar
 *
 */
public class ConfirmLicensesDialog extends ButtonDialog {

    private static final long serialVersionUID = 4276757146820898347L;
    private JButton okButton;
    private JEditorPane licensePane = new JEditorPane("text/html", "");
    private static final int LIST_WIDTH = 330;
    private JList selectedForInstallList;
    private JList dependentPackages;
    private ResourceLabel licenseLabel;
    private Map<String, String> licenseNameToLicenseTextMap;

    private static String LOADING_LICENSE_TEXT = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">"
            + "<html xmlns=\"http://www.w3.org/1999/xhtml\" dir=\"ltr\" lang=\"en\" xml:lang=\"en\">" + "<head>"
            + "<table cellpadding=0 cellspacing=0>" + "<tr><td>" + "<img src=\""
            + SwingTools.getIconPath("48/hourglass.png") + "\" /></td>" + "<td width=\"5\">" + "</td>" + "<td>"
            + I18N.getGUILabel("loading_license") + "</td></tr>" + "</table>" + "</head>" + "</html>";

    private static String ERROR_LOADING_LICENSE_TEXCT = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">"
            + "<html xmlns=\"http://www.w3.org/1999/xhtml\" dir=\"ltr\" lang=\"en\" xml:lang=\"en\">" + "<head>"
            + "<table cellpadding=0 cellspacing=0>" + "<tr><td>" + "<img src=\""
            + SwingTools.getIconPath("48/error.png") + "\" /></td>" + "<td width=\"5\">" + "</td>" + "<td>"
            + I18N.getGUILabel("error_loading_license") + "</td></tr>" + "</table>" + "</head>" + "</html>";

    // this variable checks if license loading has failed. 
    // If so we cannot allow the user to install the packages because he hasn't seen the license
    private boolean licenseLoadingFailed = true;
    private JCheckBox acceptReject;

    public ConfirmLicensesDialog(HashMap<PackageDescriptor, HashSet<PackageDescriptor>> dependency,
            HashMap<String, String> licenseNameToLicenseTextMap) {
        super("confirm_licenses", "updates");
        setModal(true);

        if (licenseNameToLicenseTextMap != null) {
            this.licenseNameToLicenseTextMap = licenseNameToLicenseTextMap;
            licenseLoadingFailed = false;
        } else {
            this.licenseNameToLicenseTextMap = new HashMap<String, String>();
        }

        JPanel main = new JPanel(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        c.fill = GridBagConstraints.BOTH;
        c.anchor = GridBagConstraints.FIRST_LINE_START;
        c.weightx = 0;
        c.weighty = 1;
        c.gridwidth = GridBagConstraints.RELATIVE;

        c.gridx = 0;
        c.weighty = 0;
        c.insets = new Insets(0, 0, 2, 0);
        ResourceLabel label = new ResourceLabel("selected_packages");
        label.setFont(label.getFont().deriveFont(Font.BOLD));
        main.add(label, c);

        Set<PackageDescriptor> selectedPackages = dependency.keySet();
        selectedForInstallList = new JList(selectedPackages.toArray());
        label.setLabelFor(selectedForInstallList);

        HashMap<PackageDescriptor, HashSet<PackageDescriptor>> invertedDependency = new HashMap<PackageDescriptor, HashSet<PackageDescriptor>>();

        for (PackageDescriptor source : selectedPackages) {
            for (PackageDescriptor dep : dependency.get(source)) {
                if (!invertedDependency.containsKey(dep)) {
                    invertedDependency.put(dep, new HashSet<PackageDescriptor>());
                    invertedDependency.get(dep).add(source);
                } else {
                    invertedDependency.get(dep).add(source);
                }
            }
        }

        Set<PackageDescriptor> depPackages = invertedDependency.keySet();
        dependentPackages = new JList(depPackages.toArray());

        c.gridx = 0;
        c.gridy = GridBagConstraints.RELATIVE;
        c.weighty = 1;
        c.insets = new Insets(0, 0, 0, 0);
        JScrollPane selectedForInstallPane = new ExtendedJScrollPane(selectedForInstallList);
        selectedForInstallPane.setMinimumSize(new Dimension(LIST_WIDTH, 100));
        selectedForInstallPane.setPreferredSize(new Dimension(LIST_WIDTH, 100));
        selectedForInstallPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        selectedForInstallPane.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.LIGHT_GRAY));
        selectedForInstallList.addListSelectionListener(new LicenseListSelectionListener(dependentPackages));
        PackageListCellRenderer sourceCellRenderer = new PackageListCellRenderer(null);
        selectedForInstallList.setCellRenderer(sourceCellRenderer);
        main.add(selectedForInstallPane, c);

        c.gridx = 0;
        c.gridy = 2;
        c.weighty = 0;
        c.insets = new Insets(10, 0, 0, 0);
        ResourceLabel dependentLabel = new ResourceLabel("dependent_packages");
        dependentLabel.setFont(dependentLabel.getFont().deriveFont(Font.BOLD));
        dependentLabel.setLabelFor(dependentPackages);
        main.add(dependentLabel, c);

        c.gridx = 0;
        c.gridy = GridBagConstraints.RELATIVE;
        c.weighty = 1;
        c.insets = new Insets(0, 0, 0, 0);
        JScrollPane dependentPackagesPane = new ExtendedJScrollPane(dependentPackages);
        dependentPackagesPane.setMinimumSize(new Dimension(LIST_WIDTH, 100));
        dependentPackagesPane.setPreferredSize(new Dimension(LIST_WIDTH, 100));
        dependentPackagesPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        dependentPackagesPane.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.LIGHT_GRAY));
        dependentPackages.addListSelectionListener(new LicenseListSelectionListener(selectedForInstallList));
        PackageListCellRenderer depCellRenderer = new PackageListCellRenderer(invertedDependency);
        dependentPackages.setCellRenderer(depCellRenderer);
        main.add(dependentPackagesPane, c);

        c.gridx = 1;
        c.gridy = 0;
        c.weighty = 0;
        c.weightx = 1;
        c.insets = new Insets(0, 10, 1, 0);
        ;
        licenseLabel = new ResourceLabel("license_label");
        main.add(licenseLabel, c);

        c.gridx = 1;
        c.gridy = GridBagConstraints.RELATIVE;
        c.gridheight = 4;
        c.insets = new Insets(0, 10, 1, 0);
        licensePane.setEditable(false);
        JScrollPane scrollPane = new JScrollPane(licensePane);
        scrollPane.setPreferredSize(new Dimension(400, 400));
        scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        scrollPane.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.LIGHT_GRAY));
        main.add(scrollPane, c);
        licensePane.addHyperlinkListener(new HyperlinkListener() {

            @Override
            public void hyperlinkUpdate(HyperlinkEvent e) {
                if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
                    RMUrlHandler.handleUrl(e.getDescription());
                }
            }
        });

        acceptReject = new JCheckBox(new ResourceAction("accept_license") {

            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                if (acceptReject.isSelected()) {
                    enableButtons();
                } else {
                    okButton.setEnabled(false);
                }
            }
        });

        okButton = this.makeOkButton("update.install");
        okButton.setText(I18N.getMessage(I18N.getGUIBundle(), "gui.action.update.install.label",
                selectedPackages.size() + depPackages.size()));
        okButton.setEnabled(false);

        layoutDefault(main, HUGE, acceptReject, okButton, makeCancelButton("skip_install"));

        enableButtons();
    }

    private void setInitialSelection() {
        selectedForInstallList.setSelectedIndex(0);
    }

    private void enableButtons() {
        okButton.setEnabled(acceptReject.isSelected() && !licenseLoadingFailed);
        acceptReject.setEnabled(!licenseLoadingFailed);
    }

    private void setLicensePaneContent(final PackageDescriptor desc) {
        licenseLabel.setText(I18N.getMessage(I18N.getGUIBundle(), "gui.label.license_label.label", desc.getName()));

        final String licenseName = desc.getLicenseName();

        String licenseText = licenseNameToLicenseTextMap.get(licenseName);
        if (licenseText != null) {
            setLicenseText(licenseText);
        } else {
            licensePane.setText(LOADING_LICENSE_TEXT);
            new Thread("fetching-license") { //TODO change to progress thread if running more than one progress thread at a time is possible

                @Override
                public void run() {
                    UpdateService service = null;
                    try {
                        service = UpdateManager.getService();
                        String licenseText = service.getLicenseTextHtml(licenseName);
                        licenseNameToLicenseTextMap.put(licenseName, licenseText);
                        licenseLoadingFailed = false;
                        setLicenseText(licenseText);
                    } catch (Exception e) {
                        licenseLoadingFailed = true;
                        setLicenseText(ERROR_LOADING_LICENSE_TEXCT);
                    }
                    enableButtons();
                }

            }.start();
        }

    }

    private void setLicenseText(final String licenseText) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                licensePane.setText(licenseText);
                licensePane.setCaretPosition(0);
            }
        });
    }

    /** Returns true iff the user chooses to confirm the license. 
     * @param licenseNameToLicenseTextMap2 
     * @param numberOfTotalPackages 
     * @param updateModel */
    public static boolean confirm(HashMap<PackageDescriptor, HashSet<PackageDescriptor>> dependency,
            HashMap<String, String> licenseNameToLicenseTextMap) {
        ConfirmLicensesDialog d = new ConfirmLicensesDialog(dependency, licenseNameToLicenseTextMap);
        d.setInitialSelection();
        d.setVisible(true);
        return d.wasConfirmed();
    }

    private class LicenseListSelectionListener implements ListSelectionListener {

        private JList otherList;

        public LicenseListSelectionListener(JList otherList) {
            this.otherList = otherList;
        }

        @Override
        public void valueChanged(ListSelectionEvent e) {
            if (!e.getValueIsAdjusting()) {
                JList source = (JList) e.getSource();
                if (!source.isSelectionEmpty()) {
                    /* 
                    * clear selection in the other list 
                     */
                    if (!otherList.isSelectionEmpty()) {
                        otherList.clearSelection();
                    }

                    PackageDescriptor desc = null;
                    Object selectedValue = ((JList) source).getSelectedValue();
                    desc = (PackageDescriptor) selectedValue;

                    try {
                        setLicensePaneContent(desc);
                    } catch (Exception e1) {
                        SwingTools.showSimpleErrorMessage("error_installing_update", e1, e1.getMessage());
                    }

                }

            }
        }
    }
}