/*
* 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.desktoputil;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import net.java.sip.communicator.service.gui.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.util.Logger;
import org.jitsi.util.*;
/**
* The AuthenticationWindow is the window where the user should type
* his user identifier and password to login.
*
* @author Yana Stamcheva
*/
public class AuthenticationWindow
extends SIPCommDialog
implements ActionListener,
AuthenticationWindowService.AuthenticationWindow
{
private static final long serialVersionUID = 1L;
/**
* Used for logging.
*/
private static Logger logger = Logger.getLogger(AuthenticationWindow.class);
/**
* Info text area.
*/
private final JTextArea infoTextArea = new JTextArea();
/**
* The uin component.
*/
private JComponent uinValue;
/**
* The password field.
*/
private final JPasswordField passwdField = new JPasswordField(15);
/**
* The login button.
*/
private final JButton loginButton = new JButton(
DesktopUtilActivator.getResources().getI18NString("service.gui.OK"));
/**
* The cancel button.
*/
private final JButton cancelButton = new JButton(
DesktopUtilActivator.getResources().getI18NString("service.gui.CANCEL"));
/**
* The check box indicating if the password should be remembered.
*/
private final JCheckBox rememberPassCheckBox = new SIPCommCheckBox(
DesktopUtilActivator.getResources()
.getI18NString("service.gui.REMEMBER_PASSWORD"),
DesktopUtilActivator.getConfigurationService()
.getBoolean(PNAME_SAVE_PASSWORD_TICKED, false));
/**
* Property to disable/enable allow save password option
* in authentication window. By default it is enabled.
*/
private static final String PNAME_ALLOW_SAVE_PASSWORD =
"net.java.sip.communicator.util.swing.auth.ALLOW_SAVE_PASSWORD";
/**
* Property to set whether the save password option in
* the authentication window is ticked by default or not.
* By default it is not ticked
*/
private static final String PNAME_SAVE_PASSWORD_TICKED =
"net.java.sip.communicator.util.swing.auth.SAVE_PASSWORD_TICKED";
/**
* The name of the server, for which this authentication window is about.
*/
private String server;
/**
* The user name.
*/
private String userName;
/**
* The password.
*/
private char[] password;
/**
* Indicates if the password should be remembered.
*/
private boolean isRememberPassword = false;
/**
* Indicates if the window has been canceled.
*/
private boolean isCanceled = false;
/**
* A lock used to synchronize data setting.
*/
private final Object lock = new Object();
/**
* The condition that decides whether to continue waiting for data.
*/
private boolean buttonClicked = false;
/**
* Used to override default Authentication window title.
*/
private String windowTitle = null;
/**
* Used to override default window text.
*/
private String windowText = null;
/**
* Used to override username label text.
*/
private String usernameLabelText = null;
/**
* Used to override password label text.
*/
private String passwordLabelText = null;
/**
* The sign up link if specified.
*/
private String signupLink = null;
/**
* Creates an instance of the LoginWindow.
*
* @param server the server name
* @param isUserNameEditable indicates if the user name is editable
* @param icon the icon to display on the left of the authentication window
*/
public AuthenticationWindow(String server,
boolean isUserNameEditable,
ImageIcon icon)
{
this(null, null, server, isUserNameEditable, false,
icon, null, null, null, null, null, null);
}
/**
* Creates an instance of the LoginWindow.
*
* @param server the server name
* @param isUserNameEditable indicates if the user name is editable
* @param icon the icon to display on the left of the authentication window
* @param windowTitle customized window title
* @param windowText customized window text
* @param usernameLabelText customized username field label text
* @param passwordLabelText customized password field label text
* @param errorMessage an error message if this dialog is shown to indicate
* the user that something went wrong
* @param signupLink an URL that allows the user to sign up
*/
AuthenticationWindow(String userName,
char[] password,
String server,
boolean isUserNameEditable,
boolean isRememberPassword,
ImageIcon icon,
String windowTitle,
String windowText,
String usernameLabelText,
String passwordLabelText,
String errorMessage,
String signupLink)
{
super(false);
this.windowTitle = windowTitle;
this.windowText = windowText;
this.usernameLabelText = usernameLabelText;
this.passwordLabelText = passwordLabelText;
this.isRememberPassword = isRememberPassword;
this.signupLink = signupLink;
init(userName, password, server, isUserNameEditable, icon, errorMessage);
}
/**
* Initializes this authentication window.
*
* @param server the server
* @param isUserNameEditable indicates if the user name is editable
* @param icon the icon to show on the authentication window
*/
private void init( String userName,
char[] password,
String server,
boolean isUserNameEditable,
ImageIcon icon,
String errorMessage)
{
this.server = server;
initIcon(icon);
if(!isUserNameEditable)
this.uinValue = new JLabel();
else
this.uinValue = new JTextField();
this.init(isUserNameEditable);
this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
this.enableKeyActions();
this.setResizable(false);
/*
* Workaround for the following bug:
* http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4446522
* Need to pack() the window after it's opened in order to obtain the
* correct size of our infoTextArea, otherwise window size is wrong and
* buttons on the south are cut.
*/
this.addWindowListener(new WindowAdapter()
{
@Override
public void windowOpened(WindowEvent e)
{
pack();
removeWindowListener(this);
}
});
if (OSUtils.IS_MAC)
getRootPane()
.putClientProperty("apple.awt.brushMetalLook", Boolean.TRUE);
if (userName != null)
{
if (uinValue instanceof JLabel)
((JLabel) uinValue).setText(userName);
else if (uinValue instanceof JTextField)
((JTextField) uinValue).setText(userName);
}
if (password != null)
passwdField.setText(new String(password));
if(errorMessage != null)
{
this.infoTextArea.setForeground(Color.RED);
this.infoTextArea.setText(errorMessage);
}
}
/**
* Creates an instance of the LoginWindow.
*
* @param userName the user name to set by default
* @param password the password to set by default
* @param server the server name this authentication window is about
* @param isUserNameEditable indicates if the user name should be editable
* by the user or not
* @param icon the icon displayed on the left of the authentication window
* @param errorMessage an error message explaining a reason for opening
* the authentication dialog (when a wrong password was provided, etc.)
*/
public AuthenticationWindow(String userName,
char[] password,
String server,
boolean isUserNameEditable,
ImageIcon icon,
String errorMessage)
{
this(userName, password, server,
isUserNameEditable,
false,
icon, null, null, null, null, errorMessage, null);
}
/**
* Creates an instance of the LoginWindow.
*
* @param userName the user name to set by default
* @param password the password to set by default
* @param server the server name this authentication window is about
* @param isUserNameEditable indicates if the user name should be editable
* by the user or not
* @param icon the icon displayed on the left of the authentication window
* @param errorMessage an error message explaining a reason for opening
* the authentication dialog (when a wrong password was provided, etc.)
* @param signupLink an URL that allows the user to sign up
*/
public AuthenticationWindow(String userName,
char[] password,
String server,
boolean isUserNameEditable,
ImageIcon icon,
String errorMessage,
String signupLink)
{
this(userName, password, server,
isUserNameEditable,
false,
icon, null, null, null, null, errorMessage, signupLink);
}
/**
* Creates an instance of the LoginWindow.
*
* @param userName the user name to set by default
* @param password the password to set by default
* @param server the server name this authentication window is about
* @param isUserNameEditable indicates if the user name should be editable
* by the user or not
* @param icon the icon displayed on the left of the authentication window
*/
public AuthenticationWindow(
String userName,
char[] password,
String server,
boolean isUserNameEditable,
ImageIcon icon)
{
this(userName, password, server, isUserNameEditable, icon, null, null);
}
/**
* Creates an instance of the LoginWindow.
*
* @param owner the owner of this dialog
* @param userName the user name to set by default
* @param password the password to set by default
* @param server the server name this authentication window is about
* @param isUserNameEditable indicates if the user name should be editable
* by the user or not
* @param icon the icon displayed on the left of the authentication window
*/
public AuthenticationWindow(
Dialog owner,
String userName,
char[] password,
String server,
boolean isUserNameEditable,
ImageIcon icon)
{
super(owner, false);
init(userName, password, server, isUserNameEditable, icon, null);
}
/**
* Shows or hides the "save password" checkbox.
* @param allow the checkbox is shown when allow is true
*/
public void setAllowSavePassword(boolean allow)
{
rememberPassCheckBox.setVisible(allow);
}
/**
* Initializes the icon image.
*
* @param icon the icon to show on the left of the window
*/
private void initIcon(ImageIcon icon)
{
// If an icon isn't provided set the application logo icon by default.
if (icon == null)
icon = DesktopUtilActivator.getResources()
.getImage("service.gui.SIP_COMMUNICATOR_LOGO_64x64");
JLabel iconLabel = new JLabel(icon);
iconLabel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
iconLabel.setAlignmentY(Component.TOP_ALIGNMENT);
JPanel iconPanel = new TransparentPanel(new BorderLayout());
iconPanel.add(iconLabel, BorderLayout.NORTH);
getContentPane().add(iconPanel, BorderLayout.WEST);
}
/**
* Constructs the LoginWindow.
* @param isUserNameEditable indicates if the user name is editable
*/
private void init(boolean isUserNameEditable)
{
String title;
if(windowTitle != null)
title = windowTitle;
else
title = DesktopUtilActivator.getResources().getI18NString(
"service.gui.AUTHENTICATION_WINDOW_TITLE", new String[]{server});
String text;
if(windowText != null)
text = windowText;
else
text = DesktopUtilActivator.getResources().getI18NString(
"service.gui.AUTHENTICATION_REQUESTED_SERVER",
new String[]{server});
String uinText;
boolean showUsernameInDialog = true;
if(usernameLabelText != null)
{
// if username is not editable and username label text is empty
// we do not want to display it
if(usernameLabelText.length() == 0
&& !isUserNameEditable)
{
showUsernameInDialog = false;
}
uinText = usernameLabelText;
}
else
uinText = DesktopUtilActivator.getResources().getI18NString(
"service.gui.IDENTIFIER");
String passText;
if(passwordLabelText != null)
passText = passwordLabelText;
else
passText = DesktopUtilActivator.getResources().getI18NString(
"service.gui.PASSWORD");
setTitle(title);
infoTextArea.setEditable(false);
infoTextArea.setOpaque(false);
infoTextArea.setLineWrap(true);
infoTextArea.setWrapStyleWord(true);
infoTextArea.setFont(
infoTextArea.getFont().deriveFont(Font.BOLD));
infoTextArea.setText(text);
infoTextArea.setAlignmentX(0.5f);
JLabel uinLabel = new JLabel(uinText);
uinLabel.setFont(uinLabel.getFont().deriveFont(Font.BOLD));
JLabel passwdLabel = new JLabel(passText);
passwdLabel.setFont(passwdLabel.getFont().deriveFont(Font.BOLD));
TransparentPanel labelsPanel
= new TransparentPanel(new GridLayout(0, 1, 8, 8));
if(showUsernameInDialog)
labelsPanel.add(uinLabel);
labelsPanel.add(passwdLabel);
TransparentPanel textFieldsPanel
= new TransparentPanel(new GridLayout(0, 1, 8, 8));
if(showUsernameInDialog)
textFieldsPanel.add(uinValue);
textFieldsPanel.add(passwdField);
JPanel southFieldsPanel = new TransparentPanel(new GridLayout(1, 2));
this.rememberPassCheckBox.setOpaque(false);
this.rememberPassCheckBox.setBorder(null);
southFieldsPanel.add(rememberPassCheckBox);
if (signupLink != null && signupLink.length() > 0)
southFieldsPanel.add(createWebSignupLabel(
DesktopUtilActivator.getResources().getI18NString(
"plugin.simpleaccregwizz.SIGNUP"), signupLink));
else
southFieldsPanel.add(new JLabel());
boolean allowRememberPassword = true;
String allowRemPassStr = DesktopUtilActivator.getResources().getSettingsString(
PNAME_ALLOW_SAVE_PASSWORD);
if(allowRemPassStr != null)
{
allowRememberPassword = Boolean.parseBoolean(allowRemPassStr);
}
allowRememberPassword = DesktopUtilActivator.getConfigurationService()
.getBoolean(PNAME_ALLOW_SAVE_PASSWORD, allowRememberPassword);
setAllowSavePassword(allowRememberPassword);
JPanel buttonPanel
= new TransparentPanel(new FlowLayout(FlowLayout.CENTER));
buttonPanel.add(loginButton);
buttonPanel.add(cancelButton);
JPanel southEastPanel = new TransparentPanel(new BorderLayout());
southEastPanel.add(buttonPanel, BorderLayout.EAST);
TransparentPanel mainPanel
= new TransparentPanel(new BorderLayout(10, 10));
mainPanel.setBorder(
BorderFactory.createEmptyBorder(20, 0, 20, 20));
JPanel mainFieldsPanel = new TransparentPanel(new BorderLayout(0, 10));
mainFieldsPanel.add(labelsPanel, BorderLayout.WEST);
mainFieldsPanel.add(textFieldsPanel, BorderLayout.CENTER);
mainFieldsPanel.add(southFieldsPanel, BorderLayout.SOUTH);
mainPanel.add(infoTextArea, BorderLayout.NORTH);
mainPanel.add(mainFieldsPanel, BorderLayout.CENTER);
mainPanel.add(southEastPanel, BorderLayout.SOUTH);
this.getContentPane().add(mainPanel, BorderLayout.EAST);
this.loginButton.setName("ok");
this.cancelButton.setName("cancel");
if(loginButton.getPreferredSize().width
> cancelButton.getPreferredSize().width)
cancelButton.setPreferredSize(loginButton.getPreferredSize());
else
loginButton.setPreferredSize(cancelButton.getPreferredSize());
this.loginButton.setMnemonic(
DesktopUtilActivator.getResources().getI18nMnemonic("service.gui.OK"));
this.cancelButton.setMnemonic(
DesktopUtilActivator.getResources().getI18nMnemonic("service.gui.CANCEL"));
this.loginButton.addActionListener(this);
this.cancelButton.addActionListener(this);
this.getRootPane().setDefaultButton(loginButton);
}
/**
* Handles the ActionEvent triggered when one of the buttons is
* clicked. When "Login" button is chosen installs a new account from
* the user input and logs in.
*
* @param evt the action event that has just occurred.
*/
public void actionPerformed(ActionEvent evt)
{
JButton button = (JButton) evt.getSource();
String buttonName = button.getName();
if ("ok".equals(buttonName))
{
if(uinValue instanceof JLabel)
userName = ((JLabel) uinValue).getText();
else if(uinValue instanceof JTextField)
userName = ((JTextField) uinValue).getText();
password = passwdField.getPassword();
isRememberPassword = rememberPassCheckBox.isSelected();
}
else
{
isCanceled = true;
}
// release the caller that opened the window
buttonClicked = true;
synchronized (lock)
{
lock.notify();
}
this.dispose();
}
/**
* Enables the actions when a key is pressed, for now
* closes the window when esc is pressed.
*/
private void enableKeyActions()
{
@SuppressWarnings("serial")
UIAction act = new UIAction()
{
public void actionPerformed(ActionEvent e)
{
close(true);
}
};
getRootPane().getActionMap().put("close", act);
InputMap imap = this.getRootPane().getInputMap(
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
imap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "close");
}
/**
* Automatically clicks the cancel button, when this window is closed.
*
* @param isEscaped indicates if the window has been closed by pressing the
* Esc key
*/
@Override
protected void close(boolean isEscaped)
{
this.cancelButton.doClick();
}
/**
* Shows this modal dialog.
*
* @param isVisible specifies whether we should be showing or hiding the
* window.
*/
@Override
public void setVisible(final boolean isVisible)
{
this.setName("AUTHENTICATION");
if(getOwner() != null)
setModal(true);
if(isVisible)
{
addWindowFocusListener(new WindowAdapter() {
@Override
public void windowGainedFocus(WindowEvent e)
{
removeWindowFocusListener(this);
if (uinValue instanceof JTextField &&
"".equals(((JTextField) uinValue).getText()))
{
uinValue.requestFocusInWindow();
}
else
passwdField.requestFocusInWindow();
}
});
}
super.setVisible(isVisible);
if(isVisible)
{
if(getOwner() != null)
return;
synchronized (lock)
{
while(!buttonClicked)
{
try
{
lock.wait();
}
catch (InterruptedException e)
{} // we don't care, just retry
}
}
}
}
/**
* Indicates if this window has been canceled.
*
* @return true if this window has been canceled, false -
* otherwise
*/
public boolean isCanceled()
{
return isCanceled;
}
/**
* Returns the user name entered by the user or previously set if the
* user name is not editable.
*
* @return the user name
*/
public String getUserName()
{
return userName;
}
/**
* Returns the password entered by the user.
*
* @return the password
*/
public char[] getPassword()
{
return password;
}
/**
* Indicates if the password should be remembered.
*
* @return true if the password should be remembered,
* false - otherwise
*/
public boolean isRememberPassword()
{
return isRememberPassword;
}
/**
* Creates the subscribe label.
* @param linkName the link name
* @return the newly created subscribe label
*/
private Component createWebSignupLabel( String linkName,
final String linkURL)
{
JLabel subscribeLabel =
new JLabel(""
+ linkName
+ "",
JLabel.RIGHT);
subscribeLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
subscribeLabel.setToolTipText(
DesktopUtilActivator.getResources().getI18NString(
"plugin.simpleaccregwizz.SPECIAL_SIGNUP"));
subscribeLabel.addMouseListener(new MouseAdapter()
{
@Override
public void mousePressed(MouseEvent e)
{
try
{
DesktopUtilActivator.getBrowserLauncher()
.openURL(linkURL);
}
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 subscribeLabel;
}
/**
* Returns the icon corresponding to the given protocolProvider.
*
* @param protocolProvider the ProtocolProviderService, which icon
* we're looking for
* @return the icon to show on the authentication window
*/
public static ImageIcon getAuthenticationWindowIcon(
ProtocolProviderService protocolProvider)
{
Image image = null;
if(protocolProvider != null)
{
ProtocolIcon protocolIcon = protocolProvider.getProtocolIcon();
if(protocolIcon.isSizeSupported(ProtocolIcon.ICON_SIZE_64x64))
image = ImageUtils.getBytesInImage(
protocolIcon.getIcon(ProtocolIcon.ICON_SIZE_64x64));
else if(protocolIcon.isSizeSupported(ProtocolIcon.ICON_SIZE_48x48))
image = ImageUtils.getBytesInImage(
protocolIcon.getIcon(ProtocolIcon.ICON_SIZE_48x48));
}
if (image != null)
return new ImageIcon(image);
return null;
}
}