JOscarPlugin.java
| Index Score | ||
|---|---|---|
![]() |
![]() |
org.xnap.plugin.joscar |
![]() |
![]() |
XNap 3 |
View: Reasons, Metrics, Source Code
These are the metrics that contribute to the Enerjy Score for this file, ranked by impact. So the metrics listed at the top influence the score to a greater extent that the metrics listed at the bottom.
/*
* XNap - A P2P framework and client.
*
* See the file AUTHORS for copyright information.
*
* This program 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.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU 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 USA
*/
package org.xnap.plugin.joscar;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.JMenu;
import javax.swing.JOptionPane;
import org.apache.log4j.Logger;
import org.xnap.XNap;
import org.xnap.XNapFacade;
import org.xnap.action.*;
import org.xnap.chat.ChatManager;
import org.xnap.event.StateEvent;
import org.xnap.event.StateListener;
import org.xnap.gui.AbstractPreferencesDialog;
import org.xnap.gui.StatusBar;
import org.xnap.gui.XNapFrame;
import org.xnap.gui.component.XNapMenu;
import org.xnap.gui.component.XNapMenuItem;
import org.xnap.gui.event.AbstractPreferencesDialogListener;
import org.xnap.gui.util.IconHelper;
import org.xnap.peer.HotlistManager;
import org.xnap.plugin.AbstractPlugin;
import org.xnap.util.FileHelper;
import org.xnap.util.IllegalOperationException;
import org.xnap.util.State;
import JOscarLib.Integration.Event.IncomingMessageEvent;
import JOscarLib.Integration.Event.IncomingUrlEvent;
import JOscarLib.Integration.Event.IncomingUserEvent;
import JOscarLib.Integration.Event.MessagingListener;
import JOscarLib.Integration.Event.OffgoingUserEvent;
import JOscarLib.Integration.Event.OfflineMessageEvent;
import JOscarLib.Integration.Event.StatusListener;
/**
* Provides a simple chat plugin for ICQ.
*
* This class creates the connection to the oscar server and is responsible of
* managing the buddies and open chat channels, it also updates the online
* status of each buddy.
*/
public class JOscarPlugin extends AbstractPlugin
implements StateListener, MessagingListener, StatusListener,
PropertyChangeListener
{
//--- Constant(s) ---
public static String ICON_FILENAME = "licq.png";
public static Icon ICON_16 = IconHelper.getIcon(ICON_FILENAME, 16, false);
public static final String BUDDY_FILE =
FileHelper.getHomeDir() + "joscar_buddies";
//--- Data Field(s) ---
private static JOscarPlugin instance;
private PreferencesDialogListener listener;
/**
* The wrapped connection to the icq network.
*/
private JOscarConnection connection;
/**
* The local JOscarPeer.
*/
private JOscarPeer peer;
/**
* The list of active channels hashed by chat partner.
*/
private Map channelsByPeer;
/**
* The buddy list, hashed by their uins.
*/
private Map buddies;
/**
* Menu plugged into XNap's plugins menu.
*/
private JMenu jmOscar;
/**
* Displays if we're online or offline for now.
*/
private JOscarStatusPanel spOscar;
private JOscarPreferences prefs;
private static Logger logger = Logger.getLogger(JOscarPlugin.class);
//--- Constructor(s) ---
public JOscarPlugin()
{
}
//--- Method(s) ---
public static JOscarPlugin getInstance()
{
return instance;
}
/**
* Returns the name of the plugin.
*/
public String getName()
{
return getInfo().getName();
}
/**
* Starts the plugin.
*/
public void start()
{
instance = this;
prefs = JOscarPreferences.getInstance();
prefs.addPropertyChangeListener("username", this);
connection = new JOscarConnection();
connection.addStateListener(this);
peer = new JOscarPeer(prefs.getUsername());
channelsByPeer = Collections.synchronizedMap(new Hashtable());
buddies = Collections.synchronizedMap(new Hashtable());
readBuddiesList();
if (prefs.getAutoconnect()) {
connection.connect();
}
}
/**
* Starts the GUI of the plugin.
*/
public void startGUI()
{
initializeMenu();
XNapFrame.getInstance().getMainMenuBar().addPluginMenu(jmOscar);
listener = new PreferencesDialogListener();
XNapFacade.addPluginPreferencesDialogListener(listener);
// add status panel to GUI
spOscar = new JOscarStatusPanel();
connection.addStateListener(spOscar);
StatusBar.getInstance().addComponent(spOscar);
}
private void initializeMenu()
{
jmOscar = new XNapMenu(getName());
jmOscar.setIcon(IconHelper.getMenuIcon(ICON_FILENAME));
jmOscar.add(new XNapMenuItem(new AddBuddyAction()));
jmOscar.addSeparator();
jmOscar.add(new XNapMenuItem(new ConnectAction()));
jmOscar.add(new XNapMenuItem(new DisconnectAction()));
}
/**
* Stops the plugin. Disposes all singletons.
*/
public void stop()
{
removeChannels();
writeBuddiesList();
removeBuddies();
try {
connection.disconnect();
}
catch (IllegalOperationException ie) {
}
connection = null;
peer = null;
buddies = null;
channelsByPeer = null;
prefs.removePropertyChangeListener(this);
JOscarPreferences.disposeInstance();
prefs = null;
instance = null;
}
public synchronized void propertyChange(PropertyChangeEvent e)
{
peer = new JOscarPeer(prefs.getUsername());
if (connection.getState() == State.CONNECTED) {
connection.disconnect();
connection.connect();
}
}
/**
*
*/
public void stateChanged(StateEvent event)
{
if (connection.getState() == State.CONNECTED) {
connection.addMessagingListener(this);
connection.addStatusListener(this);
synchronized(buddies) {
for (Iterator i = buddies.keySet().iterator(); i.hasNext();) {
connection.addUser((String)i.next());
}
}
}
else {
}
}
/**
* Stops the GUI of the plugin.
*/
public void stopGUI()
{
listener.dispose();
XNapFacade.removePluginPreferencesDialogListener(listener);
listener = null;
XNapFrame.getInstance().getMainMenuBar().removePluginMenu(jmOscar);
jmOscar = null;
StatusBar.getInstance().removeComponent(spOscar);
connection.removeStateListener(spOscar);
spOscar = null;
}
/**
* Tells {@link ChatManager} to close all joscar channels.
*/
private void removeChannels()
{
synchronized (channelsByPeer) {
for (Iterator i = channelsByPeer.values().iterator();
i.hasNext();) {
ChatManager.getInstance().remove((JOscarChannel)i.next());
}
}
}
public void sendMessage(String uin, String message)
{
connection.sendMessage(uin, message);
}
public void sendSMS(String uin, String message)
{
connection.sendSMS(uin, message);
}
/**
* Creates a new {@link JOscarPeer} if it's not already in the
* <code>buddies</code> hashtable.
*/
public JOscarPeer addBuddy(String uin)
{
return addBuddy(new JOscarPeer(uin));
}
/**
* Creates a new {@link JOscarPeer} if it's not already in the
* <code>buddies</code> hashtable.
*
*/
public JOscarPeer addBuddy(JOscarPeer buddy)
{
if (!buddies.containsKey(buddy.getName())) {
connection.addStateListener(buddy);
buddies.put(buddy.getName(), buddy);
connection.addUser(buddy.getName());
HotlistManager.getInstance().add(buddy);
return buddy;
}
return (JOscarPeer)buddies.get(buddy.getName());
}
/**
* Returns the local peer.
*/
public synchronized JOscarPeer getLocalPeer()
{
return peer;
}
/**
* Returns the oscar connection for listeners to subscribe to.
*/
public JOscarConnection getConnection()
{
return connection;
}
/**
* Removes a buddy.
*/
public void removeBuddy(JOscarPeer buddy)
{
buddies.remove(buddy.getName());
connection.removeStateListener(buddy);
HotlistManager.getInstance().remove(buddy);
}
private void removeBuddies()
{
JOscarPeer[] peers =
(JOscarPeer[])buddies.values().toArray(new JOscarPeer[0]);
for (int i = 0; i < peers.length; i++) {
removeBuddy(peers[i]);
}
}
public void addChannel(JOscarChannel channel)
{
if (!channelsByPeer.containsKey(channel.getJOscarPeer())) {
channelsByPeer.put(channel.getJOscarPeer(), channel);
ChatManager.getInstance().add(channel);
}
}
public void removeChannel(JOscarChannel channel)
{
logger.debug("channel remove called for "
+ channel.getJOscarPeer().getName());
channelsByPeer.remove(channel.getJOscarPeer());
}
private void readBuddiesList()
{
LinkedList list = new LinkedList();
try {
FileHelper.readBinary(new File(BUDDY_FILE), list);
}
catch (IOException ie) {
logger.debug("error reading buddies file", ie);
}
for (Iterator i = list.iterator(); i.hasNext();) {
addBuddy((String)i.next());
}
}
private void writeBuddiesList()
{
try {
FileHelper.writeBinary(new File(BUDDY_FILE), buddies.keySet());
}
catch (IOException ie) {
logger.debug("error writing buddies file", ie);
}
}
/**
* Implements the {@link OscarListener} interface.
*/
public void onIncomingMessage(IncomingMessageEvent event)
{
JOscarPeer peer = addBuddy(event.getSenderID());
if (!channelsByPeer.containsKey(peer)) {
JOscarChannel channel = new JOscarChannel(peer);
addChannel(channel);
// show the first message, even if it's shown twice
channel.messageReceived(peer, event.getMessage());
}
}
/**
* Implements the {@link OscarListener} interface.
*/
public void onIncomingUrl(IncomingUrlEvent e)
{
}
/**
* Implements the {@link OscarListener} interface.
*/
public void onIncomingUser(IncomingUserEvent e)
{
JOscarPeer peer = (JOscarPeer)buddies.get(e.getIncomingUserId());
if (peer != null) {
logger.debug("buddy " + peer.getName()
+ " seems to have gone online");
peer.setStatus(e.getStatusMode().toString());
}
}
/**
* Implements the {@link OscarListener} interface.
*/
public void onOffgoingUser(OffgoingUserEvent e)
{
JOscarPeer peer = (JOscarPeer)buddies.get(e.getOffgoingUserId());
logger.debug("buddy " + peer.getName() + " seems to have gone offline");
if (peer != null) {
peer.setStatus(XNap.tr("Offline"));
}
}
/**
* Implements the {@link OscarListener} interface.
*/
public void onOfflineMessage(OfflineMessageEvent e)
{
logger.debug("buddy " + e.getSenderUin() + " is going offline, " +
e.getMessage());
}
// --- Inner Class(es) ---
private class AddBuddyAction extends AbstractAction
{
public AddBuddyAction()
{
putValue(Action.NAME, XNap.tr("Add Buddy"));
putValue(Action.SHORT_DESCRIPTION,
XNap.tr("Asks for a UIN and adds it to the Hotlist."));
putValue(IconHelper.XNAP_ICON, "edit_add.png");
}
public void actionPerformed(ActionEvent event)
{
Object[] message = new Object[] {
XNap.tr("Buddy UIN")
};
String uin = JOptionPane.showInputDialog
(XNapFrame.getInstance().getRootPane(), message,
XNap.tr("Add Buddy"), JOptionPane.PLAIN_MESSAGE);
if (uin != null) {
JOscarPlugin.getInstance().addBuddy(uin.trim());
}
}
}
private class ConnectAction extends AbstractXNapAction
implements StateListener
{
public ConnectAction()
{
putValue(Action.NAME, XNap.tr("Connect"));
putValue(IconHelper.XNAP_ICON, "connect_creating.png");
connection.addStateListener(this);
stateChanged(null);
}
public void actionPerformed(ActionEvent event)
{
connection.connect();
}
public void stateChanged(StateEvent e)
{
setEnabledLater(connection.getState() == State.DISCONNECTED);
}
}
private class DisconnectAction extends AbstractXNapAction
implements StateListener
{
public DisconnectAction()
{
putValue(Action.NAME, XNap.tr("Disconnect"));
putValue(IconHelper.XNAP_ICON, "connect_no.png");
connection.addStateListener(this);
stateChanged(null);
}
public void actionPerformed(ActionEvent event)
{
connection.disconnect();
}
public void stateChanged(StateEvent e)
{
setEnabledLater(connection.getState() == State.CONNECTED);
}
}
private class PreferencesDialogListener
extends AbstractPreferencesDialogListener
{
public void addPanels(AbstractPreferencesDialog dialog, List panels)
{
JOscarPreferencesPanel jpp = new JOscarPreferencesPanel();
panels.add(jpp);
panels.add(dialog.addPanel(jpp, ICON_FILENAME));
}
}
}
The table below shows all metrics for JOscarPlugin.java.




