net.sf.taverna.t2.workbench.ui.impl.UserRegistrationForm.java Source code

Java tutorial

Introduction

Here is the source code for net.sf.taverna.t2.workbench.ui.impl.UserRegistrationForm.java

Source

/*******************************************************************************
 * Copyright (C) 2007 The University of Manchester
 *
 *  Modifications to the initial code base are copyright of their
 *  respective authors, or their employers as appropriate.
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public License
 *  as published by the Free Software Foundation; either version 2.1 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 ******************************************************************************/
package net.sf.taverna.t2.workbench.ui.impl;

import static java.awt.BorderLayout.CENTER;
import static java.awt.BorderLayout.NORTH;
import static java.awt.Color.LIGHT_GRAY;
import static java.awt.Color.WHITE;
import static java.awt.FlowLayout.LEFT;
import static java.awt.Font.BOLD;
import static java.awt.GridBagConstraints.FIRST_LINE_START;
import static java.awt.GridBagConstraints.HORIZONTAL;
import static java.awt.GridBagConstraints.LINE_START;
import static java.awt.GridBagConstraints.NONE;
import static java.awt.GridBagConstraints.WEST;
import static java.awt.event.KeyEvent.VK_ENTER;
import static java.awt.event.KeyEvent.VK_TAB;
import static javax.swing.JOptionPane.ERROR_MESSAGE;
import static javax.swing.JOptionPane.showMessageDialog;
import static javax.swing.SwingConstants.BOTTOM;
import static javax.swing.SwingConstants.TOP;
import static javax.swing.event.HyperlinkEvent.EventType.ACTIVATED;
import static net.sf.taverna.t2.workbench.icons.WorkbenchIcons.tavernaCogs32x32Icon;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.ConnectException;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.Properties;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JEditorPane;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.Border;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import javax.swing.text.Document;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.StyleSheet;

import net.sf.taverna.t2.lang.ui.DialogTextArea;
import net.sf.taverna.t2.workbench.helper.HelpEnabledDialog;

import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;

/**
 * User registration form.
 * 
 * @author Alex Nenadic
 */
@SuppressWarnings("serial")
public class UserRegistrationForm extends HelpEnabledDialog {
    private static final String FAILED = "User registration failed: ";

    private static final String REGISTRATION_FAILED_MSG = "User registration failed. Please try again later.";

    private static final String REGISTRATION_URL = "http://www.mygrid.org.uk/taverna/registration/";

    public static final String TAVERNA_VERSION_PROPERTY_NAME = "Taverna version";
    public static final String FIRST_NAME_PROPERTY_NAME = "First name";
    public static final String LAST_NAME_PROPERTY_NAME = "Last name";
    public static final String EMAIL_ADDRESS_PROPERTY_NAME = "Email address";
    public static final String INSTITUTION_OR_COMPANY_PROPERTY_NAME = "Institution or company name";
    public static final String INDUSTRY_PROPERTY_NAME = "Industry";
    public static final String FIELD_PROPERTY_NAME = "Field of investigation";
    public static final String PURPOSE_PROPERTY_NAME = "Purpose of using Taverna";
    public static final String KEEP_ME_INFORMED_PROPERTY_NAME = "Keep me informed by email";

    public static final String TAVERNA_REGISTRATION_POST_PARAMETER_NAME = "taverna_registration";
    public static final String TAVERNA_VERSION_POST_PARAMETER_NAME = "taverna_version";
    public static final String FIRST_NAME_POST_PARAMETER_NAME = "first_name";
    public static final String LAST_NAME_POST_PARAMETER_NAME = "last_name";
    public static final String EMAIL_ADDRESS_POST_PARAMETER_NAME = "email";
    public static final String INSTITUTION_OR_COMPANY_POST_PARAMETER_NAME = "institution_or_company";
    public static final String INDUSTRY_TYPE_POST_PARAMETER_NAME = "industry_type";
    public static final String FIELD_POST_PARAMETER_NAME = "field";
    public static final String PURPOSE_POST_PARAMETER_NAME = "purpose";
    public static final String KEEP_ME_INFORMED_POST_PARAMETER_PROPERTY_NAME = "keep_me_informed";

    private static String TRUE = Boolean.TRUE.toString();
    private static String FALSE = Boolean.FALSE.toString();

    private static final String WELCOME = "Welcome to the Taverna User Registration Form";
    private static final String PLEASE_FILL_IN_THIS_REGISTRATION_FORM = "Please fill in this registration form to let us know that you are using Taverna";

    private static final String WE_DO = "Note that by registering:\n"
            + "   \u25CF We do not have access to your data\n"
            + "   \u25CF We do not have access to your service usage\n" + "   \u25CF You will not be monitored\n"
            + "   \u25CF We do record the information you provide\n" + "     at registration time";

