/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license. See terms of license at gnu.org.
*/
package net.java.sip.communicator.plugin.jabberaccregwizz;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import net.java.sip.communicator.util.*;
import net.java.sip.communicator.util.swing.*;
import net.java.sip.communicator.service.protocol.*;
/**
* @author Yana Stamcheva
*/
public class AccountPanel
extends TransparentPanel
implements DocumentListener,
ValidatingPanel
{
/**
* Serial version UID.
*/
private static final long serialVersionUID = 0L;
private static final Logger logger = Logger.getLogger(AccountPanel.class);
private final JPanel userIDPassPanel
= new TransparentPanel(new BorderLayout(10, 10));
private final JPanel labelsPanel = new TransparentPanel();
private final JPanel valuesPanel = new TransparentPanel();
private final JLabel passLabel
= new JLabel(Resources.getString("service.gui.PASSWORD"));
private final JPanel emptyPanel = new TransparentPanel();
private final JTextField userIDField = new TrimTextField();
private final JPasswordField passField = new JPasswordField();
private final JCheckBox rememberPassBox = new SIPCommCheckBox(Resources
.getString("service.gui.REMEMBER_PASSWORD"));
/**
* Panel to hold the "change password" button
*/
private final JPanel changePasswordPanel = new TransparentPanel();
/**
* "Change password" button
*/
private final JButton changePasswordButton
= new JButton(Resources.getString(
"plugin.jabberaccregwizz.CHANGE_PASSWORD"));
private final JabberAccountRegistrationForm parentForm;
private final JRadioButton existingAccountButton;
private final JRadioButton createAccountButton;
private final JPanel mainPanel
= new TransparentPanel(new BorderLayout(5, 5));
private Component registrationForm;
private Component registerChoicePanel;
/**
* Creates an instance of AccountPanel by specifying the parent
* wizard page, where it's contained.
* @param parentForm the parent form where this panel is contained
*/
public AccountPanel(final JabberAccountRegistrationForm parentForm)
{
super(new BorderLayout());
this.parentForm = parentForm;
this.parentForm.addValidatingPanel(this);
JLabel userIDLabel
= new JLabel(parentForm.getUsernameLabel());
JLabel userIDExampleLabel = new JLabel(parentForm.getUsernameExample());
labelsPanel.setLayout(new BoxLayout(labelsPanel, BoxLayout.Y_AXIS));
valuesPanel.setLayout(new BoxLayout(valuesPanel, BoxLayout.Y_AXIS));
userIDField.getDocument().addDocumentListener(this);
rememberPassBox.setSelected(true);
existingAccountButton = new JRadioButton(
parentForm.getExistingAccountLabel());
createAccountButton = new JRadioButton(
parentForm.getCreateAccountLabel());
userIDExampleLabel.setForeground(Color.GRAY);
userIDExampleLabel.setFont(userIDExampleLabel.getFont().deriveFont(8));
emptyPanel.setMaximumSize(new Dimension(40, 35));
userIDExampleLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 8, 0));
labelsPanel.add(userIDLabel);
labelsPanel.add(emptyPanel);
labelsPanel.add(passLabel);
valuesPanel.add(userIDField);
valuesPanel.add(userIDExampleLabel);
valuesPanel.add(passField);
userIDPassPanel.add(labelsPanel, BorderLayout.WEST);
userIDPassPanel.add(valuesPanel, BorderLayout.CENTER);
userIDPassPanel.setBorder(
BorderFactory.createTitledBorder(
Resources.getString(
"plugin.sipaccregwizz.USERNAME_AND_PASSWORD")));
JPanel southPanel = new TransparentPanel(new BorderLayout());
southPanel.add(rememberPassBox, BorderLayout.WEST);
String homeLinkString = parentForm.getHomeLinkLabel();
if (homeLinkString != null && homeLinkString.length() > 0)
{
String homeLink = Resources.getSettingsString(
"service.gui.APPLICATION_WEB_SITE");
southPanel.add( createHomeLink(homeLinkString, homeLink),
BorderLayout.EAST);
}
userIDPassPanel.add(southPanel, BorderLayout.SOUTH);
this.add(mainPanel, BorderLayout.NORTH);
changePasswordButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ChangePasswordDialog changePasswordDialog
= new ChangePasswordDialog();
}
});
changePasswordPanel.add(changePasswordButton, BorderLayout.CENTER);
//show it only if needed (when modifying an account)
changePasswordPanel.setVisible(false);
this.add(changePasswordPanel);
}
/**
* Creates a register choice panel.
* @return the created component
*/
private Component createRegisterChoicePanel()
{
JPanel registerChoicePanel = new TransparentPanel(new GridLayout(0, 1));
existingAccountButton.addChangeListener(new ChangeListener()
{
public void stateChanged(ChangeEvent e)
{
if (existingAccountButton.isSelected())
{
mainPanel.remove(registrationForm);
mainPanel.add(userIDPassPanel, BorderLayout.CENTER);
Window window
= SwingUtilities.getWindowAncestor(AccountPanel.this);
if (window != null)
window.pack();
}
}
});
createAccountButton.addChangeListener(new ChangeListener()
{
public void stateChanged(ChangeEvent e)
{
if (createAccountButton.isSelected())
{
mainPanel.remove(userIDPassPanel);
mainPanel.add(registrationForm, BorderLayout.CENTER);
SwingUtilities.getWindowAncestor(AccountPanel.this).pack();
}
}
});
ButtonGroup buttonGroup = new ButtonGroup();
existingAccountButton.setOpaque(false);
createAccountButton.setOpaque(false);
buttonGroup.add(existingAccountButton);
buttonGroup.add(createAccountButton);
registerChoicePanel.add(existingAccountButton);
registerChoicePanel.add(createAccountButton);
// By default we select the existing account button.
existingAccountButton.setSelected(true);
return registerChoicePanel;
}
/**
* Creates the home link label.
*
* @param homeLinkText the text of the home link
* @param homeLink the link
* @return the created component
*/
private Component createHomeLink( String homeLinkText,
final String homeLink)
{
JLabel homeLinkLabel =
new JLabel(""
+ homeLinkText + "",
JLabel.RIGHT);
homeLinkLabel.setFont(homeLinkLabel.getFont().deriveFont(10f));
homeLinkLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
homeLinkLabel.setToolTipText(
Resources.getString(
"plugin.simpleaccregwizz.SPECIAL_SIGNUP"));
homeLinkLabel.addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent e)
{
try
{
JabberAccRegWizzActivator.getBrowserLauncher()
.openURL(homeLink);
}
catch (UnsupportedOperationException ex)
{
// This should not happen, because we check if the
// operation is supported, before adding the sign
// up.
logger.error("The web sign up is not supported.",
ex);
}
}
});
return homeLinkLabel;
}
/**
* Handles the DocumentEvent triggered when user types in the
* UserID field. Enables or disables the "Next" wizard button according to
* whether the UserID field is empty.
*
* @param evt the document event that has triggered this method call.
*/
public void insertUpdate(DocumentEvent evt)
{
parentForm.setServerFieldAccordingToUIN(userIDField.getText());
parentForm.reValidateInput();
}
/**
* Handles the DocumentEvent triggered when user deletes letters
* from the User ID field. Enables or disables the "Next" wizard button
* according to whether the User ID field is empty.
*
* @param evt the document event that has triggered this method call.
*/
public void removeUpdate(DocumentEvent evt)
{
parentForm.setServerFieldAccordingToUIN(userIDField.getText());
parentForm.reValidateInput();
}
public void changedUpdate(DocumentEvent evt) {}
/**
* Returns the username entered in this panel.
* @return the username entered in this panel
*/
String getUsername()
{
return userIDField.getText();
}
/**
* Sets the username to display in the username field.
* @param username the username to set
*/
void setUsername(String username)
{
userIDField.setText(username);
userIDField.setEnabled(false);
}
/**
* Returns the password entered in this panel.
* @return the password entered in this panel
*/
char[] getPassword()
{
return passField.getPassword();
}
/**
* Sets the password to display in the password field of this panel.
* @param password the password to set
*/
void setPassword(String password)
{
passField.setText(password);
}
/**
* Indicates if the remember password box is selected.
* @return true if the remember password check box is selected,
* otherwise returns false
*/
boolean isRememberPassword()
{
return rememberPassBox.isSelected();
}
/**
* Selects/deselects the remember password check box depending on the given
* isRemember parameter.
* @param isRemember indicates if the remember password checkbox should be
* selected or not
*/
void setRememberPassword(boolean isRemember)
{
rememberPassBox.setSelected(isRemember);
}
/**
* Whether current inserted values into the panel are valid and enough
* to continue with account creation/modification.
*
* @return whether the input values are ok to continue with account
* creation/modification.
*/
public boolean isValidated()
{
return userIDField.getText() != null
&& userIDField.getText().length() > 0;
}
/**
* Sets to true if this panel is opened in a simple form and
* false if it's opened in an advanced form.
*
* @param isSimpleForm indicates if this panel is opened in a simple form or
* in an advanced form
*/
void setSimpleForm(boolean isSimpleForm)
{
JabberAccountCreationFormService createAccountService
= parentForm.getCreateAccountService();
mainPanel.removeAll();
if (isSimpleForm)
{
if (createAccountService != null)
{
registrationForm = createAccountService.getForm();
registerChoicePanel = createRegisterChoicePanel();
mainPanel.add(registerChoicePanel, BorderLayout.NORTH);
}
else
{
JPanel registerPanel = new TransparentPanel();
registerPanel.setLayout(
new BoxLayout(registerPanel, BoxLayout.Y_AXIS));
String createAccountInfoString
= parentForm.getCreateAccountLabel();
if (createAccountInfoString != null
&& createAccountInfoString.length() > 0)
{
registerPanel.add(
createRegisterArea(createAccountInfoString));
}
String createAccountString
= parentForm.getCreateAccountButtonLabel();
if (createAccountString != null
&& createAccountString.length() > 0)
{
JPanel buttonPanel = new TransparentPanel(
new FlowLayout(FlowLayout.CENTER));
buttonPanel.add(createRegisterButton(createAccountString));
registerPanel.add(buttonPanel);
}
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
mainPanel.add(userIDPassPanel);
mainPanel.add(Box.createVerticalStrut(10));
if (registerPanel.getComponentCount() > 0)
{
registerPanel.setBorder(
BorderFactory.createTitledBorder(""));
mainPanel.add(registerPanel);
}
}
}
else
{
mainPanel.add(userIDPassPanel, BorderLayout.NORTH);
}
}
/**
* Indicates if the account information provided by this form is for new
* account or an existing one.
* @return true if the account information provided by this form
* is for new account or false if it's for an existing one
*/
boolean isCreateAccount()
{
return createAccountButton.isSelected();
}
/**
* Creates the register area.
*
* @param text the text to show to the user
* @return the created component
*/
private Component createRegisterArea(String text)
{
JEditorPane registerArea = new JEditorPane();
registerArea.setAlignmentX(JEditorPane.CENTER_ALIGNMENT);
registerArea.setOpaque(false);
registerArea.setContentType("text/html");
registerArea.setEditable(false);
registerArea.setText(text);
/* Display the description with the font we use elsewhere in the UI. */
registerArea.putClientProperty(
JEditorPane.HONOR_DISPLAY_PROPERTIES,
true);
registerArea.addHyperlinkListener(new HyperlinkListener()
{
public void hyperlinkUpdate(HyperlinkEvent e)
{
if (e.getEventType()
.equals(HyperlinkEvent.EventType.ACTIVATED))
{
JabberAccRegWizzActivator
.getBrowserLauncher().openURL(e.getURL().toString());
}
}
});
return registerArea;
}
/**
* Creates the register button.
*
* @param text the text of the button
* @return the created component
*/
private Component createRegisterButton(String text)
{
JButton registerButton = new JButton(text);
registerButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
if (logger.isDebugEnabled())
logger.debug("Reg OK");
if (parentForm.isWebSignupSupported())
{
parentForm.webSignup();
}
}
});
return registerButton;
}
/**
* Shows or hides the "change password" button
*/
public void showChangePasswordButton()
{
changePasswordPanel.setVisible(true);
}
/**
* A "change password" dialog.
*/
private class ChangePasswordDialog extends SIPCommDialog
{
/**
* The main panel
*/
private final JPanel mainPanel = new JPanel(new BorderLayout());
/**
* A pane for showing messages (info or errors)
*/
private final JEditorPane messagePane = new JEditorPane();
/**
* Panel for the text fields
*/
TransparentPanel valuesPanel
= new TransparentPanel(new GridLayout(0, 1));
/**
* The password field
*/
private final JPasswordField passField1 = new JPasswordField();
/**
* The confirm password field
*/
private final JPasswordField passField2 = new JPasswordField();
/**
* Panel for the "ok" and "cancel" buttons
*/
private final TransparentPanel buttonsPanel
= new TransparentPanel(new FlowLayout(FlowLayout.RIGHT));
/**
* The "OK" button
*/
private final JButton okButton
= new JButton(Resources.getString("service.gui.OK"));
/**
* The "cancel" button
*/
private final JButton cancelButton
= new JButton(Resources.getString("service.gui.CANCEL"));
/**
* Panel for the labels
*/
private final TransparentPanel labelsPanel
= new TransparentPanel(new GridLayout(0, 1));
/**
* The "new password" label
*/
private final JLabel passLabel1 = new JLabel(Resources.
getString("plugin.jabberaccregwizz.NEW_PASSWORD"));
/**
* The "confirm password" label
*/
private final JLabel passLabel2 = new JLabel(Resources.
getString("plugin.jabberaccregwizz.NEW_PASSWORD_CONFIRM"));
/**
* Creates a full dialog (sets all the fields and buttons)
*/
public ChangePasswordDialog()
{
//don't save size and location
super(false);
setTitle(Resources.
getString("plugin.jabberaccregwizz.CHANGE_PASSWORD"));
messagePane.setOpaque(false);
messagePane.setForeground(Color.RED);
messagePane.setBorder(BorderFactory.createEmptyBorder(0, 0, 15, 0));
messagePane.setEditable(false);
mainPanel.add(messagePane, BorderLayout.NORTH);
loadMessage(Resources.getString(
"plugin.jabberaccregwizz.ENTER_NEW_PASSWORD"));
labelsPanel.add(passLabel1);
labelsPanel.add(passLabel2);
passField1.setColumns(15);
passField2.setColumns(15);
valuesPanel.add(passField1);
valuesPanel.add(passField2);
okButton.addActionListener(okButtonListener);
cancelButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
dispose();
}
});
buttonsPanel.add(okButton);
buttonsPanel.add(cancelButton);
getRootPane().setDefaultButton(okButton);
mainPanel.add(labelsPanel, BorderLayout.WEST);
mainPanel.add(valuesPanel, BorderLayout.CENTER);
mainPanel.add(buttonsPanel, BorderLayout.SOUTH);
mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
getContentPane().add(mainPanel, BorderLayout.NORTH);
setModal(true);
setVisible(true);
pack();
}
/**
* This is the ActionListener for the "ok" button.
*/
private final ActionListener okButtonListener = new ActionListener(){
/**
* Action for the "ok" button. This contains most of the logic for
* the dialog:
* It checks the fields, whether the account is logged in, tries to
* change the password and displays messages in the message pane
*/
public void actionPerformed(ActionEvent e) {
String newPass1 = new String(passField1.getPassword());
String newPass2 = new String(passField2.getPassword());
ProtocolProviderService protocolProvider =
parentForm.getWizard().getProtocolProvider();
if (protocolProvider == null) {
//we shouldn't get here, because this dialog only shows
//when editing an existing account
logger.warn("protocolProvider is null in change"
+ " password dialog");
loadMessage("Could not change password");
hideCancelAndFields();
okButton.removeActionListener(okButtonListener);
okButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
dispose();
}
});
}
else if (!protocolProvider.isRegistered()) {
//editing an account, which is not logged in
loadMessage(Resources.getString(
"plugin.jabberaccregwizz.HAS_TO_BE_LOGGED_IN"));
}
else if (!newPass1.equals(newPass2)) {
loadMessage(Resources.getString(
"plugin.jabberaccregwizz.NOT_SAME_PASSWORD"));
}
else if (newPass1.length() <= 0) {
loadMessage(Resources.getString(
"plugin.jabberaccregwizz.PASSWORD_EMPTY"));
}
else if (protocolProvider.getTransportProtocol()
!= TransportProtocol.TLS) {
//XEP-077 advices agains changing password unless
//the underlying stream is encrypted
loadMessage(Resources.getString(
"plugin.jabberaccregwizz.TLS_REQUIRED"));
}
else //try to change
{
if (logger.isInfoEnabled()) {
logger.info("Trying to change password for jabber"
+ " account "
+ protocolProvider.
getAccountID().getAccountAddress());
}
OperationSetChangePassword opset =
protocolProvider.getOperationSet(
OperationSetChangePassword.class);
try {
opset.changePassword(newPass1);
loadMessage(Resources.getString(
"plugin.jabberaccregwizz.PASSWORD_CHANGED"));
/**
* If the old password was stored, update it with the
* new one. If the old password was not stored, leave it
* like it is.
*/
if (isRememberPassword())
{
try
{
if(logger.isInfoEnabled())
logger.info("Storing new password for"
+ " account " + protocolProvider.
getAccountID().getAccountAddress());
storeNewPassword(newPass1);
}
catch (IllegalArgumentException ex)
{
//If we get here its a bug, and showing a
//message like this might be unappropriate. But
//the user would want to know about it!
logger.warn("Failed to store password for"
+ " account " + protocolProvider.
getAccountID().getAccountAddress(),
ex);
loadMessage(Resources.getString(
"plugin.jabberaccregwizz."
+ "PASSWORD_NOT_STORED"));
}
//now update the password field in AccountPanel,
//because it still has the old pass and if the user
//completes the wizard it will store it.
passField.setText(newPass1);
}
hideCancelAndFields();
okButton.removeActionListener(this);
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
}
});
}
catch (IllegalStateException ex) {
//we already checked for this, but if the connection
//has since been lost smack will throw this
loadMessage(Resources.getString(
"plugin.jabberaccregwizz.HAS_TO_BE_LOGGED_IN"));
}
catch (OperationFailedException ex) {
loadMessage(Resources.getString(
"plugin.jabberaccregwizz."
+ "SERVER_NOT_SUPPORT_PASSWORD_CHANGE"));
}
}
}
};
/**
* Loads the given message into the message pane.
* @param message The message to load
*/
private void loadMessage(String message)
{
messagePane.setText(message);
mainPanel.revalidate();
mainPanel.repaint();
pack();
}
/**
* Leaves only the message pane and the "ok" button visible
* XXX: a more appropriate name?
*/
public void hideCancelAndFields()
{
cancelButton.setVisible(false);
passField1.setVisible(false);
passField2.setVisible(false);
passLabel1.setVisible(false);
passLabel2.setVisible(false);
pack();
}
/**
* Stores the new password in the account configuration
* @param newPass The new password
* @throws IllegalArgumentException on failure (from
* ProtocolProviderFactory.storePassword)
*/
void storeNewPassword(String newPass) throws IllegalArgumentException
{
AccountID accountID = parentForm.getWizard().getProtocolProvider().
getAccountID();
ProtocolProviderFactory protocolProviderFactory =
JabberAccRegWizzActivator.getJabberProtocolProviderFactory();
protocolProviderFactory.storePassword(accountID, newPass);
}
}
}