All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.datacleaner.windows.AboutDialog Maven / Gradle / Ivy

/**
 * DataCleaner (community edition)
 * Copyright (C) 2014 Free Software Foundation, Inc.
 *
 * This copyrighted material is made available to anyone wishing to use, modify,
 * copy, or redistribute it subject to the terms and conditions of the GNU
 * Lesser General Public License, as published by the Free Software Foundation.
 *
 * 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 Lesser General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this distribution; if not, write to:
 * Free Software Foundation, Inc.
 * 51 Franklin Street, Fifth Floor
 * Boston, MA  02110-1301  USA
 */
package org.datacleaner.windows;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.JToolBar;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;

import org.apache.metamodel.DataContext;
import org.apache.metamodel.csv.CsvConfiguration;
import org.apache.metamodel.csv.CsvDataContext;
import org.apache.metamodel.data.DataSet;
import org.apache.metamodel.data.Row;
import org.apache.metamodel.query.Query;
import org.apache.metamodel.schema.Column;
import org.apache.metamodel.schema.Table;
import org.apache.metamodel.util.FileHelper;
import org.datacleaner.Version;
import org.datacleaner.bootstrap.DCWindowContext;
import org.datacleaner.bootstrap.WindowContext;
import org.datacleaner.panels.DCPanel;
import org.datacleaner.util.IconUtils;
import org.datacleaner.util.ImageManager;
import org.datacleaner.util.ResourceManager;
import org.datacleaner.util.StringUtils;
import org.datacleaner.util.WidgetFactory;
import org.datacleaner.util.WidgetUtils;
import org.datacleaner.widgets.DCLabel;
import org.datacleaner.widgets.DCListCellRenderer;
import org.datacleaner.widgets.tabs.CloseableTabbedPane;
import org.jdesktop.swingx.HorizontalLayout;
import org.jdesktop.swingx.VerticalLayout;
import org.jdesktop.swingx.action.OpenBrowserAction;

/**
 * The "About" dialog of the DataCleaner application.
 */
public class AboutDialog extends AbstractDialog {

    public static class LicensedProject {
        public String name;
        public String websiteUrl;
        public String license;
    }

    private static final long serialVersionUID = 1L;
    private static final ResourceManager resourceManager = ResourceManager.get();
    private static final ImageManager imageManager = ImageManager.get();

    public AboutDialog(final WindowContext windowContext) {
        super(windowContext);
    }

    public static List getLicensedProjects() {
        final List result = new ArrayList<>();
        final URL url = resourceManager.getUrl("licenses/dependency-licenses.csv");
        if (url == null) {
            throw new IllegalStateException("Could not find dependencies file");
        }
        try {
            final DataContext dc = new CsvDataContext(url.openStream(), new CsvConfiguration());
            final Table table = dc.getDefaultSchema().getTable(0);
            final Column projectColumn = table.getColumnByName("Project");
            final Column websiteColumn = table.getColumnByName("Website");
            final Column licenseColumn = table.getColumnByName("License");
            final Query q = dc.query().from(table).select(table.getColumns()).orderBy(projectColumn).asc().toQuery();
            final DataSet ds = dc.executeQuery(q);
            while (ds.next()) {
                final LicensedProject licensedProject = new LicensedProject();
                final Row row = ds.getRow();
                final String licenseName = row.getValue(licenseColumn).toString();

                licensedProject.name = row.getValue(projectColumn).toString();
                licensedProject.websiteUrl = row.getValue(websiteColumn).toString();
                licensedProject.license = getLicense(licenseName);

                result.add(licensedProject);
            }

        } catch (final IOException e) {
            throw new IllegalStateException("Error occurred while reading dependencies file", e);
        }

        return result;
    }

    public static String getLicense(final String licenseName) {
        final URL url = resourceManager.getUrl("licenses/" + licenseName + ".txt");
        if (url == null) {
            throw new IllegalArgumentException("Could not find license file for license: " + licenseName);
        }
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new InputStreamReader(url.openStream(), FileHelper.UTF_8_ENCODING));
            final StringBuilder sb = new StringBuilder();
            for (String line = reader.readLine(); line != null; line = reader.readLine()) {
                if (sb.length() != 0) {
                    sb.append('\n');
                }
                sb.append(line);
            }