    private static final String WHY_REGISTER = "By registering you will:\n"
            + "   \u25CF Allow us to support you better; future plans will be\n"
            + "     directed towards solutions Taverna users require\n"
            + "   \u25CF Help sustain Taverna development; our continued\n"
            + "     funding relies on us showing usage\n"
            + "   \u25CF (Optionally) Hear about news and product updates";

    private static final String FIRST_NAME = "*First name:";
    private static final String LAST_NAME = "*Last name:";
    private static final String EMAIL_ADDRESS = "*Email address:";
    private static final String KEEP_ME_INFORMED = "Keep me informed of news and product updates via email";
    private static final String INSTITUTION_COMPANY_NAME = "*Institution/Company name:";
    private static final String FIELD_OF_INVESTIGATION = " Field of investigation:\n" + " (e.g. bioinformatics)";
    private static final String WHY_YOU_INTEND_TO_USE_TAVERNA = " A brief description of how you intend\n"
            + " to use Taverna: (e.g. genome analysis\n" + " for bacterial strain identification)";

    private static String[] industryTypes = { "", "Academia - Life Sciences", "Academia - Social Sciences",
            "Academia - Physical Sciences", "Academia - Environmental Sciences", "Academia - Other",
            "Industry - Biotechnology", "Industry - Pharmaceutical", "Industry - Engineering", "Industry - Other",
            "Healthcare Services", "Goverment and Public Sector", "Other" };

    private static final String I_AGREE_TO_THE_TERMS_AND_CONDITIONS = "I agree to the terms and conditions of registration at";
    private static final String TERMS_AND_CONDITIONS_URL = "http://www.taverna.org.uk/legal/terms";

    private Logger logger = Logger.getLogger(UserRegistrationForm.class);
    private UserRegistrationData previousRegistrationData;
    private JTextField firstNameTextField;
    private JTextField lastNameTextField;
    private JTextField emailTextField;
    private JCheckBox keepMeInformedCheckBox;
    private JTextField institutionOrCompanyTextField;
    private JComboBox<String> industryTypeTextField;
    private JTextField fieldTextField;
    private JTextArea purposeTextArea;
    private JCheckBox termsAndConditionsCheckBox;

    private final File registrationDataFile;
    private final File remindMeLaterFile;
    private final File doNotRegisterMeFile;
    private final String appName;

    public UserRegistrationForm(String appName, File registrationDataFile, File doNotRegisterMeFile,
            File remindMeLaterFile) {
        super((Frame) null, "Taverna User Registration", true);
        this.appName = appName;
        this.registrationDataFile = registrationDataFile;
        this.doNotRegisterMeFile = doNotRegisterMeFile;
        this.remindMeLaterFile = remindMeLaterFile;
        initComponents();
    }

    public UserRegistrationForm(String appName, File previousRegistrationDataFile, File registrationDataFile,
            File doNotRegisterMeFile, File remindMeLaterFile) {
        super((Frame) null, "Taverna User Registration", true);
        this.appName = appName;
        this.registrationDataFile = registrationDataFile;
        this.doNotRegisterMeFile = doNotRegisterMeFile;
        this.remindMeLaterFile = remindMeLaterFile;
        previousRegistrationData = loadUserRegistrationData(previousRegistrationDataFile);
        initComponents();
    }

    // For testing only
    // public static void main(String[] args) throws ClassNotFoundException,
    // InstantiationException, IllegalAccessException,
    // UnsupportedLookAndFeelException{
    // WorkbenchImpl.setLookAndFeel();
    // UserRegistrationForm form = new UserRegistrationForm();
    // form.setVisible(true);
    // }

