de.tntinteractive.portalsammler.gui.MainDialog.java Source code

Java tutorial

Introduction

Here is the source code for de.tntinteractive.portalsammler.gui.MainDialog.java

Source

/*
Copyright (C) 2013  Tobias Baum <tbaum at tntinteractive.de>
    
This file is a part of Portalsammler.
    
Portalsammler 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.
    
Portalsammler 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 Portalsammler.  If not, see <http://www.gnu.org/licenses/>.
 */
package de.tntinteractive.portalsammler.gui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JTextField;
import javax.swing.ProgressMonitor;
import javax.swing.SwingWorker;

import org.apache.commons.lang3.tuple.Pair;

import com.jgoodies.forms.builder.ButtonBarBuilder;
import com.jgoodies.forms.builder.PanelBuilder;
import com.jgoodies.forms.factories.CC;
import com.jgoodies.forms.layout.FormLayout;

import de.tntinteractive.portalsammler.engine.CryptoHelper;
import de.tntinteractive.portalsammler.engine.DocumentFilterParser;
import de.tntinteractive.portalsammler.engine.SecureStore;
import de.tntinteractive.portalsammler.engine.Settings;
import de.tntinteractive.portalsammler.engine.SourceSettings;
import de.tntinteractive.portalsammler.sources.DocumentSourceFactory;

public final class MainDialog extends JFrame {

    private static final long serialVersionUID = -2309663260423505246L;

    private final Gui gui;
    private final JTextField filterField;
    private final JButton pollButton;
    private final DocumentTable table;

