/**
* $RCSfile: ,v $
* $Revision: $
* $Date: $
*
* Copyright (C) 2004-2011 Jive Software. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.spark.ui;
import org.jivesoftware.Spark;
import org.jivesoftware.resource.Res;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.RosterGroup;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.RosterPacket;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.spark.SparkManager;
import org.jivesoftware.spark.UserManager;
import org.jivesoftware.spark.component.RolloverButton;
import org.jivesoftware.spark.component.TitlePanel;
import org.jivesoftware.spark.component.borders.ComponentTitledBorder;
import org.jivesoftware.spark.util.ModelUtil;
import org.jivesoftware.spark.util.ResourceUtils;
import org.jivesoftware.spark.util.log.Log;
import org.jivesoftware.sparkimpl.plugin.gateways.transports.Transport;
import org.jivesoftware.sparkimpl.plugin.gateways.transports.TransportUtils;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
* SubscriptionDialog handles all subscription requests.
*
* @author Derek DeMoro
*/
public class SubscriptionDialog {
private final RolloverButton acceptButton = new RolloverButton();
private final RolloverButton viewInfoButton = new RolloverButton();
private final RolloverButton denyButton = new RolloverButton();
private final JPanel mainPanel;
private final JCheckBox rosterBox = new JCheckBox();
private final JLabel nicknameLabel = new JLabel();
private final JTextField nicknameField = new JTextField();
private final JLabel groupLabel = new JLabel();
private final JComboBox groupBox = new JComboBox();
private JLabel usernameLabel = new JLabel();
private JLabel usernameLabelValue = new JLabel();
private JFrame dialog;
private String jid;
public SubscriptionDialog() {
mainPanel = new JPanel();
mainPanel.setLayout(new GridBagLayout());
// Add Roster Addition
final JPanel rosterPanel = new JPanel();
rosterPanel.setLayout(new GridBagLayout());
// Add ResourceUtils
ResourceUtils.resLabel(usernameLabel, nicknameField, Res.getString("label.username") + ":");
ResourceUtils.resLabel(nicknameLabel, nicknameField, Res.getString("label.nickname") + ":");
ResourceUtils.resLabel(groupLabel, groupBox, Res.getString("label.group") + ":");
rosterBox.setText(Res.getString("label.add.to.roster"));
groupBox.setEditable(true);
rosterBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
nicknameField.setEnabled(rosterBox.isSelected());
groupBox.setEnabled(rosterBox.isSelected());
}
});
rosterBox.setSelected(true);
ComponentTitledBorder componentBorder = new ComponentTitledBorder(rosterBox, rosterPanel, BorderFactory.createEtchedBorder());
rosterPanel.add(usernameLabel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
rosterPanel.add(usernameLabelValue, new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0));
rosterPanel.add(nicknameLabel, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
rosterPanel.add(nicknameField, new GridBagConstraints(1, 2, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0));
rosterPanel.add(groupLabel, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
rosterPanel.add(groupBox, new GridBagConstraints(1, 3, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0));
rosterPanel.add(new JLabel(), new GridBagConstraints(1, 4, 1, 1, 1.0, 1.0, GridBagConstraints.SOUTH, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0));
// Add Roster Panel to mainPanel
mainPanel.add(rosterPanel, new GridBagConstraints(2, 1, 5, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0));
rosterPanel.setBorder(componentBorder);
// Add Buttons
ResourceUtils.resButton(acceptButton, Res.getString("button.accept"));
ResourceUtils.resButton(viewInfoButton, Res.getString("button.profile"));
ResourceUtils.resButton(denyButton, Res.getString("button.deny"));
mainPanel.add(acceptButton, new GridBagConstraints(3, 2, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHEAST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 5));
mainPanel.add(viewInfoButton, new GridBagConstraints(4, 2, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHEAST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 5));
mainPanel.add(denyButton, new GridBagConstraints(5, 2, 1, 1, 0.0, 1.0, GridBagConstraints.NORTHEAST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 5));
// Set Group Box
for (ContactGroup group : SparkManager.getWorkspace().getContactList().getContactGroups()) {
if (!group.isOfflineGroup() && !"Unfiled".equalsIgnoreCase(group.getGroupName()) && !group.isSharedGroup()) {
groupBox.addItem(group.getGroupName());
}
}
groupBox.setEditable(true);
if (groupBox.getItemCount() == 0) {
groupBox.addItem("Friends");
}
if (groupBox.getItemCount() > 0) {
groupBox.setSelectedIndex(0);
}
}
public void invoke(final String jid) {
this.jid = jid;
final Roster roster = SparkManager.getConnection().getRoster();
// If User is already in roster, do not show.
RosterEntry entry = roster.getEntry(jid);
if (entry != null && entry.getType() == RosterPacket.ItemType.to) {
Presence response = new Presence(Presence.Type.subscribed);
response.setTo(jid);
SparkManager.getConnection().sendPacket(response);
return;
}
String message = Res.getString("message.approve.subscription", UserManager.unescapeJID(jid));
Transport transport = TransportUtils.getTransport(StringUtils.parseServer(jid));
Icon icon = null;
if (transport != null) {
icon = transport.getIcon();
}
TitlePanel messageLabel = new TitlePanel("", message, icon, true);
// Add Message Label
mainPanel.add(messageLabel, new GridBagConstraints(0, 0, 6, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
UserManager userManager = SparkManager.getUserManager();
String username = userManager.getNickname(userManager.getFullJID(jid));
username = username == null ? StringUtils.parseName(UserManager.unescapeJID(jid)) : username;
usernameLabelValue.setText(UserManager.unescapeJID(jid));
nicknameField.setText(username);
acceptButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (!rosterBox.isSelected()) {
Presence response = new Presence(Presence.Type.subscribed);
response.setTo(jid);
SparkManager.getConnection().sendPacket(response);
dialog.dispose();
return;
}
boolean addEntry = addEntry();
if (addEntry) {
Presence response = new Presence(Presence.Type.subscribed);
response.setTo(jid);
SparkManager.getConnection().sendPacket(response);
}
else {
dialog.dispose();
}
}
});
denyButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Send subscribed
unsubscribeAndClose();
}
});
viewInfoButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
SparkManager.getVCardManager().viewProfile(jid, mainPanel);
}
});
dialog = new JFrame(Res.getString("title.subscription.request")){
private static final long serialVersionUID = 5713933518069623228L;
public Dimension getPreferredSize() {
final Dimension dim = super.getPreferredSize();
dim.width = 400;
return dim;
}
};
dialog.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
dialog.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
unsubscribeAndClose();
}
});
KeyStroke key = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
ActionListener action = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
unsubscribeAndClose();
}
};
dialog.getRootPane().registerKeyboardAction(action,key,JComponent.WHEN_FOCUSED);
dialog.setIconImage(SparkManager.getApplicationImage().getImage());
dialog.getContentPane().add(mainPanel);
dialog.pack();
dialog.setLocationRelativeTo(SparkManager.getMainWindow());
if (SparkManager.getMainWindow().isFocused()) {
dialog.setState(Frame.NORMAL);
dialog.setVisible(true);
}
else if (!SparkManager.getMainWindow().isVisible() || !SparkManager.getMainWindow().isFocused()) {
if (Spark.isWindows()) {
dialog.setFocusable(false);
dialog.setState(Frame.ICONIFIED);
}
SparkManager.getNativeManager().flashWindowStopOnFocus(dialog);
dialog.setVisible(true);
}
}
private void unsubscribeAndClose()
{
Presence response = new Presence(Presence.Type.unsubscribe);
response.setTo(jid);
SparkManager.getConnection().sendPacket(response);
dialog.dispose();
}
private boolean addEntry() {
String errorMessage = Res.getString("title.error");
String nickname = nicknameField.getText();
String group = (String)groupBox.getSelectedItem();
ContactGroup contactGroup = SparkManager.getWorkspace().getContactList().getContactGroup(group);
boolean isSharedGroup = contactGroup != null && contactGroup.isSharedGroup();
if (isSharedGroup) {
errorMessage = Res.getString("message.cannot.add.contact.to.shared.group");
}
else if (!ModelUtil.hasLength(nickname)) {
errorMessage = Res.getString("message.specify.contact.jid");
}
else if (!ModelUtil.hasLength(group)) {
errorMessage = Res.getString("message.specify.group");
}
else if (ModelUtil.hasLength(nickname) && ModelUtil.hasLength(group) && !isSharedGroup) {
addEntry(jid, nickname, group);
dialog.setVisible(false);
return true;
}
JOptionPane.showMessageDialog(dialog, errorMessage, Res.getString("title.error"), JOptionPane.ERROR_MESSAGE);
return false;
}
/**
* Adds a new entry to the users Roster.
*
* @param jid the jid.
* @param nickname the nickname.
* @param group the contact group.
* @return the new RosterEntry.
*/
public RosterEntry addEntry(String jid, String nickname, String group) {
String[] groups = {group};
Roster roster = SparkManager.getConnection().getRoster();
RosterEntry userEntry = roster.getEntry(jid);
boolean isSubscribed = true;
if (userEntry != null) {
isSubscribed = userEntry.getGroups().size() == 0;
}
if (isSubscribed) {
try {
roster.createEntry(jid, nickname, new String[]{group});
}
catch (XMPPException e) {
Log.error("Unable to add new entry " + jid, e);
}
return roster.getEntry(jid);
}
try {
RosterGroup rosterGroup = roster.getGroup(group);
if (rosterGroup == null) {
rosterGroup = roster.createGroup(group);
}
if (userEntry == null) {
roster.createEntry(jid, nickname, groups);
userEntry = roster.getEntry(jid);
}
else {
userEntry.setName(nickname);
rosterGroup.addEntry(userEntry);
}
userEntry = roster.getEntry(jid);
}
catch (XMPPException ex) {
Log.error(ex);
}
return userEntry;
}
}