            return sb.toString();
        } catch (final Exception e) {
            throw new IllegalStateException("Error occurred while reading license file: " + licenseName, e);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (final IOException e) {
                    // do nothing
                }
            }
        }
    }

    @Override
    public void toFront() {
        super.toFront();
    }

    @Override
    protected String getBannerTitle() {
        return "About DataCleaner";
    }

    @Override
    protected int getDialogWidth() {
        return 650;
    }

    @Override
    protected boolean isWindowResizable() {
        return true;
    }

    @Override
    protected JComponent getDialogContent() {
        final CloseableTabbedPane tabbedPane = new CloseableTabbedPane(true);

        tabbedPane.addTab("About DataCleaner",
                imageManager.getImageIcon(IconUtils.APPLICATION_ICON, IconUtils.ICON_SIZE_LARGE), getAboutPanel(),
                "About DataCleaner");
        tabbedPane.setUnclosableTab(0);

        tabbedPane.addTab("Licensing", imageManager.getImageIcon("images/menu/license.png"), getLicensingPanel(),
                "Licensing");
        tabbedPane.setUnclosableTab(1);

        tabbedPane.setPreferredSize(new Dimension(getDialogWidth(), 500));

        return tabbedPane;
    }

    private JComponent getLicensingPanel() {
        final String dcLicense = getLicense("lgpl");

        final DCLabel licenseHeader = DCLabel.dark("");
        licenseHeader.setFont(WidgetUtils.FONT_HEADER1);

        final DCLabel licenseLabel = DCLabel.darkMultiLine("");
        licenseLabel.setBackground(WidgetUtils.BG_COLOR_BRIGHTEST);
        licenseLabel.setFont(WidgetUtils.FONT_MONOSPACE);
        licenseLabel.setOpaque(true);

        final JButton dcLicenseButton = WidgetFactory.createSmallButton("images/menu/license.png");
        dcLicenseButton.setToolTipText("DataCleaner's license: GNU LGPL");
        dcLicenseButton.addActionListener(e -> {
            licenseHeader.setText("Displaying license of DataCleaner");
            licenseLabel.setText(dcLicense);
        });

        final JComboBox librariesComboBox = new JComboBox<>();
        final JButton visitProjectButton = WidgetFactory.createSmallButton(IconUtils.WEBSITE);

        librariesComboBox.setRenderer(new DCListCellRenderer() {

            private static final long serialVersionUID = 1L;

            @Override
            public Component getListCellRendererComponent(final JList list, final Object value, final int index,
                    final boolean isSelected, final boolean cellHasFocus) {
                if (value instanceof LicensedProject) {
                    final LicensedProject project = (LicensedProject) value;
                    final String name = project.name;
                    return super.getListCellRendererComponent(list, name, index, isSelected, cellHasFocus);
                } else if (value instanceof String) {
                    return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
                }
                throw new UnsupportedOperationException();
            }
        });
        librariesComboBox.addItemListener(e -> {
            final Object item = e.getItem();
            if (item instanceof LicensedProject) {
                visitProjectButton.setEnabled(true);
                final LicensedProject project = (LicensedProject) item;
                licenseLabel.setText(project.license);
                licenseHeader.setText("Displaying license of " + project.name + "");
            } else {
                visitProjectButton.setEnabled(false);
                licenseHeader.setText("Displaying license of DataCleaner");
                licenseLabel.setText(dcLicense);
            }
        });

        visitProjectButton.addActionListener(e -> {
            final Object item = librariesComboBox.getSelectedItem();
            final LicensedProject project = (LicensedProject) item;
            final String websiteUrl = project.websiteUrl;
            if (!StringUtils.isNullOrEmpty(websiteUrl)) {
                new OpenBrowserAction(websiteUrl).actionPerformed(e);
            }
        });

        librariesComboBox.addItem("- select project -");
        final List licensedProjects = getLicensedProjects();
        for (final LicensedProject licensedProject : licensedProjects) {
            librariesComboBox.addItem(licensedProject);
        }

        final JToolBar toolBar = WidgetFactory.createToolBar();
        toolBar.add(DCLabel.dark("DataCleaners license: "));
        toolBar.add(dcLicenseButton);
        toolBar.add(WidgetFactory.createToolBarSeparator());
        toolBar.add(DCLabel.dark("Included libraries: "));
        toolBar.add(librariesComboBox);
        toolBar.add(visitProjectButton);

        final JScrollPane licenseLabelScroll = WidgetUtils.scrolleable(licenseLabel);
        licenseLabelScroll.setBorder(new CompoundBorder(new EmptyBorder(10, 0, 10, 0), WidgetUtils.BORDER_THIN));

        final DCPanel headerPanel = new DCPanel();
        headerPanel.setLayout(new VerticalLayout());
        headerPanel.add(toolBar);
        headerPanel.add(Box.createVerticalStrut(20));
        headerPanel.add(licenseHeader);

        final DCPanel panel = new DCPanel(WidgetUtils.COLOR_DEFAULT_BACKGROUND);
        panel.setBorder(new EmptyBorder(4, 4, 4, 4));
        panel.setLayout(new BorderLayout());
        panel.add(headerPanel, BorderLayout.NORTH);
        panel.add(licenseLabelScroll, BorderLayout.CENTER);

        return panel;
    }

    private JComponent getAboutPanel() {
        final DCLabel headerLabel =
                DCLabel.dark("DataCleaner " + Version.getEdition() + " " + Version.getDistributionVersion());
        headerLabel.setFont(WidgetUtils.FONT_HEADER1);

        final ImageManager imageManager = ImageManager.get();

        final JButton datacleanerButton = new JButton(imageManager.getImageIcon("images/links/datacleaner.png"));
        WidgetUtils.setDefaultButtonStyle(datacleanerButton);
        datacleanerButton.addActionListener(new OpenBrowserAction("https://datacleaner.org"));
        datacleanerButton.setToolTipText("Visit the DataCleaner website");

        final JButton bloggerButton = new JButton(imageManager.getImageIcon("images/links/blogger.png"));
        bloggerButton.addActionListener(new OpenBrowserAction("http://kasper.eobjects.org"));
        bloggerButton.setToolTipText("Follow along at our blog");
        WidgetUtils.setDefaultButtonStyle(bloggerButton);

        final JButton linkedInButton = new JButton(imageManager.getImageIcon("images/links/linkedin.png"));
        linkedInButton.addActionListener(new OpenBrowserAction("http://www.linkedin.com/groups?gid=3352784"));
        linkedInButton.setToolTipText("Join the DataCleaner LinkedIn group");
        WidgetUtils.setDefaultButtonStyle(linkedInButton);

        final DCPanel buttonPanel = new DCPanel();
        buttonPanel.setLayout(new HorizontalLayout());
        buttonPanel.add(datacleanerButton);
        buttonPanel.add(Box.createHorizontalStrut(10));
        buttonPanel.add(bloggerButton);
        buttonPanel.add(Box.createHorizontalStrut(10));
        buttonPanel.add(linkedInButton);

        final DCPanel contentPanel = new DCPanel();
        contentPanel.setLayout(new VerticalLayout());
        contentPanel.add(headerLabel);
        contentPanel.add(DCLabel.dark("Core version " + Version.getVersion()));
        contentPanel.add(DCLabel.dark("Copyright (C) " + Calendar.getInstance().get(Calendar.YEAR)));
        contentPanel.add(Box.createVerticalStrut(20));

        if (Version.isCommunityEdition()) {
            contentPanel.add(Box.createVerticalStrut(20));
            contentPanel.add(DCLabel.dark("Licensed under the LGPL license"));
            contentPanel.add(DCLabel.dark("(see Licensing tab)."));
        } else {
            final String licenseKey = Version.getLicenseKey();
            contentPanel.add(Box.createVerticalStrut(20));
            contentPanel.add(DCLabel.dark("License key: " + licenseKey));
        }

        contentPanel.add(Box.createVerticalStrut(30));
        contentPanel.add(DCLabel.dark("Java runtime information:"));
        contentPanel.add(DCLabel.dark("  " + System.getProperty("java.vm.name")));
        contentPanel.add(DCLabel.dark("  by " + System.getProperty("java.vm.vendor")));
        contentPanel.add(DCLabel.dark("  version " + System.getProperty("java.runtime.version")));
        contentPanel.add(Box.createVerticalStrut(30));
        contentPanel.add(buttonPanel);

        final DCPanel mainPanel = new DCPanel(imageManager.getImage("images/window/app-icon-hires.png"), 97, 10,
                WidgetUtils.COLOR_DEFAULT_BACKGROUND);
        mainPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
        mainPanel.setLayout(new VerticalLayout());
        mainPanel.add(contentPanel);

        return mainPanel;
    }

    @Override
    public String getWindowTitle() {
        return "About DataCleaner | DataCleaner";
    }

    public static void main(final String[] args) {
        new AboutDialog(new DCWindowContext(null, null)).setVisible(true);
    }
}