    public MainDialog(final Gui gui, final SecureStore store) {
        this.setTitle("Portalsammler");
        this.setSize(800, 600);
        this.gui = gui;
        this.table = new DocumentTable(gui, store);

        this.setDefaultCloseOperation(EXIT_ON_CLOSE);

        this.filterField = new JTextField();
        this.filterField.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(final ActionEvent e) {
                MainDialog.this.filter();
            }
        });

        final PanelBuilder fpb = new PanelBuilder(new FormLayout("right:pref, 4dlu, fill:pref:grow", "p"));
        fpb.addLabel("&Filter", CC.xy(1, 1));
        fpb.add(this.filterField, CC.xy(3, 1));

        final ButtonBarBuilder bbb = new ButtonBarBuilder();
        this.pollButton = this.createPollButton();
        bbb.addButton(this.pollButton, this.createConfigButton());

        final PanelBuilder builder = new PanelBuilder(
                new FormLayout("4dlu, fill:pref:grow, 4dlu", "4dlu, p, 4dlu, fill:50dlu:grow, 4dlu, p, 4dlu"));
        builder.add(fpb.getPanel(), CC.xy(2, 2));
        builder.add(this.table.createWrappedPanel(), CC.xy(2, 4));
        builder.add(bbb.getPanel(), CC.xy(2, 6));

        this.setContentPane(builder.getPanel());
        this.setLocationRelativeTo(this.getOwner());
    }

    private void filter() {
        this.table.changeFilter(DocumentFilterParser.parse(this.filterField.getText()));
    }

    private JButton createConfigButton() {
        final JButton button = new JButton("Konfiguration...");
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(final ActionEvent e) {
                final JPopupMenu menu = MainDialog.this.createConfigMenu();
                final JButton source = (JButton) e.getSource();
                menu.show(source, 0, source.getHeight());
            }
        });
        return button;
    }

    private JPopupMenu createConfigMenu() {
        final JPopupMenu menu = new JPopupMenu();

        final JMenuItem sourceConfig = new JMenuItem("Quellen verwalten...");
        sourceConfig.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(final ActionEvent e) {
                MainDialog.this.gui.showConfigGui(MainDialog.this.getStore());
            }
        });
        menu.add(sourceConfig);

        final JMenuItem changePassword = new JMenuItem("Neues Passwort...");
        changePassword.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(final ActionEvent e) {
                try {
                    MainDialog.this.changePassword();
                } catch (final GeneralSecurityException ex) {
                    MainDialog.this.gui.showError(ex);
                } catch (final IOException ex) {
                    MainDialog.this.gui.showError(ex);
                }
            }
        });
        menu.add(changePassword);

        return menu;
    }

    private JButton createPollButton() {
        final JButton button = new JButton("Dokumente abrufen");
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(final ActionEvent e) {
                MainDialog.this.poll(MainDialog.this.gui);
            }
        });
        return button;
    }

    private void poll(final Gui gui) {

        this.pollButton.setEnabled(false);

        final Settings settings = this.getStore().getSettings().deepClone();
        final ProgressMonitor progress = new ProgressMonitor(this, "Sammle Daten aus den Quell-Portalen...", "...",
                0, settings.getSize());
        progress.setMillisToDecideToPopup(0);
        progress.setMillisToPopup(0);
        progress.setProgress(0);

        final SwingWorker<String, String> task = new SwingWorker<String, String>() {

            @Override
            protected String doInBackground() throws Exception {
                final StringBuilder summary = new StringBuilder();
                int cnt = 0;
                for (final String id : settings.getAllSettingIds()) {
                    if (this.isCancelled()) {
                        break;
                    }
                    cnt++;
                    this.publish(cnt + ": " + id);
                    final Pair<Integer, Integer> counts = MainDialog.this.pollSingleSource(settings, id);
                    summary.append(id).append(": ");
                    if (counts != null) {
                        summary.append(counts.getLeft()).append(" neu, ").append(counts.getRight())
                                .append(" schon bekannt\n");
                    } else {
                        summary.append("Fehler!\n");
                    }
                    this.setProgress(cnt);
                }
                MainDialog.this.getStore().writeMetadata();
                return summary.toString();
            }

            @Override
            protected void process(final List<String> ids) {
                progress.setNote(ids.get(ids.size() - 1));
            }

            @Override
            public void done() {
                MainDialog.this.pollButton.setEnabled(true);
                MainDialog.this.table.refreshContents();
                try {
                    final String summary = this.get();
                    JOptionPane.showMessageDialog(MainDialog.this, summary, "Abruf-Zusammenfassung",
                            JOptionPane.INFORMATION_MESSAGE);
                } catch (final Exception e) {
                    gui.showError(e);
                }
            }

        };

        task.addPropertyChangeListener(new PropertyChangeListener() {
            @Override
            public void propertyChange(final PropertyChangeEvent evt) {
                if ("progress".equals(evt.getPropertyName())) {
                    progress.setProgress((Integer) evt.getNewValue());
                }
                if (progress.isCanceled()) {
                    task.cancel(true);
                }
            }
        });

        task.execute();
    }

    private Pair<Integer, Integer> pollSingleSource(final Settings settings, final String id) {
        final SourceSettings s = settings.getSettings(id);
        final DocumentSourceFactory factory = SourceFactories.getByName(s.get(SourceFactories.TYPE, this.gui));
        try {
            return factory.create(id).poll(s, this.gui, this.getStore());
        } catch (final Exception e) {
            this.gui.showError(e);
            return null;
        }
    }

    private void changePassword() throws GeneralSecurityException, IOException {
        final SecureRandom srand = new SecureRandom();
        final byte[] key = CryptoHelper.generateKey(srand);
        this.gui.showGeneratedPassword(CryptoHelper.keyToString(key));

        while (true) {
            final String enteredPw = this.gui.askForPassword(this.getStore().getDirectory());
            if (enteredPw == null) {
                //Abbruch durch den Benutzer
                return;
            }
            if (Arrays.equals(key, CryptoHelper.keyFromString(enteredPw))) {
                //alles OK => ndern kann abgeschlossen werden
                break;
            }
            JOptionPane.showMessageDialog(this, "Das neue Passwort wurde nicht korrekt eingegeben.",
                    "Falsches Passwort", JOptionPane.ERROR_MESSAGE, null);
        }

        this.table.setStore(this.getStore().recrypt(key));
    }

    private SecureStore getStore() {
        return this.table.getStore();
    }

}