/*FreeMind - A Program for creating and viewing Mindmaps
*Copyright (C) 2000-2001 Joerg Mueller <joergmueller@bigfoot.com>
*See COPYING for Details
*
*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; either version 2
*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 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 plugins.collaboration.jabber.mindmap;
import java.util.LinkedList;
import java.util.logging.Level;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import com.echomine.jabber.Jabber;
import com.echomine.jabber.JabberChatMessage;
import com.echomine.jabber.JabberCode;
import com.echomine.jabber.JabberContext;
import com.echomine.jabber.JabberMessageEvent;
import com.echomine.jabber.JabberMessageException;
import com.echomine.jabber.JabberMessageListener;
import com.echomine.jabber.JabberSession;
import freemind.controller.actions.generated.instance.CollaborationAction;
import freemind.controller.actions.generated.instance.CompoundAction;
import freemind.controller.actions.generated.instance.XmlAction;
import freemind.main.Tools;
import freemind.modes.mindmapmode.MindMapController;
import freemind.modes.mindmapmode.actions.xml.ActionPair;
/**
* @author RReppel - Connects to a jabber server. - Establishes a private chat
* with another user. - Listens to a limited number of FreeMind commands
* sent by the other user. - Performs the FreeMind actions corresponding
* to the commands sent.
*
*/
public class JabberListener {
// Logging:
private static java.util.logging.Logger logger;
MindMapController controller;
//A queue ensuring FIFO processing of user commands.
LinkedList commandQueue;
JabberSession session;
public JabberListener(MindMapController c,
MapSharingController sharingWizardController, String jabberServer,
int port, String userName, String password) {
controller = c;
if (logger == null) {
logger = controller.getController().getFrame().getLogger(
this.getClass().getName());
}
commandQueue = new LinkedList();
JabberContext context = new JabberContext(userName, password,
jabberServer);
Jabber jabber = new Jabber();
session = jabber.createSession(context);
try {
session.connect(jabberServer, port);
session.getUserService().login();
logger.info("User logged in.\n");
session.getPresenceService().setToAvailable("FreeMind Session",
null, false);
//Send a test message:
//JabberChatService chat = session.getChatService();
//chat.sendPrivateMessage(new JID("lucy@rreppel-linux"), "FreeMind
// launched.", false);
session.addMessageListener(new FreeMindJabberMessageListener(
sharingWizardController)); //end addMessageListener
} //end MindMapJabberController
catch (Exception ex) {
freemind.main.Resources.getInstance().logException(ex);
String message;
//TODO: Descriptive error message on Jabber server connection
// failure.
if (ex.getClass().getName().compareTo(
"com.echomine.jabber.JabberMessageException") == 0) {
JabberMessageException jabberMessageException = (JabberMessageException) ex;
message = jabberMessageException.getErrorMessage();
} else {
message = ex.getClass().getName() + "\n\n" + ex.getMessage();
} //endif
JFrame frame = new JFrame();
JOptionPane.showMessageDialog(frame, message, "Error",
JOptionPane.ERROR_MESSAGE);
//TODO: Bug: Do not move to the next screen when a connection error
// has occurred. Do not set status to "connected".
}
}
/**
* @return
*/
public JabberSession getSession() {
return session;
}
/**
*
* @author RReppel
*
* Listens to received Jabber messages and initiates the appropriate
* FreeMind actions.
*
*/
private class FreeMindJabberMessageListener implements
JabberMessageListener {
MapSharingController sharingWizardController;
public FreeMindJabberMessageListener(
MapSharingController sharingWizardController) {
super();
this.sharingWizardController = sharingWizardController;
}
public void messageReceived(JabberMessageEvent event) {
if (event.getMessageType() != JabberCode.MSG_CHAT)
return;
JabberChatMessage latestMsg = (JabberChatMessage) event
.getMessage();
if (latestMsg.getType().equals(JabberChatMessage.TYPE_CHAT)
|| latestMsg.getType()
.equals(JabberChatMessage.TYPE_NORMAL)) {
commandQueue.addLast(latestMsg); //Add the message to the end
// of the list of commands to
// be applied.
logger.info("Queue has " + commandQueue.size() + " items.");
JabberChatMessage msg = (JabberChatMessage) commandQueue
.removeFirst(); //Process the first command in the
String msgString = Tools.decompress(msg.getBody());
// list.
if(logger.isLoggable(Level.INFO)){
String displayMessage = ("Sending message:" + ((msgString
.length() < 100) ? msgString : (msgString
.substring(0, 50)
+ "..." + msgString
.substring(msgString.length() - 50))));
logger.info("message " + displayMessage + " from "
+ msg.getFrom().getUsername()
+ " is reply required:" + msg.isReplyRequired());
}
XmlAction action = controller.unMarshall(msgString);
if (action instanceof CollaborationAction) {
CollaborationAction xml = (CollaborationAction) action;
String cmd = xml.getCmd();
String username = xml.getUser();
try {
if (cmd.compareTo(JabberSender.REQUEST_MAP_SHARING) == 0) {
sharingWizardController
.setMapSharingRequested(username, xml.getMap(), xml.getFilename());
} else if (cmd
.compareTo(JabberSender.ACCEPT_MAP_SHARING) == 0) {
sharingWizardController.setMapShareRequestAccepted(
username, true);
} else if (cmd
.compareTo(JabberSender.DECLINE_MAP_SHARING) == 0) {
sharingWizardController.setMapShareRequestAccepted(
username, false);
} else if (cmd.compareTo(JabberSender.STOP_MAP_SHARING) == 0) {
sharingWizardController.setSharingStopped(username);
} else {
logger.warning("Unknown command:" + cmd);
}
} catch (Exception e) {
freemind.main.Resources.getInstance().logException(e);
} //end catch
} else if (action instanceof CompoundAction) {
CompoundAction pair = (CompoundAction) action;
if (pair
.getListChoiceList()
.size() != 2) {
//FIXME: Warn the user
logger.warning("Cannot process the message "
+ msgString);
return;
}
executeRemoteCommand(pair);
} else {
logger.warning("Unknown collaboration message:"+msgString);
}//endif
} //endif
} //end messageReceived
/** Executes a command that was received via the jabber channel.
* @param pair
*/
private void executeRemoteCommand(CompoundAction pair) {
XmlAction doAction = (XmlAction) pair
.getListChoiceList()
.get(0);
XmlAction undoAction = (XmlAction) pair
.getListChoiceList()
.get(1);
final ActionPair ePair = new ActionPair(doAction,
undoAction);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
sharingWizardController.setSendingEnabled(false);
try {
sharingWizardController.getController()
.getActionFactory()
.executeAction(ePair);
} catch (Exception e) {
// TODO: handle exception
freemind.main.Resources.getInstance().logException(e);
}
sharingWizardController.setSendingEnabled(true);
}
});
}
}
}