    private void initComponents() {
        JPanel mainPanel = new JPanel(new GridBagLayout());

        // Base font for all components on the form
        Font baseFont = new JLabel("base font").getFont().deriveFont(11f);

        // Title panel
        JPanel titlePanel = new JPanel(new FlowLayout(LEFT));
        titlePanel.setBackground(WHITE);
        // titlePanel.setBorder(new EmptyBorder(10, 10, 10, 10));
        JLabel titleLabel = new JLabel(WELCOME);
        titleLabel.setFont(baseFont.deriveFont(BOLD, 13.5f));
        // titleLabel.setBorder(new EmptyBorder(10, 10, 0, 10));
        JLabel titleIcon = new JLabel(tavernaCogs32x32Icon);
        // titleIcon.setBorder(new EmptyBorder(10, 10, 10, 10));
        DialogTextArea titleMessage = new DialogTextArea(PLEASE_FILL_IN_THIS_REGISTRATION_FORM);
        titleMessage.setMargin(new Insets(0, 20, 0, 10));
        titleMessage.setFont(baseFont);
        titleMessage.setEditable(false);
        titleMessage.setFocusable(false);
        // titlePanel.setBorder( new EmptyBorder(10, 10, 0, 10));
        JPanel messagePanel = new JPanel(new BorderLayout());
        messagePanel.add(titleLabel, NORTH);
        messagePanel.add(titleMessage, CENTER);
        messagePanel.setBackground(WHITE);
        titlePanel.add(titleIcon);
        titlePanel.add(messagePanel);
        addDivider(titlePanel, BOTTOM, true);

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.weightx = 1.0;
        gbc.weighty = 0.0;
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.fill = HORIZONTAL;
        gbc.anchor = WEST;
        gbc.gridwidth = 2;
        // gbc.insets = new Insets(5, 10, 0, 0);
        mainPanel.add(titlePanel, gbc);

        // Registration messages
        gbc.weightx = 0.0;
        gbc.weighty = 0.0;
        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.fill = NONE;
        gbc.anchor = WEST;
        gbc.gridwidth = 2;
        // gbc.insets = new Insets(5, 0, 0, 10);
        DialogTextArea registrationMessage1 = new DialogTextArea(WHY_REGISTER);
        registrationMessage1.setMargin(new Insets(0, 10, 0, 0));
        registrationMessage1.setFont(baseFont);
        registrationMessage1.setEditable(false);
        registrationMessage1.setFocusable(false);
        registrationMessage1.setBackground(getBackground());

        DialogTextArea registrationMessage2 = new DialogTextArea(WE_DO);
        registrationMessage2.setMargin(new Insets(0, 10, 0, 10));
        registrationMessage2.setFont(baseFont);
        registrationMessage2.setEditable(false);
        registrationMessage2.setFocusable(false);
        registrationMessage2.setBackground(getBackground());
        JPanel registrationMessagePanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        registrationMessagePanel.add(registrationMessage1);
        registrationMessagePanel.add(registrationMessage2);
        addDivider(registrationMessagePanel, BOTTOM, true);
        mainPanel.add(registrationMessagePanel, gbc);

        // Mandatory label
        // JLabel mandatoryLabel = new JLabel("* Mandatory fields");
        // mandatoryLabel.setFont(baseFont);
        // gbc.weightx = 0.0;
        // gbc.weighty = 0.0;
        // gbc.gridx = 0;
        // gbc.gridy = 3;
        // gbc.fill = NONE;
        // gbc.anchor = GridBagConstraints.EAST;
        // gbc.gridwidth = 2;
        // gbc.insets = new Insets(0, 10, 0, 20);
        // mainPanel.add(mandatoryLabel, gbc);

        // First name
        JLabel firstNameLabel = new JLabel(FIRST_NAME);
        firstNameLabel.setFont(baseFont);
        gbc.weightx = 0.0;
        gbc.weighty = 0.0;
        gbc.gridx = 0;
        gbc.gridy = 4;
        gbc.fill = NONE;
        gbc.anchor = WEST;
        gbc.gridwidth = 1;
        gbc.insets = new Insets(0, 10, 0, 10);
        mainPanel.add(firstNameLabel, gbc);

        firstNameTextField = new JTextField();
        firstNameTextField.setFont(baseFont);
        if (previousRegistrationData != null)
            firstNameTextField.setText(previousRegistrationData.getFirstName());
        gbc.weightx = 1.0;
        gbc.weighty = 0.0;
        gbc.gridx = 1;
        gbc.gridy = 4;
        gbc.fill = HORIZONTAL;
        gbc.anchor = WEST;
        gbc.gridwidth = 1;
        gbc.insets = new Insets(5, 10, 0, 10);
        mainPanel.add(firstNameTextField, gbc);

        // Last name
        JLabel lastNameLabel = new JLabel(LAST_NAME);
        lastNameLabel.setFont(baseFont);
        gbc.weightx = 0.0;
        gbc.weighty = 0.0;
        gbc.gridx = 0;
        gbc.gridy = 5;
        gbc.fill = NONE;
        gbc.anchor = WEST;
        gbc.gridwidth = 1;
        gbc.insets = new Insets(0, 10, 0, 10);
        mainPanel.add(lastNameLabel, gbc);

        lastNameTextField = new JTextField();
        lastNameTextField.setFont(baseFont);
        if (previousRegistrationData != null)
            lastNameTextField.setText(previousRegistrationData.getLastName());
        gbc.weightx = 1.0;
        gbc.weighty = 0.0;
        gbc.gridx = 1;
        gbc.gridy = 5;
        gbc.fill = HORIZONTAL;
        gbc.anchor = WEST;
        gbc.gridwidth = 1;
        gbc.insets = new Insets(5, 10, 0, 10);
        mainPanel.add(lastNameTextField, gbc);

        // Email address
        JLabel emailLabel = new JLabel(EMAIL_ADDRESS);
        emailLabel.setFont(baseFont);
        gbc.weightx = 0.0;
        gbc.weighty = 0.0;
        gbc.gridx = 0;
        gbc.gridy = 6;
        gbc.fill = NONE;
        gbc.anchor = WEST;
        gbc.gridwidth = 1;
        gbc.insets = new Insets(5, 10, 0, 10);
        mainPanel.add(emailLabel, gbc);

        emailTextField = new JTextField();
        emailTextField.setFont(baseFont);
        if (previousRegistrationData != null)
            emailTextField.setText(previousRegistrationData.getEmailAddress());
        gbc.weightx = 1.0;
        gbc.weighty = 0.0;
        gbc.gridx = 1;
        gbc.gridy = 6;
        gbc.fill = HORIZONTAL;
        gbc.anchor = WEST;
        gbc.gridwidth = 1;
        gbc.insets = new Insets(5, 10, 0, 10);
        mainPanel.add(emailTextField, gbc);

        // Keep me informed
        keepMeInformedCheckBox = new JCheckBox(KEEP_ME_INFORMED);
        keepMeInformedCheckBox.setFont(baseFont);
        if (previousRegistrationData != null)
            keepMeInformedCheckBox.setSelected(previousRegistrationData.getKeepMeInformed());
        keepMeInformedCheckBox.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent evt) {
                if (evt.getKeyCode() == VK_ENTER) {
                    evt.consume();
                    keepMeInformedCheckBox.setSelected(!keepMeInformedCheckBox.isSelected());
                }
            }
        });
        gbc.weightx = 0.0;
        gbc.weighty = 0.0;
        gbc.gridx = 1;
        gbc.gridy = 7;
        gbc.fill = NONE;
        gbc.anchor = WEST;
        gbc.gridwidth = 2;
        gbc.insets = new Insets(5, 10, 0, 10);
        mainPanel.add(keepMeInformedCheckBox, gbc);

        // Institution name
        JLabel institutionLabel = new JLabel(INSTITUTION_COMPANY_NAME);
        institutionLabel.setFont(baseFont);
        gbc.weightx = 0.0;
        gbc.weighty = 0.0;
        gbc.gridx = 0;
        gbc.gridy = 8;
        gbc.fill = NONE;
        gbc.anchor = WEST;
        gbc.gridwidth = 1;
        gbc.insets = new Insets(5, 10, 0, 10);
        mainPanel.add(institutionLabel, gbc);

        institutionOrCompanyTextField = new JTextField();
        institutionOrCompanyTextField.setFont(baseFont);
        if (previousRegistrationData != null)
            institutionOrCompanyTextField.setText(previousRegistrationData.getInstitutionOrCompanyName());
        gbc.weightx = 1.0;
        gbc.weighty = 0.0;
        gbc.gridx = 1;
        gbc.gridy = 8;
        gbc.fill = HORIZONTAL;
        gbc.anchor = WEST;
        gbc.gridwidth = 1;
        gbc.insets = new Insets(5, 10, 0, 10);
        mainPanel.add(institutionOrCompanyTextField, gbc);

        // Industry type
        JLabel industryLabel = new JLabel(" Industry type:");
        industryLabel.setFont(baseFont);
        gbc.weightx = 0.0;
        gbc.weighty = 0.0;
        gbc.gridx = 0;
        gbc.gridy = 9;
        gbc.fill = NONE;
        gbc.anchor = WEST;
        gbc.gridwidth = 1;
        gbc.insets = new Insets(5, 10, 0, 10);
        mainPanel.add(industryLabel, gbc);

        industryTypeTextField = new JComboBox<>(industryTypes);
        industryTypeTextField.setFont(baseFont);
        if (previousRegistrationData != null)
            industryTypeTextField.setSelectedItem(previousRegistrationData.getIndustry());
        gbc.weightx = 1.0;
        gbc.weighty = 0.0;
        gbc.gridx = 1;
        gbc.gridy = 9;
        gbc.fill = HORIZONTAL;
        gbc.anchor = WEST;
        gbc.gridwidth = 1;
        gbc.insets = new Insets(5, 10, 0, 10);
        mainPanel.add(industryTypeTextField, gbc);

        // Field of investigation
        JTextArea fieldLabel = new JTextArea(FIELD_OF_INVESTIGATION);
        fieldLabel.setFont(baseFont);
        fieldLabel.setEditable(false);
        fieldLabel.setFocusable(false);
        fieldLabel.setBackground(getBackground());
        gbc.weightx = 0.0;
        gbc.weighty = 0.0;
        gbc.gridx = 0;
        gbc.gridy = 10;
        gbc.fill = NONE;
        gbc.anchor = LINE_START;
        gbc.gridwidth = 1;
        gbc.insets = new Insets(5, 10, 0, 10);
        mainPanel.add(fieldLabel, gbc);

        fieldTextField = new JTextField();
        fieldTextField.setFont(baseFont);
        if (previousRegistrationData != null)
            fieldTextField.setText(previousRegistrationData.getField());
        gbc.weightx = 1.0;
        gbc.weighty = 0.0;
        gbc.gridx = 1;
        gbc.gridy = 10;
        gbc.fill = HORIZONTAL;
        gbc.anchor = FIRST_LINE_START;
        gbc.gridwidth = 1;
        gbc.insets = new Insets(5, 10, 0, 10);
        mainPanel.add(fieldTextField, gbc);

        // Purpose of using Taverna
        JTextArea purposeLabel = new JTextArea(WHY_YOU_INTEND_TO_USE_TAVERNA);
        purposeLabel.setFont(baseFont);
        purposeLabel.setEditable(false);
        purposeLabel.setFocusable(false);
        purposeLabel.setBackground(getBackground());
        gbc.weightx = 0.0;
        gbc.weighty = 0.0;
        gbc.gridx = 0;
        gbc.gridy = 11;
        gbc.fill = NONE;
        gbc.anchor = LINE_START;
        gbc.gridwidth = 1;
        gbc.insets = new Insets(5, 10, 0, 10);
        mainPanel.add(purposeLabel, gbc);

        purposeTextArea = new JTextArea(4, 30);
        purposeTextArea.setFont(baseFont);
        purposeTextArea.setLineWrap(true);
        purposeTextArea.setAutoscrolls(true);
        if (previousRegistrationData != null)
            purposeTextArea.setText(previousRegistrationData.getPurposeOfUsingTaverna());
        purposeTextArea.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent evt) {
                if (evt.getKeyCode() == VK_TAB) {
                    if (evt.getModifiers() > 0)
                        purposeTextArea.transferFocusBackward();
                    else
                        purposeTextArea.transferFocus();
                    evt.consume();
                }
            }
        });
        JScrollPane purposeScrollPane = new JScrollPane(purposeTextArea);
        gbc.weightx = 1.0;
        gbc.weighty = 0.0;
        gbc.gridx = 1;
        gbc.gridy = 11;
        gbc.fill = HORIZONTAL;
        gbc.anchor = FIRST_LINE_START;
        gbc.gridwidth = 1;
        gbc.insets = new Insets(5, 10, 0, 10);
        mainPanel.add(purposeScrollPane, gbc);

        // Terms and conditions
        termsAndConditionsCheckBox = new JCheckBox(I_AGREE_TO_THE_TERMS_AND_CONDITIONS);
        termsAndConditionsCheckBox.setFont(baseFont);
        termsAndConditionsCheckBox.setBorder(null);
        termsAndConditionsCheckBox.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent evt) {
                if (evt.getKeyCode() == VK_ENTER) {
                    evt.consume();
                    termsAndConditionsCheckBox.setSelected(!termsAndConditionsCheckBox.isSelected());
                }
            }
        });
        // gbc.weightx = 0.0;
        // gbc.weighty = 0.0;
        // gbc.gridx = 0;
        // gbc.gridy = 12;
        // gbc.fill = NONE;
        // gbc.anchor = WEST;
        // gbc.gridwidth = 2;
        // gbc.insets = new Insets(10, 10, 0, 0);
        // mainPanel.add(termsAndConditionsCheckBox, gbc);

        // Terms and conditions link
        JEditorPane termsAndConditionsURL = new JEditorPane();
        termsAndConditionsURL.setEditable(false);
        termsAndConditionsURL.setBackground(getBackground());
        termsAndConditionsURL.setFocusable(false);
        HTMLEditorKit kit = new HTMLEditorKit();
        termsAndConditionsURL.setEditorKit(kit);
        StyleSheet styleSheet = kit.getStyleSheet();
        // styleSheet.addRule("body {font-family:"+baseFont.getFamily()+"; font-size:"+baseFont.getSize()+";}");
        // // base font looks bigger when rendered as HTML
        styleSheet.addRule("body {font-family:" + baseFont.getFamily() + "; font-size:9px;}");
        Document doc = kit.createDefaultDocument();
        termsAndConditionsURL.setDocument(doc);
        termsAndConditionsURL.setText("<html><body><a href=\"" + TERMS_AND_CONDITIONS_URL + "\">"
                + TERMS_AND_CONDITIONS_URL + "</a></body></html>");
        termsAndConditionsURL.addHyperlinkListener(new HyperlinkListener() {
            @Override
            public void hyperlinkUpdate(HyperlinkEvent he) {
                if (he.getEventType() == ACTIVATED)
                    followHyperlinkToTandCs();
            }
        });
        gbc.weightx = 0.0;
        gbc.weighty = 0.0;
        gbc.gridx = 0;
        gbc.gridy = 13;
        gbc.fill = NONE;
        gbc.anchor = WEST;
        gbc.gridwidth = 2;
        gbc.insets = new Insets(5, 10, 0, 10);
        JPanel termsAndConditionsPanel = new JPanel(new FlowLayout(LEFT));
        termsAndConditionsPanel.add(termsAndConditionsCheckBox);
        termsAndConditionsPanel.add(termsAndConditionsURL);
        mainPanel.add(termsAndConditionsPanel, gbc);

        // Button panel
        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        JButton registerButton = new JButton("Register");
        registerButton.setFont(baseFont);
        registerButton.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent evt) {
                if (evt.getKeyCode() == VK_ENTER) {
                    evt.consume();
                    register();
                }
            }
        });
        registerButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                register();
            }
        });
        JButton doNotRegisterButton = new JButton("Do not ask me again");
        doNotRegisterButton.setFont(baseFont);
        doNotRegisterButton.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent evt) {
                if (evt.getKeyCode() == VK_ENTER) {
                    evt.consume();
                    doNotRegister();
                }
            }
        });
        doNotRegisterButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                doNotRegister();
            }
        });
        JButton remindMeLaterButton = new JButton("Remind me later"); // in 2 weeks
        remindMeLaterButton.setFont(baseFont);
        remindMeLaterButton.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent evt) {
                if (evt.getKeyCode() == VK_ENTER) {
                    evt.consume();
                    remindMeLater();
                }
            }
        });
        remindMeLaterButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                remindMeLater();
            }
        });
        buttonPanel.add(registerButton);
        buttonPanel.add(remindMeLaterButton);
        buttonPanel.add(doNotRegisterButton);
        addDivider(buttonPanel, TOP, true);
        gbc.gridx = 0;
        gbc.gridy = 14;
        gbc.fill = HORIZONTAL;
        gbc.anchor = GridBagConstraints.CENTER;
        gbc.insets = new Insets(5, 10, 0, 10);
        gbc.gridwidth = 2;
        mainPanel.add(buttonPanel, gbc);

        getContentPane().setLayout(new BorderLayout());
        getContentPane().add(mainPanel, CENTER);

        pack();
        setResizable(false);
        // Center the dialog on the screen (we do not have the parent)
        Dimension dimension = getToolkit().getScreenSize();
        Rectangle abounds = getBounds();
        setLocation((dimension.width - abounds.width) / 2, (dimension.height - abounds.height) / 2);
        setSize(getPreferredSize());
    }

    protected void remindMeLater() {
        try {
            FileUtils.touch(remindMeLaterFile);
        } catch (IOException ioex) {
            logger.error("Failed to touch the 'Remind me later' file at user registration.", ioex);
        }
        closeDialog();
    }

    protected void doNotRegister() {
        try {
            FileUtils.touch(doNotRegisterMeFile);
            if (remindMeLaterFile.exists())
                remindMeLaterFile.delete();
        } catch (IOException ioex) {
            logger.error("Failed to touch the 'Do not register me' file at user registration.", ioex);
        }
        closeDialog();
    }

    private void register() {
        if (!validateForm())
            return;
        UserRegistrationData regData = new UserRegistrationData();
        regData.setTavernaVersion(appName);
        regData.setFirstName(firstNameTextField.getText());
        regData.setLastName(lastNameTextField.getText());
        regData.setEmailAddress(emailTextField.getText());
        regData.setKeepMeInformed(keepMeInformedCheckBox.isSelected());
        regData.setInstitutionOrCompanyName(institutionOrCompanyTextField.getText());
        regData.setIndustry(industryTypeTextField.getSelectedItem().toString());
        regData.setField(fieldTextField.getText());
        regData.setPurposeOfUsingTaverna(purposeTextArea.getText());

        if (postUserRegistrationDataToServer(regData)) {
            saveUserRegistrationData(regData, registrationDataFile);
            if (remindMeLaterFile.exists())
                remindMeLaterFile.delete();
            closeDialog();
        }
    }

    private boolean validateForm() {
        String errorMessage = "";
        if (firstNameTextField.getText().isEmpty())
            errorMessage += "Please provide your first name.<br>";
        if (lastNameTextField.getText().isEmpty())
            errorMessage += "Please provide your last name.<br>";
        if (emailTextField.getText().isEmpty())
            errorMessage += "Please provide your email address.<br>";
        if (institutionOrCompanyTextField.getText().isEmpty())
            errorMessage += "Please provide your institution or company name.";
        if (!errorMessage.isEmpty()) {
            showMessageDialog(this, new JLabel("<html><body>" + errorMessage + "</body></html>"), "Error in form",
                    ERROR_MESSAGE);
            return false;
        }
        if (!termsAndConditionsCheckBox.isSelected()) {
            showMessageDialog(this, new JLabel("You must agree to the terms and conditions."), "Error in form",
                    ERROR_MESSAGE);
            return false;
        }
        return true;
    }

    public UserRegistrationData loadUserRegistrationData(File propertiesFile) {
        UserRegistrationData regData = new UserRegistrationData();
        Properties props = new Properties();

        // Try to retrieve data from file
        try {
            props.load(new FileInputStream(propertiesFile));
        } catch (IOException e) {
            logger.error("Failed to load old user registration data from " + propertiesFile.getAbsolutePath(), e);
            return null;
        }
        regData.setTavernaVersion(props.getProperty(TAVERNA_VERSION_PROPERTY_NAME));
        regData.setFirstName(props.getProperty(FIRST_NAME_PROPERTY_NAME));
        regData.setLastName(props.getProperty(LAST_NAME_PROPERTY_NAME));
        regData.setEmailAddress(props.getProperty(EMAIL_ADDRESS_PROPERTY_NAME));
        regData.setKeepMeInformed(props.getProperty(KEEP_ME_INFORMED_PROPERTY_NAME).equals(TRUE));
        regData.setInstitutionOrCompanyName(props.getProperty(INSTITUTION_OR_COMPANY_PROPERTY_NAME));
        regData.setIndustry(props.getProperty(INDUSTRY_PROPERTY_NAME));
        regData.setField(props.getProperty(FIELD_PROPERTY_NAME));
        regData.setPurposeOfUsingTaverna(props.getProperty(PURPOSE_PROPERTY_NAME));
        return regData;
    }

    private void enc(StringBuilder buffer, String name, Object value) throws UnsupportedEncodingException {
        if (buffer.length() != 0)
            buffer.append('&');
        buffer.append(URLEncoder.encode(name, "UTF-8"));
        buffer.append('=');
        buffer.append(URLEncoder.encode(value.toString(), "UTF-8"));
    }

    /**
     * Post registration data to our server.
     */
    private boolean postUserRegistrationDataToServer(UserRegistrationData regData) {
        StringBuilder parameters = new StringBuilder();

        /*
         * The 'submit' parameter - to let the server-side script know we are
         * submitting the user's registration form - all other requests will be
         * silently ignored
         */
        try {
            // value does not matter
            enc(parameters, TAVERNA_REGISTRATION_POST_PARAMETER_NAME, "submit");

            enc(parameters, TAVERNA_VERSION_POST_PARAMETER_NAME, regData.getTavernaVersion());
            enc(parameters, FIRST_NAME_POST_PARAMETER_NAME, regData.getFirstName());
            enc(parameters, LAST_NAME_POST_PARAMETER_NAME, regData.getLastName());
            enc(parameters, EMAIL_ADDRESS_POST_PARAMETER_NAME, regData.getEmailAddress());
            enc(parameters, KEEP_ME_INFORMED_POST_PARAMETER_PROPERTY_NAME, regData.getKeepMeInformed());
            enc(parameters, INSTITUTION_OR_COMPANY_POST_PARAMETER_NAME, regData.getInstitutionOrCompanyName());
            enc(parameters, INDUSTRY_TYPE_POST_PARAMETER_NAME, regData.getIndustry());
            enc(parameters, FIELD_POST_PARAMETER_NAME, regData.getField());
            enc(parameters, PURPOSE_POST_PARAMETER_NAME, regData.getPurposeOfUsingTaverna());
        } catch (UnsupportedEncodingException ueex) {
            logger.error(FAILED + "Could not url encode post parameters", ueex);
            showMessageDialog(null, REGISTRATION_FAILED_MSG, "Error encoding registration data", ERROR_MESSAGE);
            return false;
        }
        String server = REGISTRATION_URL;
        logger.info("Posting user registartion to " + server + " with parameters: " + parameters);
        String response = "";
        String failure;
        try {
            URL url = new URL(server);
            URLConnection conn = url.openConnection();
            /*
             * Set timeout to e.g. 7 seconds, otherwise we might hang too long
             * if server is not responding and it will block Taverna
             */
            conn.setConnectTimeout(7000);
            // Set connection parameters
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setUseCaches(false);
            // Make server believe we are HTML form data...
            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            // Write out the bytes of the content string to the stream.
            try (DataOutputStream out = new DataOutputStream(conn.getOutputStream())) {
                out.writeBytes(parameters.toString());
                out.flush();
            }
            // Read response from the input stream.
            try (BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
                String temp;
                while ((temp = in.readLine()) != null)
                    response += temp + "\n";
                // Remove the last \n character
                if (!response.isEmpty())
                    response = response.substring(0, response.length() - 1);
            }
            if (response.equals("Registration successful!"))
                return true;
            logger.error(FAILED + "Response form server was: " + response);
            failure = "Error saving registration data on the server";
        } catch (ConnectException ceex) {
            /*
             * the connection was refused remotely (e.g. no process is listening
             * on the remote address/port).
             */
            logger.error(FAILED + "Registration server is not listening of the specified url.", ceex);
            failure = "Registration server is not listening at the specified url";
        } catch (SocketTimeoutException stex) {
            // timeout has occurred on a socket read or accept.
            logger.error(FAILED + "Socket timeout occurred.", stex);
            failure = "Registration server timeout";
        } catch (MalformedURLException muex) {
            logger.error(FAILED + "Registartion server's url is malformed.", muex);
            failure = "Error with registration server's url";
        } catch (IOException ioex) {
            logger.error(
                    FAILED + "Failed to open url connection to registration server or writing/reading to/from it.",
                    ioex);
            failure = "Error opening connection to the registration server";
        }
        showMessageDialog(null, REGISTRATION_FAILED_MSG, failure, ERROR_MESSAGE);
        return false;
    }

    private void saveUserRegistrationData(UserRegistrationData regData, File propertiesFile) {
        Properties props = new Properties();
        props.setProperty(TAVERNA_VERSION_PROPERTY_NAME, regData.getTavernaVersion());
        props.setProperty(FIRST_NAME_PROPERTY_NAME, regData.getFirstName());
        props.setProperty(LAST_NAME_PROPERTY_NAME, regData.getLastName());
        props.setProperty(EMAIL_ADDRESS_PROPERTY_NAME, regData.getEmailAddress());
        props.setProperty(KEEP_ME_INFORMED_PROPERTY_NAME, regData.getKeepMeInformed() ? TRUE : FALSE);
        props.setProperty(INSTITUTION_OR_COMPANY_PROPERTY_NAME, regData.getInstitutionOrCompanyName());
        props.setProperty(INDUSTRY_PROPERTY_NAME, regData.getIndustry());
        props.setProperty(FIELD_PROPERTY_NAME, regData.getPurposeOfUsingTaverna());
        props.setProperty(PURPOSE_PROPERTY_NAME, regData.getPurposeOfUsingTaverna());

        // Write the properties file.
        try {
            props.store(new FileOutputStream(propertiesFile), null);
        } catch (Exception e) {
            logger.error("Failed to save user registration data locally on disk.");
        }
    }

    private void closeDialog() {
        setVisible(false);
        dispose();
    }

    /**
     * Adds a light gray or etched border to the top or bottom of a JComponent.
     * 
     * @author David Withers
     * @param component
     */
    protected void addDivider(JComponent component, final int position, final boolean etched) {
        component.setBorder(new Border() {
            private final Color borderColor = new Color(.6f, .6f, .6f);

            @Override
            public Insets getBorderInsets(Component c) {
                if (position == TOP)
                    return new Insets(5, 0, 0, 0);
                else
                    return new Insets(0, 0, 5, 0);
            }

            @Override
            public boolean isBorderOpaque() {
                return false;
            }

            @Override
            public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
                if (position == TOP) {
                    if (etched) {
                        g.setColor(borderColor);
                        g.drawLine(x, y, x + width, y);
                        g.setColor(WHITE);
                        g.drawLine(x, y + 1, x + width, y + 1);
                    } else {
                        g.setColor(LIGHT_GRAY);
                        g.drawLine(x, y, x + width, y);
                    }
                } else {
                    if (etched) {
                        g.setColor(borderColor);
                        g.drawLine(x, y + height - 2, x + width, y + height - 2);
                        g.setColor(WHITE);
                        g.drawLine(x, y + height - 1, x + width, y + height - 1);
                    } else {
                        g.setColor(LIGHT_GRAY);
                        g.drawLine(x, y + height - 1, x + width, y + height - 1);
                    }
                }
            }
        });
    }

    private void followHyperlinkToTandCs() {
        // Open a Web browser
        try {
            Desktop.getDesktop().browse(new URI(TERMS_AND_CONDITIONS_URL));
        } catch (Exception ex) {
            logger.error("User registration: Failed to launch browser to show terms and conditions at "
                    + TERMS_AND_CONDITIONS_URL);
        }
    }
}