From d3061b8371ff844d58d918bc1afc91fc6e779187 Mon Sep 17 00:00:00 2001 From: Damian Minkov Date: Thu, 14 Feb 2008 15:14:12 +0000 Subject: [PATCH] Chat Alerter Plugin --- build.xml | 13 +- lib/felix.client.run.properties | 2 + lib/installer-exclude/jdic_misc.jar | Bin 0 -> 5731 bytes lib/native/linux/libjdic_misc.so | Bin 0 -> 3168 bytes lib/native/windows/jdic_misc.dll | Bin 0 -> 53248 bytes .../impl/gui/PopupDialogImpl.java | 9 + .../impl/gui/main/chat/ChatWindow.java | 8 + .../main/configforms/ConfigurationFrame.java | 9 + .../addcontact/AddContactWizard.java | 9 + .../gui/main/login/AuthenticationWindow.java | 9 + .../plugin/branding/AboutWindow.java | 10 +- .../contactinfo/ChatAlerterActivator.java | 353 ++++++++++++++++++ .../contactinfo/chatalerter.manifest.mf | 12 + .../service/gui/ExportedWindow.java | 6 + 14 files changed, 438 insertions(+), 2 deletions(-) create mode 100644 lib/installer-exclude/jdic_misc.jar create mode 100755 lib/native/linux/libjdic_misc.so create mode 100755 lib/native/windows/jdic_misc.dll create mode 100644 src/net/java/sip/communicator/plugin/contactinfo/ChatAlerterActivator.java create mode 100644 src/net/java/sip/communicator/plugin/contactinfo/chatalerter.manifest.mf diff --git a/build.xml b/build.xml index d1f0575c5..078e979c5 100644 --- a/build.xml +++ b/build.xml @@ -606,7 +606,7 @@ bundle-pluginmanager,bundle-notification, bundle-ssh,bundle-plugin-sshaccregwizz, bundle-contacteventhandler,bundle-plugin-contactinfo, - bundle-plugin-accountinfo"/> + bundle-plugin-accountinfo,bundle-plugin-chatalerter"/> @@ -1530,6 +1530,17 @@ javax.swing.event, javax.swing.border"/> prefix="net/java/sip/communicator/plugin/contactinfo"/> + + + + + + + + + diff --git a/lib/felix.client.run.properties b/lib/felix.client.run.properties index 6e988a795..1b288adcc 100644 --- a/lib/felix.client.run.properties +++ b/lib/felix.client.run.properties @@ -36,6 +36,7 @@ org.osgi.framework.system.packages= org.osgi.framework; ; version=1.3.0, \ org.jdesktop.jdic.tray; \ org.jdesktop.jdic.desktop; \ com.apple.eio; \ + com.apple.cocoa.application; \ org.xml.sax.helpers; \ javax.crypto; \ javax.crypto.spec; \ @@ -112,6 +113,7 @@ felix.auto.start.60= \ reference:file:sc-bundles/contacteventhandler.jar \ reference:file:sc-bundles/contactinfo.jar \ reference:file:sc-bundles/accountinfo.jar \ + reference:file:sc-bundles/chatalerter.jar \ reference:file:sc-bundles/shutdown.jar # Uncomment the following lines if you want to run the architect viewer diff --git a/lib/installer-exclude/jdic_misc.jar b/lib/installer-exclude/jdic_misc.jar new file mode 100644 index 0000000000000000000000000000000000000000..2f53c56a6081b307ea3f6cbdfa6ad58e04a90304 GIT binary patch literal 5731 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 VFof730{|zmKY#3I8lu4c`yW#~&MyD} literal 0 HcmV?d00001 diff --git a/lib/native/linux/libjdic_misc.so b/lib/native/linux/libjdic_misc.so new file mode 100755 index 0000000000000000000000000000000000000000..816229dbbfa4a927754b7b4b2c9217836ff16955 GIT binary patch literal 3168 zcmcImZ)_Ar6rZ*S6gg?ZLoTuEX{sq2Hl?5;hD4w&txY9psgyLhZm&ywcz^2cwt%6r zbs_0xt!czBeo>MdzY$~PixQKDBN`GUO;JMP2T2rjgsLS}Xw1p_`_0|RQ6V8FzV>%- z-n`$uc{BTFcHh!lx0aQa2_+SxLeQG25Mmwl(aM5nors8ls1sqaQu-C2Igu@qPWECOU)XbN*@{2&d; zeE^qmKfu_`aWTLc6l(f8hH*wj?XWntaWVTimT|uP>Ai!E`uEcp-sq_LV)W|L4+Dv( zuAKXwDcmMUODt@|ZTl2~{d9?+_Q9gP4|+K;QnaZ!zNTmoU{Q~w{eID=qW>&Vvyzq& z%fwax1a!E>J~_|kn6cu*mtz;6hy4yV-Yu%yz7FW8AcD%N8x>fN7-CJ;vT{%YNNS^`Q}q z8i|-4HDZarxX~I*_V3>mx6&A7*p}0t?y-{51I@9dBU(1?++j3X4wUGC-uWWCZPC$I z(%zc3ED?`&?KSr~nw?@Z3avdW46EC8Ok~+*+lBnmmFyNxtuJhDG#a!u+FC5OMELy6 z=KXz!KJFRCel&)%DHrDorl`g~vqnNieGL0p4%A`)%7K1r6z32%_IC!GyAYGiQsWuS zQKR50F@6#HgVeCwGnd-j=|GOtbPi`9$gJ=Cho_tcxku2O`+z^Qh}qG3I_rPV zs`kg33&kI2#rCp!`67n-<6J>6-Ipg}GJft|Si{*0#Ku%ZCuE)VulL+M=b3OG^4t&@ znLussEA(7h;!XrIZWvwulqa=UeR!(>^4Bg$mbs?_ox8K6$Df2D^UrB$3}?qt(}?dK z2{Y`Jv%)(vS7w>?$rvriuBcWt!3osjR&A3#xfKJ2u8WdZjJ*?M>ew&Td{N z#Hbs@ri^aSdmHoaobOa+&ij+z*1Y>$0A~NS&R2J5=hajY!*a8K`Tj1{54J%dfM2TF zMtO-(ikjzuRmHo5_bBfOR^4&nkDGpqWORud)GIUNt+2vXi+DXwh_3X_C^r^gUv)Niohuhz>g-Q$U9rZ zm5o8EM8d**;9jK)MAjf{fptl=0(hiSSg!=@@w%!R780-lYCdm8k;{0jXW}B-jKN{l ztmB6PjwO%vPq6NlkV|<2VC|B}x+Qpfs(IN@Gytr1wps5)1nts!VTw%vzhlVbxgmIN zprnw`OTPtBydgLVbsl*}6|W6#=F0QSb57Kwt%N+vHbC(vz#-=I$lX=Kn*oR5J4*?3 zpcsIP$9sj4?<46g`8PLk7=2Wh0;2l#&3GZ)gjbF(C literal 0 HcmV?d00001 diff --git a/lib/native/windows/jdic_misc.dll b/lib/native/windows/jdic_misc.dll new file mode 100755 index 0000000000000000000000000000000000000000..c0cbd412c59331da9aeb602096e6b916393d3b60 GIT binary patch literal 53248 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 TfiQtEfiQtEfiQvpHG%&ClLmdK literal 0 HcmV?d00001 diff --git a/src/net/java/sip/communicator/impl/gui/PopupDialogImpl.java b/src/net/java/sip/communicator/impl/gui/PopupDialogImpl.java index b58416bca..78993cfb5 100644 --- a/src/net/java/sip/communicator/impl/gui/PopupDialogImpl.java +++ b/src/net/java/sip/communicator/impl/gui/PopupDialogImpl.java @@ -254,4 +254,13 @@ public void minimize() public void maximize() { } + + /** + * The source of the window + * @return the source of the window + */ + public Object getSource() + { + return this; + } } diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindow.java b/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindow.java index 20d5c7db7..6671d2a44 100755 --- a/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindow.java +++ b/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindow.java @@ -671,4 +671,12 @@ public void pluginComponentRemoved(PluginComponentEvent event) } } + /** + * The source of the window + * @return the source of the window + */ + public Object getSource() + { + return this; + } } diff --git a/src/net/java/sip/communicator/impl/gui/main/configforms/ConfigurationFrame.java b/src/net/java/sip/communicator/impl/gui/main/configforms/ConfigurationFrame.java index 561b25685..7a2bf2612 100644 --- a/src/net/java/sip/communicator/impl/gui/main/configforms/ConfigurationFrame.java +++ b/src/net/java/sip/communicator/impl/gui/main/configforms/ConfigurationFrame.java @@ -221,4 +221,13 @@ public void bringToFront() { this.toFront(); } + + /** + * The source of the window + * @return the source of the window + */ + public Object getSource() + { + return this; + } } diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/addcontact/AddContactWizard.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/addcontact/AddContactWizard.java index 593c3e760..1c19aefbd 100644 --- a/src/net/java/sip/communicator/impl/gui/main/contactlist/addcontact/AddContactWizard.java +++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/addcontact/AddContactWizard.java @@ -213,4 +213,13 @@ public MainFrame getMainFrame() { return mainFrame; } + + /** + * The source of the window + * @return the source of the window + */ + public Object getSource() + { + return this; + } } diff --git a/src/net/java/sip/communicator/impl/gui/main/login/AuthenticationWindow.java b/src/net/java/sip/communicator/impl/gui/main/login/AuthenticationWindow.java index a0e1fd641..b75d5e58a 100644 --- a/src/net/java/sip/communicator/impl/gui/main/login/AuthenticationWindow.java +++ b/src/net/java/sip/communicator/impl/gui/main/login/AuthenticationWindow.java @@ -339,4 +339,13 @@ public void bringToFront() { this.toFront(); } + + /** + * The source of the window + * @return the source of the window + */ + public Object getSource() + { + return this; + } } diff --git a/src/net/java/sip/communicator/plugin/branding/AboutWindow.java b/src/net/java/sip/communicator/plugin/branding/AboutWindow.java index e36f86097..ee3f39525 100644 --- a/src/net/java/sip/communicator/plugin/branding/AboutWindow.java +++ b/src/net/java/sip/communicator/plugin/branding/AboutWindow.java @@ -239,5 +239,13 @@ public static void activateAntialiasing(Graphics g) g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); } - + + /** + * The source of the window + * @return the source of the window + */ + public Object getSource() + { + return this; + } } diff --git a/src/net/java/sip/communicator/plugin/contactinfo/ChatAlerterActivator.java b/src/net/java/sip/communicator/plugin/contactinfo/ChatAlerterActivator.java new file mode 100644 index 000000000..3b014f430 --- /dev/null +++ b/src/net/java/sip/communicator/plugin/contactinfo/ChatAlerterActivator.java @@ -0,0 +1,353 @@ +package net.java.sip.communicator.plugin.chatalerter; + +import java.util.*; +import javax.swing.*; +import org.osgi.framework.*; + +import net.java.sip.communicator.service.gui.*; +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.service.protocol.event.*; +import net.java.sip.communicator.util.*; + +import org.jdesktop.jdic.misc.*; + +/** + * The Activator of the Chat Alerter bundle. + * + * @author Damian Minkov + */ +public class ChatAlerterActivator + implements BundleActivator, + ServiceListener, + MessageListener, + ChatRoomMessageListener, + LocalUserChatRoomPresenceListener +{ + /** + * The logger for this class. + */ + private static Logger logger = Logger + .getLogger(ChatAlerterActivator.class); + + /** + * The BundleContext that we got from the OSGI bus. + */ + private BundleContext bundleContext = null; + + /** + * UIService reference. + */ + private UIService uiService; + + /** + * Starts this bundle. + */ + public void start(BundleContext bc) throws Exception + { + try + { + // try to load native libs, if it fails don't do anything + Alerter.newInstance(); + } + catch (Exception exception) + { + logger.info("The Alerter not supported or problem loading it!", + exception); + return; + } + + ServiceReference uiServiceRef + = bc.getServiceReference(UIService.class.getName()); + + uiService = (UIService) bc.getService(uiServiceRef); + + this.bundleContext = bc; + + // start listening for newly register or removed protocol providers + bc.addServiceListener(this); + + ServiceReference[] protocolProviderRefs = null; + try + { + protocolProviderRefs = bc.getServiceReferences( + ProtocolProviderService.class.getName(), + null); + } + catch (InvalidSyntaxException ex) + { + // this shouldn't happen since we're providing no parameter string + // but let's log just in case. + logger.error( + "Error while retrieving service refs", ex); + return; + } + + // in case we found any + if (protocolProviderRefs != null) + { + logger.debug("Found " + + protocolProviderRefs.length + + " already installed providers."); + for (int i = 0; i < protocolProviderRefs.length; i++) + { + ProtocolProviderService provider = (ProtocolProviderService) bc + .getService(protocolProviderRefs[i]); + + this.handleProviderAdded(provider); + } + } + } + + public void stop(BundleContext bc) throws Exception + { + // start listening for newly register or removed protocol providers + bc.removeServiceListener(this); + + ServiceReference[] protocolProviderRefs = null; + try + { + protocolProviderRefs = bc.getServiceReferences( + ProtocolProviderService.class.getName(), + null); + } + catch (InvalidSyntaxException ex) + { + // this shouldn't happen since we're providing no parameter string + // but let's log just in case. + logger.error( + "Error while retrieving service refs", ex); + return; + } + + // in case we found any + if (protocolProviderRefs != null) + { + for (int i = 0; i < protocolProviderRefs.length; i++) + { + ProtocolProviderService provider = (ProtocolProviderService) bc + .getService(protocolProviderRefs[i]); + + this.handleProviderRemoved(provider); + } + } + } + + /** + * Used to attach the Alerter plugin to existing or + * just registered protocol provider. Checks if the provider has implementation + * of OperationSetBasicInstantMessaging + * + * @param provider ProtocolProviderService + */ + private void handleProviderAdded(ProtocolProviderService provider) + { + logger.debug("Adding protocol provider " + provider.getProtocolName()); + + // check whether the provider has a basic im operation set + OperationSetBasicInstantMessaging opSetIm + = (OperationSetBasicInstantMessaging) provider + .getSupportedOperationSets().get( + OperationSetBasicInstantMessaging.class.getName()); + + if (opSetIm != null) + { + opSetIm.addMessageListener(this); + } + else + { + logger.trace("Service did not have a im op. set."); + } + + // check whether the provider has a sms operation set + OperationSetSmsMessaging opSetSms + = (OperationSetSmsMessaging) provider + .getSupportedOperationSets().get( + OperationSetSmsMessaging.class.getName()); + + if (opSetSms != null) + { + opSetSms.addMessageListener(this); + } + else + { + logger.trace("Service did not have a sms op. set."); + } + + OperationSetMultiUserChat opSetMultiUChat + = (OperationSetMultiUserChat) provider + .getSupportedOperationSets().get( + OperationSetMultiUserChat.class.getName()); + + if (opSetMultiUChat != null) + { + Iterator iter = + opSetMultiUChat.getCurrentlyJoinedChatRooms().iterator(); + + while(iter.hasNext()) + { + ChatRoom room = (ChatRoom)iter.next(); + room.addMessageListener(this); + } + + opSetMultiUChat.addPresenceListener(this); + } + else + { + logger.trace("Service did not have a multi im op. set."); + } + } + + /** + * Removes the specified provider from the list of currently known providers + * and ignores all the messages exchanged by it + * + * @param provider the ProtocolProviderService that has been unregistered. + */ + private void handleProviderRemoved(ProtocolProviderService provider) + { + OperationSetBasicInstantMessaging opSetIm + = (OperationSetBasicInstantMessaging) provider + .getSupportedOperationSets().get( + OperationSetBasicInstantMessaging.class.getName()); + + if (opSetIm != null) + { + opSetIm.removeMessageListener(this); + } + + OperationSetMultiUserChat opSetMultiUChat + = (OperationSetMultiUserChat) provider + .getSupportedOperationSets().get( + OperationSetMultiUserChat.class.getName()); + + if (opSetMultiUChat != null) + { + Iterator iter = + opSetMultiUChat.getCurrentlyJoinedChatRooms().iterator(); + + while(iter.hasNext()) + { + ChatRoom room = (ChatRoom)iter.next(); + room.removeMessageListener(this); + } + } + } + + /** + * Called to notify interested parties that a change in our presence in + * a chat room has occurred. Changes may include us being kicked, join, + * left. + * @param evt the LocalUserChatRoomPresenceChangeEvent instance + * containing the chat room and the type, and reason of the change + */ + public void localUserPresenceChanged(LocalUserChatRoomPresenceChangeEvent evt) + { + if(evt.getEventType() == + LocalUserChatRoomPresenceChangeEvent.LOCAL_USER_JOINED) + { + if (!evt.getChatRoom().isSystem()) + evt.getChatRoom().addMessageListener(this); + } + else + { + evt.getChatRoom().removeMessageListener(this); + } + } + + public void messageReceived(MessageReceivedEvent evt) + { + try + { + ExportedWindow win = + uiService.getExportedWindow(ExportedWindow.CHAT_WINDOW); + + if(win == null || win.getSource() == null || + !(win.getSource() instanceof JFrame)) + return; + + JFrame fr = (JFrame)win.getSource(); + + if(fr != null) + Alerter.newInstance().alert(fr); + } + catch (Exception ex) + { + logger.error("Cannot alert chat window!"); + } + } + + public void messageDelivered(MessageDeliveredEvent evt) + { + // do nothing + } + + public void messageDeliveryFailed(MessageDeliveryFailedEvent evt) + { + // do nothing + } + + public void messageReceived(ChatRoomMessageReceivedEvent evt) + { + try + { + ExportedWindow win = + uiService.getExportedWindow(ExportedWindow.CHAT_WINDOW); + + if(win == null || win.getSource() == null || + !(win.getSource() instanceof JFrame)) + return; + + JFrame fr = (JFrame)win.getSource(); + + if(fr != null) + Alerter.newInstance().alert(fr); + } + catch (Exception ex) + { + logger.error("Cannot alert chat window!"); + } + } + + public void messageDelivered(ChatRoomMessageDeliveredEvent evt) + { + // do nothing + } + + public void messageDeliveryFailed(ChatRoomMessageDeliveryFailedEvent evt) + { + // do nothing + } + + /** + * When new protocol provider is registered we check + * does it supports needed Op. Sets and if so add a listener to it + * + * @param serviceEvent ServiceEvent + */ + public void serviceChanged(ServiceEvent serviceEvent) + { + Object sService = + bundleContext.getService(serviceEvent.getServiceReference()); + + logger.trace("Received a service event for: " + + sService.getClass().getName()); + + // we don't care if the source service is not a protocol provider + if (! (sService instanceof ProtocolProviderService)) + { + return; + } + + logger.debug("Service is a protocol provider."); + if (serviceEvent.getType() == ServiceEvent.REGISTERED) + { + logger.debug("Handling registration of a new Protocol Provider."); + + this.handleProviderAdded((ProtocolProviderService)sService); + } + else if (serviceEvent.getType() == ServiceEvent.UNREGISTERING) + { + this.handleProviderRemoved( (ProtocolProviderService) sService); + } + } +} diff --git a/src/net/java/sip/communicator/plugin/contactinfo/chatalerter.manifest.mf b/src/net/java/sip/communicator/plugin/contactinfo/chatalerter.manifest.mf new file mode 100644 index 000000000..a98d4d107 --- /dev/null +++ b/src/net/java/sip/communicator/plugin/contactinfo/chatalerter.manifest.mf @@ -0,0 +1,12 @@ +Bundle-Activator: net.java.sip.communicator.plugin.chatalerter.ChatAlerterActivator +Bundle-Name: Chat Alerter +Bundle-Description: A plug-in that alerts for new messages by flashing the window in the taskbar. +Bundle-Vendor: sip-communicator.org +Bundle-Version: 0.0.1 +Import-Package: org.osgi.framework, + net.java.sip.communicator.util, + net.java.sip.communicator.service.gui, + net.java.sip.communicator.service.protocol, + net.java.sip.communicator.service.protocol.event, + com.apple.cocoa.application, + javax.swing \ No newline at end of file diff --git a/src/net/java/sip/communicator/service/gui/ExportedWindow.java b/src/net/java/sip/communicator/service/gui/ExportedWindow.java index 4e68a9f6b..2dcb34111 100644 --- a/src/net/java/sip/communicator/service/gui/ExportedWindow.java +++ b/src/net/java/sip/communicator/service/gui/ExportedWindow.java @@ -92,4 +92,10 @@ public interface ExportedWindow * Maximizes the window. */ public void maximize(); + + /** + * The source of the window + * @return the source of the window + */ + public Object getSource(); }