From dfb0c91c94d7e7ba0ef34bcb022f2779af20be9b Mon Sep 17 00:00:00 2001 From: Lyubomir Marinov Date: Tue, 13 Oct 2009 13:51:23 +0000 Subject: [PATCH] Commits the patch of Sebastien Vincent provided on the dev mailing list in an e-mail with the subject "[Patch] Warnings" which fixes multiple warnings about unnecessary casts, missing or incorrect javadocs. --- .../callhistory/CallHistoryServiceImpl.java | 35 +- .../MetaContactListServiceImpl.java | 63 +- .../communicator/impl/gui/main/MainFrame.java | 10 +- .../gui/main/call/AccountSelectorBox.java | 15 +- .../impl/gui/main/call/CallManager.java | 8 +- .../impl/gui/main/call/DialPanel.java | 11 +- .../impl/gui/main/call/HoldButton.java | 2 +- .../impl/gui/main/call/LocalVideoButton.java | 234 +- .../gui/main/call/OneToOneCallPeerPanel.java | 2 +- .../gui/main/call/ParentCallPeerPanel.java | 4 +- .../gui/main/call/ReceivedCallDialog.java | 2 +- .../impl/gui/main/call/SecurityPanel.java | 5 +- .../gui/main/call/TransferCallButton.java | 4 +- .../conference/ConferenceChatManager.java | 19 +- .../gui/main/chat/history/HistoryWindow.java | 9 +- .../gui/main/contactlist/ContactListPane.java | 10 +- .../ContactListTransferHandler.java | 2 +- .../gui/main/presence/AccountStatusPanel.java | 6 +- .../gui/main/presence/PresenceStatusMenu.java | 3 +- .../impl/gui/utils/ImageLoader.java | 3 +- .../impl/gui/utils/InviteDialog.java | 8 +- .../transform/zrtp/ZRTPTransformEngine.java | 4 +- .../msghistory/MessageHistoryServiceImpl.java | 12 +- .../impl/osdependent/jdic/StatusSubMenu.java | 8 +- .../protocol/SingleCallInProgressPolicy.java | 832 +++---- .../protocol/facebook/FacebookAdapter.java | 791 +++--- .../protocol/facebook/FacebookBuddyList.java | 575 +++-- .../FacebookIncomingMessagePoller.java | 10 +- .../facebook/FacebookOutgoingChatMessage.java | 1 - ...nSetBasicInstantMessagingFacebookImpl.java | 531 ++-- .../protocol/icq/AdHocChatRoomIcqImpl.java | 2 +- .../protocol/jabber/CallPeerJabberImpl.java | 8 +- .../OperationSetGeolocationJabberImpl.java | 5 +- .../OperationSetMultiUserChatJabberImpl.java | 2 +- .../impl/protocol/rss/UriHandlerRssImpl.java | 3 +- .../impl/protocol/ssh/ContactSSHImpl.java | 9 +- ...erationSetAdHocMultiUserChatYahooImpl.java | 1 - .../accountinfo/AccountDetailsPanel.java | 1591 ++++++------ .../plugin/autoaway/StatusUpdateThread.java | 386 ++- .../chatalerter/ChatAlerterActivator.java | 672 +++--- .../communicator/plugin/mailbox/Mailbox.java | 19 +- .../communicator/plugin/otr/OtrActivator.java | 8 +- .../whiteboard/WhiteboardActivator.java | 3 +- .../whiteboard/WhiteboardSessionManager.java | 7 +- .../contactlist/TestMetaContactGroup.java | 2 +- .../TestMetaContactListPersistence.java | 24 +- .../generic/PredictableTransformLayer.java | 2 +- .../TestProtocolProviderServiceIcqImpl.java | 3 +- ...tOperationSetBasicTelephonyJabberImpl.java | 2126 ++++++++--------- ...TestOperationSetBasicTelephonySipImpl.java | 12 +- 50 files changed, 4033 insertions(+), 4071 deletions(-) diff --git a/src/net/java/sip/communicator/impl/callhistory/CallHistoryServiceImpl.java b/src/net/java/sip/communicator/impl/callhistory/CallHistoryServiceImpl.java index 2d1140270..7ff11ad6a 100644 --- a/src/net/java/sip/communicator/impl/callhistory/CallHistoryServiceImpl.java +++ b/src/net/java/sip/communicator/impl/callhistory/CallHistoryServiceImpl.java @@ -106,10 +106,11 @@ public Collection findByStartDate(Date startDate) History history = this.getHistory(null, null); HistoryReader reader = history.getReader(); addHistorySearchProgressListeners(reader, 1); - QueryResultSet rs = reader.findByStartDate(startDate); + QueryResultSet rs + = reader.findByStartDate(startDate); while (rs.hasNext()) { - HistoryRecord hr = (HistoryRecord) rs.next(); + HistoryRecord hr = rs.next(); result.add(convertHistoryRecordToCallRecord(hr)); } removeHistorySearchProgressListeners(reader); @@ -154,10 +155,10 @@ public Collection findByEndDate(Date endDate) throws RuntimeExceptio History history = this.getHistory(null, null); HistoryReader reader = history.getReader(); addHistorySearchProgressListeners(reader, 1); - QueryResultSet rs = reader.findByEndDate(endDate); + QueryResultSet rs = reader.findByEndDate(endDate); while (rs.hasNext()) { - HistoryRecord hr = (HistoryRecord) rs.next(); + HistoryRecord hr = rs.next(); result.add(convertHistoryRecordToCallRecord(hr)); } removeHistorySearchProgressListeners(reader); @@ -204,10 +205,11 @@ public Collection findByPeriod(Date startDate, Date endDate) throws History history = this.getHistory(null, null); HistoryReader reader = history.getReader(); addHistorySearchProgressListeners(reader, 1); - QueryResultSet rs = reader.findByPeriod(startDate, endDate); + QueryResultSet rs + = reader.findByPeriod(startDate, endDate); while (rs.hasNext()) { - HistoryRecord hr = (HistoryRecord) rs.next(); + HistoryRecord hr = rs.next(); result.add(convertHistoryRecordToCallRecord(hr)); } removeHistorySearchProgressListeners(reader); @@ -250,10 +252,11 @@ public Collection findLast(int count) throws RuntimeException { // the default ones History history = this.getHistory(null, null); - QueryResultSet rs = history.getReader().findLast(count); + QueryResultSet rs + = history.getReader().findLast(count); while (rs.hasNext()) { - HistoryRecord hr = (HistoryRecord) rs.next(); + HistoryRecord hr = rs.next(); result.add(convertHistoryRecordToCallRecord(hr)); } } @@ -281,11 +284,11 @@ public Collection findByPeer(String address) History history = this.getHistory(null, null); HistoryReader reader = history.getReader(); addHistorySearchProgressListeners(reader, 1); - QueryResultSet rs = - reader.findByKeyword(address, "callParticipantIDs"); + QueryResultSet rs + = reader.findByKeyword(address, "callParticipantIDs"); while (rs.hasNext()) { - HistoryRecord hr = (HistoryRecord) rs.next(); + HistoryRecord hr = rs.next(); result.add(convertHistoryRecordToCallRecord(hr)); } removeHistorySearchProgressListeners(reader); @@ -679,9 +682,8 @@ private void handleProviderAdded(ProtocolProviderService provider) logger.debug("Adding protocol provider " + provider.getProtocolName()); // check whether the provider has a basic telephony operation set - OperationSetBasicTelephony opSetTelephony = - (OperationSetBasicTelephony) provider - .getOperationSet(OperationSetBasicTelephony.class); + OperationSetBasicTelephony opSetTelephony + = provider.getOperationSet(OperationSetBasicTelephony.class); if (opSetTelephony != null) { @@ -701,9 +703,8 @@ private void handleProviderAdded(ProtocolProviderService provider) */ private void handleProviderRemoved(ProtocolProviderService provider) { - OperationSetBasicTelephony opSetTelephony = - (OperationSetBasicTelephony) provider - .getOperationSet(OperationSetBasicTelephony.class); + OperationSetBasicTelephony opSetTelephony + = provider.getOperationSet(OperationSetBasicTelephony.class); if (opSetTelephony != null) { diff --git a/src/net/java/sip/communicator/impl/contactlist/MetaContactListServiceImpl.java b/src/net/java/sip/communicator/impl/contactlist/MetaContactListServiceImpl.java index 0fc35a91d..cf11d1f0a 100644 --- a/src/net/java/sip/communicator/impl/contactlist/MetaContactListServiceImpl.java +++ b/src/net/java/sip/communicator/impl/contactlist/MetaContactListServiceImpl.java @@ -210,9 +210,8 @@ public void stop(BundleContext bc) //stop listening to all currently installed providers for (ProtocolProviderService pp : currentlyInstalledProviders.values()) { - OperationSetPersistentPresence opSetPersPresence - = (OperationSetPersistentPresence)pp - .getOperationSet(OperationSetPersistentPresence.class); + OperationSetPersistentPresence opSetPersPresence = + pp.getOperationSet(OperationSetPersistentPresence.class); if(opSetPersPresence !=null) { @@ -226,8 +225,8 @@ public void stop(BundleContext bc) else { //check if a non persistent presence operation set exists. - OperationSetPresence opSetPresence = (OperationSetPresence)pp - .getOperationSet(OperationSetPresence.class); + OperationSetPresence opSetPresence = + pp.getOperationSet(OperationSetPresence.class); if(opSetPresence != null) { @@ -357,8 +356,7 @@ private void addNewContactToMetaContact( ProtocolProviderService provider, throws MetaContactListException { OperationSetPersistentPresence opSetPersPresence = - (OperationSetPersistentPresence) provider - .getOperationSet(OperationSetPersistentPresence.class); + provider.getOperationSet(OperationSetPersistentPresence.class); if (opSetPersPresence == null) { /** @todo handle non-persistent presence operation sets as well */ @@ -507,8 +505,7 @@ private ContactGroup resolveProtoPath(ProtocolProviderService protoProvider, } OperationSetPersistentPresence opSetPersPresence = - (OperationSetPersistentPresence) protoProvider - .getOperationSet(OperationSetPersistentPresence.class); + protoProvider.getOperationSet(OperationSetPersistentPresence.class); //if persistent presence is not supported - just bail //we should have verified this earlier anyway @@ -884,9 +881,10 @@ public void moveContact(Contact contact, currentParentMetaContact.removeProtoContact(contact); //get a persistent presence operation set - OperationSetPersistentPresence opSetPresence = - (OperationSetPersistentPresence) contact.getProtocolProvider() - .getOperationSet(OperationSetPersistentPresence.class); + OperationSetPersistentPresence opSetPresence + = contact + .getProtocolProvider() + .getOperationSet(OperationSetPersistentPresence.class); if (opSetPresence == null) { @@ -985,10 +983,11 @@ public void moveMetaContact(MetaContact metaContact, .getProtocolProvider(), (MetaContactGroupImpl) newMetaGroup); //get a persistent or non persistent presence operation set - OperationSetPersistentPresence opSetPresence = - (OperationSetPersistentPresence) protoContact - .getProtocolProvider().getOperationSet( - OperationSetPersistentPresence.class); + OperationSetPersistentPresence opSetPresence + = protoContact + .getProtocolProvider() + .getOperationSet( + OperationSetPersistentPresence.class); if (opSetPresence == null) { @@ -1034,9 +1033,10 @@ public void removeContact(Contact contact) throws MetaContactListException //updating and/or removing the corresponding meta contact would happen //once a confirmation event is received from the underlying protocol //provider - OperationSetPresence opSetPresence = - (OperationSetPresence) contact.getProtocolProvider() - .getOperationSet(OperationSetPresence.class); + OperationSetPresence opSetPresence + = contact + .getProtocolProvider() + .getOperationSet(OperationSetPresence.class); //in case the provider only has a persistent operation set: if (opSetPresence == null) @@ -1139,10 +1139,11 @@ public void removeMetaContactGroup( { ContactGroup protoGroup = protoGroups.next(); - OperationSetPersistentPresence opSetPersPresence = - (OperationSetPersistentPresence) protoGroup - .getProtocolProvider().getOperationSet( - OperationSetPersistentPresence.class); + OperationSetPersistentPresence opSetPersPresence + = protoGroup + .getProtocolProvider() + .getOperationSet( + OperationSetPersistentPresence.class); if (opSetPersPresence == null) { @@ -1614,8 +1615,7 @@ private synchronized void handleProviderAdded( // check whether the provider has a persistent presence op set OperationSetPersistentPresence opSetPersPresence = - (OperationSetPersistentPresence) provider - .getOperationSet(OperationSetPersistentPresence.class); + provider.getOperationSet(OperationSetPersistentPresence.class); this.currentlyInstalledProviders.put( provider.getAccountID().getAccountUniqueID(), @@ -1673,9 +1673,8 @@ private void handleProviderRemoved( remove(provider.getAccountID().getAccountUniqueID()); //get the root group for the provider so that we could remove it. - OperationSetPersistentPresence persPresOpSet - = (OperationSetPersistentPresence)provider - .getOperationSet(OperationSetPersistentPresence.class); + OperationSetPersistentPresence persPresOpSet = + provider.getOperationSet(OperationSetPersistentPresence.class); //ignore if persistent presence is not supported. if(persPresOpSet == null) @@ -2708,8 +2707,8 @@ ContactGroup loadStoredContactGroup(MetaContactGroupImpl containingMetaGroup, //get the presence op set ProtocolProviderService sourceProvider = currentlyInstalledProviders.get(accountID); - OperationSetPersistentPresence presenceOpSet = - (OperationSetPersistentPresence) sourceProvider + OperationSetPersistentPresence presenceOpSet + = sourceProvider .getOperationSet(OperationSetPersistentPresence.class); ContactGroup newProtoGroup = presenceOpSet.createUnresolvedContactGroup( @@ -2758,8 +2757,8 @@ void loadStoredMetaContact( //mc ProtocolProviderService sourceProvider = currentlyInstalledProviders.get(accountID); - OperationSetPersistentPresence presenceOpSet = - (OperationSetPersistentPresence) sourceProvider + OperationSetPersistentPresence presenceOpSet + = sourceProvider .getOperationSet(OperationSetPersistentPresence.class); for (MclStorageManager.StoredProtoContactDescriptor contactDescriptor diff --git a/src/net/java/sip/communicator/impl/gui/main/MainFrame.java b/src/net/java/sip/communicator/impl/gui/main/MainFrame.java index c4cd63397..1d41489fd 100755 --- a/src/net/java/sip/communicator/impl/gui/main/MainFrame.java +++ b/src/net/java/sip/communicator/impl/gui/main/MainFrame.java @@ -387,8 +387,8 @@ public void addProtocolSupportedOperationSets( } // Obtain the ad-hoc multi user chat operation set. - OperationSetAdHocMultiUserChat adHocMultiChatOpSet = - (OperationSetAdHocMultiUserChat) protocolProvider + OperationSetAdHocMultiUserChat adHocMultiChatOpSet + = protocolProvider .getOperationSet(OperationSetAdHocMultiUserChat.class); if (adHocMultiChatOpSet != null) @@ -403,13 +403,11 @@ public void addProtocolSupportedOperationSets( // Obtain file transfer operation set. OperationSetFileTransfer fileTransferOpSet - = (OperationSetFileTransfer) protocolProvider - .getOperationSet(OperationSetFileTransfer.class); + = protocolProvider.getOperationSet(OperationSetFileTransfer.class); if (fileTransferOpSet != null) { - fileTransferOpSet.addFileTransferListener( - getContactListPanel()); + fileTransferOpSet.addFileTransferListener(getContactListPanel()); } } diff --git a/src/net/java/sip/communicator/impl/gui/main/call/AccountSelectorBox.java b/src/net/java/sip/communicator/impl/gui/main/call/AccountSelectorBox.java index 1237e684e..fa5eeccf4 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/AccountSelectorBox.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/AccountSelectorBox.java @@ -82,18 +82,15 @@ public void addAccount(ProtocolProviderService pps) } else { - OperationSetPresence presence = - (OperationSetPresence) pps - .getOperationSet(OperationSetPresence.class); - - OperationSetPresence selectedPresence = - (OperationSetPresence) selectedProvider - .getOperationSet(OperationSetPresence.class); + OperationSetPresence presence + = pps.getOperationSet(OperationSetPresence.class); + OperationSetPresence selectedPresence + = selectedProvider.getOperationSet(OperationSetPresence.class); if (presence != null && selectedPresence != null - && (selectedPresence.getPresenceStatus().getStatus() < presence - .getPresenceStatus().getStatus())) + && (selectedPresence.getPresenceStatus().getStatus() + < presence.getPresenceStatus().getStatus())) { setSelected(pps); } diff --git a/src/net/java/sip/communicator/impl/gui/main/call/CallManager.java b/src/net/java/sip/communicator/impl/gui/main/call/CallManager.java index 1dbc205b3..9162cee08 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/CallManager.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/CallManager.java @@ -260,7 +260,7 @@ public CreateCallThread(ProtocolProviderService protocolProvider, public void run() { OperationSetBasicTelephony telephonyOpSet - = (OperationSetBasicTelephony) protocolProvider + = protocolProvider .getOperationSet(OperationSetBasicTelephony.class); /* @@ -326,8 +326,7 @@ public void run() { CallPeer peer = peers.next(); OperationSetBasicTelephony telephony = - (OperationSetBasicTelephony) pps - .getOperationSet(OperationSetBasicTelephony.class); + pps.getOperationSet(OperationSetBasicTelephony.class); try { @@ -363,8 +362,7 @@ public CreateConferenceCallThread( public void run() { OperationSetTelephonyConferencing confOpSet - = (OperationSetTelephonyConferencing) protocolProvider - .getOperationSet(OperationSetTelephonyConferencing.class); + = protocolProvider.getOperationSet(OperationSetTelephonyConferencing.class); /* * XXX If we are here and we just discover that diff --git a/src/net/java/sip/communicator/impl/gui/main/call/DialPanel.java b/src/net/java/sip/communicator/impl/gui/main/call/DialPanel.java index 5ae712c02..82f157f58 100755 --- a/src/net/java/sip/communicator/impl/gui/main/call/DialPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/DialPanel.java @@ -419,16 +419,13 @@ private void sendDtmfTone(DTMFTone dtmfTone) while (callPeers.hasNext()) { CallPeer peer = callPeers.next(); - - if (peer.getProtocolProvider() - .getOperationSet(OperationSetDTMF.class) != null) - { - OperationSetDTMF dtmfOpSet - = (OperationSetDTMF) peer.getProtocolProvider() + OperationSetDTMF dtmfOpSet + = peer + .getProtocolProvider() .getOperationSet(OperationSetDTMF.class); + if (dtmfOpSet != null) dtmfOpSet.sendDTMF(peer, dtmfTone); - } } } catch (NullPointerException e1) diff --git a/src/net/java/sip/communicator/impl/gui/main/call/HoldButton.java b/src/net/java/sip/communicator/impl/gui/main/call/HoldButton.java index e3c795562..c15577ecb 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/HoldButton.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/HoldButton.java @@ -122,7 +122,7 @@ public void actionPerformed(ActionEvent evt) if (call != null) { OperationSetBasicTelephony telephony = - (OperationSetBasicTelephony) call.getProtocolProvider() + call.getProtocolProvider() .getOperationSet(OperationSetBasicTelephony.class); Iterator peers = call.getCallPeers(); diff --git a/src/net/java/sip/communicator/impl/gui/main/call/LocalVideoButton.java b/src/net/java/sip/communicator/impl/gui/main/call/LocalVideoButton.java index 73482e199..afdaf5765 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/LocalVideoButton.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/LocalVideoButton.java @@ -1,117 +1,117 @@ -/* - * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.gui.main.call; - -import java.awt.event.*; - -import net.java.sip.communicator.impl.gui.*; -import net.java.sip.communicator.impl.gui.utils.*; -import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.util.*; -import net.java.sip.communicator.util.swing.*; - -/** - * @author Lubomir Marinov - */ -public class LocalVideoButton - extends SIPCommToggleButton -{ - private static final Logger logger - = Logger.getLogger(LocalVideoButton.class); - - private static final long serialVersionUID = 0L; - - /** - * Creates a LocalVideoButton by specifying the corresponding - * call. - * @param call the corresponding to this button call - */ - public LocalVideoButton(Call call) - { - setBgImage(ImageLoader.getImage(ImageLoader.CALL_SETTING_BUTTON_BG)); - setBgRolloverImage( - ImageLoader.getImage(ImageLoader.CALL_SETTING_BUTTON_BG)); - setIconImage(ImageLoader.getImage(ImageLoader.LOCAL_VIDEO_BUTTON)); - setPressedImage( - ImageLoader.getImage(ImageLoader.CALL_SETTING_BUTTON_PRESSED_BG)); - - setModel(new LocalVideoButtonModel(call)); - setToolTipText(GuiActivator.getResources().getI18NString( - "service.gui.LOCAL_VIDEO_BUTTON_TOOL_TIP")); - } - - private static class LocalVideoButtonModel - extends ToggleButtonModel - implements ActionListener, - Runnable - { - private final Call call; - - private Thread runner; - - public LocalVideoButtonModel(Call call) - { - this.call = call; - - addActionListener(this); - } - - public synchronized void actionPerformed(ActionEvent event) - { - if (runner == null) - { - runner = new Thread(this, LocalVideoButton.class.getName()); - runner.setDaemon(true); - - setEnabled(false); - runner.start(); - } - } - - public void run() - { - try - { - doRun(); - } - finally - { - synchronized (this) - { - if (Thread.currentThread().equals(runner)) - { - runner = null; - setEnabled(true); - } - } - } - } - - private void doRun() - { - OperationSetVideoTelephony telephony = (OperationSetVideoTelephony) - call.getProtocolProvider() - .getOperationSet(OperationSetVideoTelephony.class); - - if (telephony != null) - { - try - { - telephony.setLocalVideoAllowed( - call, - !telephony.isLocalVideoAllowed(call)); - } - catch (OperationFailedException ex) - { - logger.error( - "Failed to toggle the streaming of local video.", - ex); - } - } - } - } -} +/* + * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package net.java.sip.communicator.impl.gui.main.call; + +import java.awt.event.*; + +import net.java.sip.communicator.impl.gui.*; +import net.java.sip.communicator.impl.gui.utils.*; +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.swing.*; + +/** + * @author Lubomir Marinov + */ +public class LocalVideoButton + extends SIPCommToggleButton +{ + private static final Logger logger + = Logger.getLogger(LocalVideoButton.class); + + private static final long serialVersionUID = 0L; + + /** + * Creates a LocalVideoButton by specifying the corresponding + * call. + * @param call the corresponding to this button call + */ + public LocalVideoButton(Call call) + { + setBgImage(ImageLoader.getImage(ImageLoader.CALL_SETTING_BUTTON_BG)); + setBgRolloverImage( + ImageLoader.getImage(ImageLoader.CALL_SETTING_BUTTON_BG)); + setIconImage(ImageLoader.getImage(ImageLoader.LOCAL_VIDEO_BUTTON)); + setPressedImage( + ImageLoader.getImage(ImageLoader.CALL_SETTING_BUTTON_PRESSED_BG)); + + setModel(new LocalVideoButtonModel(call)); + setToolTipText(GuiActivator.getResources().getI18NString( + "service.gui.LOCAL_VIDEO_BUTTON_TOOL_TIP")); + } + + private static class LocalVideoButtonModel + extends ToggleButtonModel + implements ActionListener, + Runnable + { + private final Call call; + + private Thread runner; + + public LocalVideoButtonModel(Call call) + { + this.call = call; + + addActionListener(this); + } + + public synchronized void actionPerformed(ActionEvent event) + { + if (runner == null) + { + runner = new Thread(this, LocalVideoButton.class.getName()); + runner.setDaemon(true); + + setEnabled(false); + runner.start(); + } + } + + public void run() + { + try + { + doRun(); + } + finally + { + synchronized (this) + { + if (Thread.currentThread().equals(runner)) + { + runner = null; + setEnabled(true); + } + } + } + } + + private void doRun() + { + OperationSetVideoTelephony telephony = + call.getProtocolProvider() + .getOperationSet(OperationSetVideoTelephony.class); + + if (telephony != null) + { + try + { + telephony.setLocalVideoAllowed( + call, + !telephony.isLocalVideoAllowed(call)); + } + catch (OperationFailedException ex) + { + logger.error( + "Failed to toggle the streaming of local video.", + ex); + } + } + } + } +} diff --git a/src/net/java/sip/communicator/impl/gui/main/call/OneToOneCallPeerPanel.java b/src/net/java/sip/communicator/impl/gui/main/call/OneToOneCallPeerPanel.java index b2a95cfb6..00cc876fe 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/OneToOneCallPeerPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/OneToOneCallPeerPanel.java @@ -290,7 +290,7 @@ private OperationSetVideoTelephony addVideoListener() return null; final OperationSetVideoTelephony telephony = - (OperationSetVideoTelephony) call.getProtocolProvider() + call.getProtocolProvider() .getOperationSet(OperationSetVideoTelephony.class); if (telephony == null) return null; diff --git a/src/net/java/sip/communicator/impl/gui/main/call/ParentCallPeerPanel.java b/src/net/java/sip/communicator/impl/gui/main/call/ParentCallPeerPanel.java index dcf07bb2c..16b788d99 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/ParentCallPeerPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/ParentCallPeerPanel.java @@ -505,7 +505,7 @@ private void createSecurityPanel(CallPeerSecurityOnEvent event) if (callPeer != null) { OperationSetSecureTelephony secure - = (OperationSetSecureTelephony) callPeer + = callPeer .getProtocolProvider().getOperationSet( OperationSetSecureTelephony.class); @@ -548,7 +548,7 @@ protected Component createTransferCallButton() if (callPeer != null) { OperationSetAdvancedTelephony telephony = - (OperationSetAdvancedTelephony) callPeer.getProtocolProvider() + callPeer.getProtocolProvider() .getOperationSet(OperationSetAdvancedTelephony.class); if (telephony != null) diff --git a/src/net/java/sip/communicator/impl/gui/main/call/ReceivedCallDialog.java b/src/net/java/sip/communicator/impl/gui/main/call/ReceivedCallDialog.java index ae5093892..8686f2ced 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/ReceivedCallDialog.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/ReceivedCallDialog.java @@ -53,7 +53,7 @@ public ReceivedCallDialog(Call call) this.initComponents(); OperationSetBasicTelephony telephonyOpSet - = (OperationSetBasicTelephony) call.getProtocolProvider() + = call.getProtocolProvider() .getOperationSet(OperationSetBasicTelephony.class); telephonyOpSet.addCallListener(this); diff --git a/src/net/java/sip/communicator/impl/gui/main/call/SecurityPanel.java b/src/net/java/sip/communicator/impl/gui/main/call/SecurityPanel.java index d9bec879e..274d47a30 100755 --- a/src/net/java/sip/communicator/impl/gui/main/call/SecurityPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/SecurityPanel.java @@ -65,8 +65,9 @@ public void actionPerformed(ActionEvent e) if (call != null) { OperationSetSecureTelephony secure - = (OperationSetSecureTelephony) call - .getProtocolProvider().getOperationSet( + = call + .getProtocolProvider() + .getOperationSet( OperationSetSecureTelephony.class); if (secure != null) diff --git a/src/net/java/sip/communicator/impl/gui/main/call/TransferCallButton.java b/src/net/java/sip/communicator/impl/gui/main/call/TransferCallButton.java index a4036ec97..df811cd84 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/TransferCallButton.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/TransferCallButton.java @@ -89,7 +89,7 @@ private void actionPerformed(ActionListener listener, ActionEvent evt) if (call != null) { OperationSetAdvancedTelephony telephony = - (OperationSetAdvancedTelephony) call.getProtocolProvider() + call.getProtocolProvider() .getOperationSet(OperationSetAdvancedTelephony.class); if (telephony != null) @@ -222,7 +222,7 @@ private CallPeer findCallPeer(String address) { ProtocolProviderService service = (ProtocolProviderService) bundleContext.getService(serviceReference); - OperationSetBasicTelephony telephony = (OperationSetBasicTelephony) + OperationSetBasicTelephony telephony = service.getOperationSet(telephonyClass); if (telephony != null) diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatManager.java b/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatManager.java index a5d2755d7..f83fdcdda 100644 --- a/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatManager.java +++ b/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatManager.java @@ -650,8 +650,7 @@ public ChatRoomWrapper createChatRoom( ChatRoomWrapper chatRoomWrapper = null; OperationSetMultiUserChat groupChatOpSet - = (OperationSetMultiUserChat) protocolProvider - .getOperationSet(OperationSetMultiUserChat.class); + = protocolProvider.getOperationSet(OperationSetMultiUserChat.class); // If there's no group chat operation set we have nothing to do here. if (groupChatOpSet == null) @@ -661,10 +660,9 @@ public ChatRoomWrapper createChatRoom( try { Map members = new Hashtable(); - OperationSetPersistentPresence opSet = - (OperationSetPersistentPresence) - protocolProvider.getOperationSet( - OperationSetPersistentPresence.class); + OperationSetPersistentPresence opSet + = protocolProvider + .getOperationSet(OperationSetPersistentPresence.class); for(String contact : contacts) { @@ -733,7 +731,7 @@ public AdHocChatRoomWrapper createAdHocChatRoom( AdHocChatRoomWrapper chatRoomWrapper = null; OperationSetAdHocMultiUserChat groupChatOpSet - = (OperationSetAdHocMultiUserChat) protocolProvider + = protocolProvider .getOperationSet(OperationSetAdHocMultiUserChat.class); // If there's no group chat operation set we have nothing to do here. @@ -746,7 +744,6 @@ public AdHocChatRoomWrapper createAdHocChatRoom( { List members = new LinkedList(); OperationSetPersistentPresence opSet = - (OperationSetPersistentPresence) protocolProvider.getOperationSet( OperationSetPersistentPresence.class); @@ -1645,8 +1642,8 @@ private static class FindRoomTask public ChatRoom doInBackground() { OperationSetMultiUserChat groupChatOpSet - = (OperationSetMultiUserChat) chatRoomProvider - .getProtocolProvider().getOperationSet( + = chatRoomProvider + .getProtocolProvider().getOperationSet( OperationSetMultiUserChat.class); ChatRoom chatRoom = null; @@ -1687,7 +1684,7 @@ public List doInBackground() return null; OperationSetMultiUserChat groupChatOpSet - = (OperationSetMultiUserChat) protocolProvider + = protocolProvider .getOperationSet(OperationSetMultiUserChat.class); if (groupChatOpSet == null) diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/history/HistoryWindow.java b/src/net/java/sip/communicator/impl/gui/main/chat/history/HistoryWindow.java index 7688c13f6..b61b6c8b8 100644 --- a/src/net/java/sip/communicator/impl/gui/main/chat/history/HistoryWindow.java +++ b/src/net/java/sip/communicator/impl/gui/main/chat/history/HistoryWindow.java @@ -149,11 +149,10 @@ public HistoryWindow(Object historyContact) Contact protoContact = protoContacts.next(); OperationSetBasicInstantMessaging basicInstantMessaging - = (OperationSetBasicInstantMessaging) - protoContact - .getProtocolProvider() - .getOperationSet( - OperationSetBasicInstantMessaging.class); + = protoContact + .getProtocolProvider() + .getOperationSet( + OperationSetBasicInstantMessaging.class); if (basicInstantMessaging != null) { diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListPane.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListPane.java index cc7d1e3c1..2b82386ee 100755 --- a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListPane.java +++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListPane.java @@ -155,9 +155,8 @@ public void contactClicked(ContactListEvent evt) = defaultContact.getProtocolProvider(); OperationSetBasicInstantMessaging - defaultIM = (OperationSetBasicInstantMessaging) - defaultProvider.getOperationSet( - OperationSetBasicInstantMessaging.class); + defaultIM = defaultProvider.getOperationSet( + OperationSetBasicInstantMessaging.class); ProtocolProviderService protoContactProvider; OperationSetBasicInstantMessaging protoContactIM; @@ -177,9 +176,8 @@ public void contactClicked(ContactListEvent evt) protoContactProvider = contact.getProtocolProvider(); - protoContactIM = (OperationSetBasicInstantMessaging) - protoContactProvider.getOperationSet( - OperationSetBasicInstantMessaging.class); + protoContactIM = protoContactProvider.getOperationSet( + OperationSetBasicInstantMessaging.class); if(protoContactIM != null && protoContactIM.isOfflineMessagingSupported() diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTransferHandler.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTransferHandler.java index 84c033db7..e5141a31b 100644 --- a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTransferHandler.java +++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTransferHandler.java @@ -46,7 +46,7 @@ public ContactListTransferHandler(DefaultContactList contactList) * @param t the data to import * @return true if the data was inserted into the component; * false, otherwise - * @see TransferHandler#importData(JComponent. Transferable) + * @see TransferHandler#importData(JComponent, Transferable) */ @SuppressWarnings("unchecked") //taken care of public boolean importData(JComponent comp, Transferable t) diff --git a/src/net/java/sip/communicator/impl/gui/main/presence/AccountStatusPanel.java b/src/net/java/sip/communicator/impl/gui/main/presence/AccountStatusPanel.java index 57b8f079d..22af0c60a 100644 --- a/src/net/java/sip/communicator/impl/gui/main/presence/AccountStatusPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/presence/AccountStatusPanel.java @@ -162,10 +162,8 @@ public void registrationStateChanged(RegistrationStateChangeEvent evt) * to do anything useful can be prevented. */ final OperationSetServerStoredAccountInfo accountInfoOpSet - = (OperationSetServerStoredAccountInfo) - protocolProvider - .getOperationSet( - OperationSetServerStoredAccountInfo.class); + = protocolProvider.getOperationSet( + OperationSetServerStoredAccountInfo.class); if (accountInfoOpSet != null) diff --git a/src/net/java/sip/communicator/impl/gui/main/presence/PresenceStatusMenu.java b/src/net/java/sip/communicator/impl/gui/main/presence/PresenceStatusMenu.java index 2727a8d54..caeb9ca8f 100644 --- a/src/net/java/sip/communicator/impl/gui/main/presence/PresenceStatusMenu.java +++ b/src/net/java/sip/communicator/impl/gui/main/presence/PresenceStatusMenu.java @@ -68,8 +68,7 @@ public PresenceStatusMenu(ProtocolProviderService protocolProvider) this.protocolProvider = protocolProvider; this.presence - = (OperationSetPresence) protocolProvider - .getOperationSet(OperationSetPresence.class); + = protocolProvider.getOperationSet(OperationSetPresence.class); this.statusIterator = this.presence.getSupportedStatusSet(); diff --git a/src/net/java/sip/communicator/impl/gui/utils/ImageLoader.java b/src/net/java/sip/communicator/impl/gui/utils/ImageLoader.java index 22c82d551..b365b1f25 100644 --- a/src/net/java/sip/communicator/impl/gui/utils/ImageLoader.java +++ b/src/net/java/sip/communicator/impl/gui/utils/ImageLoader.java @@ -1341,8 +1341,7 @@ public static ImageIcon getAccountStatusImage(ProtocolProviderService pps) ImageIcon statusIcon; OperationSetPresence presence - = (OperationSetPresence) pps - .getOperationSet(OperationSetPresence.class); + = pps.getOperationSet(OperationSetPresence.class); Image statusImage; if (presence != null) diff --git a/src/net/java/sip/communicator/impl/gui/utils/InviteDialog.java b/src/net/java/sip/communicator/impl/gui/utils/InviteDialog.java index fdff799db..7f39a8a01 100644 --- a/src/net/java/sip/communicator/impl/gui/utils/InviteDialog.java +++ b/src/net/java/sip/communicator/impl/gui/utils/InviteDialog.java @@ -138,7 +138,7 @@ public void mouseClicked(MouseEvent e) if (e.getClickCount() > 1) { Object[] metaContacts - = (Object[]) selectedContactList.getSelectedValues(); + = selectedContactList.getSelectedValues(); moveContactsFromRightToLeft(metaContacts); } @@ -189,8 +189,7 @@ public void mouseClicked(MouseEvent e) { public void actionPerformed(ActionEvent e) { - Object[] metaContacts - = (Object[]) contactList.getSelectedValues(); + Object[] metaContacts = contactList.getSelectedValues(); if (metaContacts != null && metaContacts.length > 0) moveContactsFromLeftToRight(metaContacts); @@ -201,8 +200,7 @@ public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) { - Object[] metaContacts - = (Object[]) selectedContactList.getSelectedValues(); + Object[] metaContacts = selectedContactList.getSelectedValues(); if (metaContacts != null && metaContacts.length > 0) moveContactsFromRightToLeft(metaContacts); diff --git a/src/net/java/sip/communicator/impl/media/transform/zrtp/ZRTPTransformEngine.java b/src/net/java/sip/communicator/impl/media/transform/zrtp/ZRTPTransformEngine.java index 7237c45a4..0a6704aec 100644 --- a/src/net/java/sip/communicator/impl/media/transform/zrtp/ZRTPTransformEngine.java +++ b/src/net/java/sip/communicator/impl/media/transform/zrtp/ZRTPTransformEngine.java @@ -484,7 +484,7 @@ public void cleanup() * The data output stream calls this method to transform outgoing * packets. * - * @see PacketTransformer#transform(net.java.sip.communicator.impl.media.transform.RawPacket) + * @see PacketTransformer#transform(RawPacket) */ public RawPacket transform(RawPacket pkt) { @@ -521,7 +521,7 @@ public RawPacket transform(RawPacket pkt) * The input data stream calls this method to transform * incoming packets. * - * @see PacketTransformer#reverseTransform(net.java.sip.communicator.impl.media.transform.RawPacket) + * @see PacketTransformer#reverseTransform(RawPacket) */ public RawPacket reverseTransform(RawPacket pkt) { diff --git a/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java b/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java index 11ed5998a..83ed9717f 100644 --- a/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java +++ b/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java @@ -1064,8 +1064,7 @@ private void handleProviderAdded(ProtocolProviderService provider) // check whether the provider has a basic im operation set OperationSetBasicInstantMessaging opSetIm = - (OperationSetBasicInstantMessaging) provider - .getOperationSet(OperationSetBasicInstantMessaging.class); + provider.getOperationSet(OperationSetBasicInstantMessaging.class); if (opSetIm != null) { @@ -1077,8 +1076,7 @@ private void handleProviderAdded(ProtocolProviderService provider) } OperationSetMultiUserChat opSetMultiUChat = - (OperationSetMultiUserChat) provider - .getOperationSet(OperationSetMultiUserChat.class); + provider.getOperationSet(OperationSetMultiUserChat.class); if (opSetMultiUChat != null) { @@ -1108,8 +1106,7 @@ private void handleProviderAdded(ProtocolProviderService provider) private void handleProviderRemoved(ProtocolProviderService provider) { OperationSetBasicInstantMessaging opSetIm = - (OperationSetBasicInstantMessaging) provider - .getOperationSet(OperationSetBasicInstantMessaging.class); + provider.getOperationSet(OperationSetBasicInstantMessaging.class); if (opSetIm != null) { @@ -1117,8 +1114,7 @@ private void handleProviderRemoved(ProtocolProviderService provider) } OperationSetMultiUserChat opSetMultiUChat = - (OperationSetMultiUserChat) provider - .getOperationSet(OperationSetMultiUserChat.class); + provider.getOperationSet(OperationSetMultiUserChat.class); if (opSetMultiUChat != null) { diff --git a/src/net/java/sip/communicator/impl/osdependent/jdic/StatusSubMenu.java b/src/net/java/sip/communicator/impl/osdependent/jdic/StatusSubMenu.java index 8ef016a88..0f0feb9a0 100644 --- a/src/net/java/sip/communicator/impl/osdependent/jdic/StatusSubMenu.java +++ b/src/net/java/sip/communicator/impl/osdependent/jdic/StatusSubMenu.java @@ -93,8 +93,8 @@ public Object getMenu() private void addAccount(ProtocolProviderService protocolProvider) { OperationSetPresence presence - = (OperationSetPresence) - protocolProvider.getOperationSet(OperationSetPresence.class); + = protocolProvider.getOperationSet(OperationSetPresence.class); + boolean swing = (menu instanceof JComponent); if (presence == null) @@ -157,8 +157,8 @@ private void removeAccount(ProtocolProviderService protocolProvider) * addAccount(ProtocolProviderService). */ OperationSetPresence presence - = (OperationSetPresence) - protocolProvider.getOperationSet(OperationSetPresence.class); + = protocolProvider.getOperationSet(OperationSetPresence.class); + if (presence != null) presence.removeProviderPresenceStatusListener(this); else diff --git a/src/net/java/sip/communicator/impl/protocol/SingleCallInProgressPolicy.java b/src/net/java/sip/communicator/impl/protocol/SingleCallInProgressPolicy.java index 6281050b8..eabce4f0b 100644 --- a/src/net/java/sip/communicator/impl/protocol/SingleCallInProgressPolicy.java +++ b/src/net/java/sip/communicator/impl/protocol/SingleCallInProgressPolicy.java @@ -1,416 +1,416 @@ -/* - * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.protocol; - -import java.util.*; - -import org.osgi.framework.*; - -import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.protocol.event.*; -import net.java.sip.communicator.util.*; - -/** - * Imposes the policy to have one call in progress i.e. to put existing calls on - * hold when a new call enters in progress. - * - * @author Lubomir Marinov - */ -public class SingleCallInProgressPolicy -{ - - /** - * The name of the configuration property which specifies whether - * SingleCallInProgressPolicy is enabled i.e. whether it should - * put existing calls on hold when a new call enters in progress. - */ - private static final String PNAME_SINGLE_CALL_IN_PROGRESS_POLICY_ENABLED - = "net.java.sip.communicator.impl.protocol.SingleCallInProgressPolicy.enabled"; - - /** - * Implements the listeners interfaces used by this policy. - */ - private class SingleCallInProgressPolicyListener - implements CallChangeListener, - CallListener, - ServiceListener - { - /** - * Stops tracking the state of a specific Call and no - * longer tries to put it on hold when it ends. - * - * @see CallListener#callEnded(CallEvent) - */ - public void callEnded(CallEvent callEvent) - { - SingleCallInProgressPolicy.this.handleCallEvent( - CallEvent.CALL_ENDED, callEvent); - } - - /** - * Does nothing because adding CallPeers to - * Calls isn't related to the policy to put existing calls - * on hold when a new call becomes in-progress and just implements - * CallChangeListener. - * - * @see CallChangeListener#callPeerAdded(CallPeerEvent) - */ - public void callPeerAdded( CallPeerEvent callPeerEvent) - { - - /* - * Not of interest, just implementing CallChangeListener in which - * only #callStateChanged(CallChangeEvent) is of interest. - */ - } - - /** - * Does nothing because removing CallPeers to - * Calls isn't related to the policy to put existing calls - * on hold when a new call becomes in-progress and just implements - * CallChangeListener. - * - * @see CallChangeListener#callPeerRemoved(CallPeerEvent) - */ - public void callPeerRemoved( CallPeerEvent callPeerEvent) - { - - /* - * Not of interest, just implementing CallChangeListener in which - * only #callStateChanged(CallChangeEvent) is of interest. - */ - } - - /** - * Upon a Call changing its state to - * CallState.CALL_IN_PROGRESS, puts the other existing - * Calls on hold. - * - * @param callChangeEvent the CallChangeEvent that we are to - * deliver. - * - * @see CallChangeListener#callStateChanged(CallChangeEvent) - */ - public void callStateChanged(CallChangeEvent callChangeEvent) - { - SingleCallInProgressPolicy.this.callStateChanged(callChangeEvent); - } - - /** - * Remembers an incoming Call so that it can put the other - * existing Calls on hold when it changes its state to - * CallState.CALL_IN_PROGRESS. - * - * @see CallListener#incomingCallReceived(CallEvent) - */ - public void incomingCallReceived(CallEvent callEvent) - { - SingleCallInProgressPolicy.this.handleCallEvent( - CallEvent.CALL_RECEIVED, callEvent); - } - - /** - * Remembers an outgoing Call so that it can put the other - * existing Calls on hold when it changes its state to - * CallState.CALL_IN_PROGRESS. - * - * @see CallListener#outgoingCallCreated(CallEvent) - */ - public void outgoingCallCreated(CallEvent callEvent) - { - SingleCallInProgressPolicy.this.handleCallEvent( - CallEvent.CALL_INITIATED, callEvent); - } - - /** - * Starts/stops tracking the new Calls originating from a - * specific ProtocolProviderService when it - * registers/unregisters in order to take them into account when putting - * existing calls on hold upon a new call entering its in-progress - * state. - * - * @param serviceEvent - * the ServiceEvent event describing a change in - * the state of a service registration which may be a - * ProtocolProviderService supporting - * OperationSetBasicTelephony and thus being - * able to create new Calls - */ - public void serviceChanged(ServiceEvent serviceEvent) - { - SingleCallInProgressPolicy.this.serviceChanged(serviceEvent); - } - } - - /** - * Our class logger - */ - private static final Logger logger = - Logger.getLogger(SingleCallInProgressPolicy.class); - - /** - * The BundleContext to the Calls of which this policy applies. - */ - private final BundleContext bundleContext; - - /** - * The Calls this policy manages i.e. put on hold when one of - * them enters in progress. - */ - private final List calls = new ArrayList(); - - /** - * The listener utilized by this policy to discover new Call - * and track their in-progress state. - */ - private final SingleCallInProgressPolicyListener listener = - new SingleCallInProgressPolicyListener(); - - /** - * Initializes a new SingleCallInProgressPolicy instance which - * will apply to the Calls of a specific - * BundleContext. - * - * @param bundleContext - * the BundleContext to the - * Calls of which the new policy should apply - */ - public SingleCallInProgressPolicy(BundleContext bundleContext) - { - this.bundleContext = bundleContext; - - this.bundleContext.addServiceListener(listener); - } - - /** - * Registers a specific Call with this policy in order to have - * the rules of the latter apply to the former. - * - * @param call - * the Call to register with this policy in order to - * have the rules of the latter apply to the former - */ - private void addCallListener(Call call) - { - synchronized (calls) - { - if (!calls.contains(call)) - { - CallState callState = call.getCallState(); - - if ((callState != null) - && !callState.equals(CallState.CALL_ENDED)) - { - calls.add(call); - } - } - } - - call.addCallChangeListener(listener); - } - - /** - * Registers a specific OperationSetBasicTelephony with this - * policy in order to have the rules of the latter apply to the - * Calls created by the former. - * - * @param telephony - * the OperationSetBasicTelephony to register with - * this policy in order to have the rules of the latter apply to - * the Calls created by the former - */ - private void addOperationSetBasicTelephonyListener( - OperationSetBasicTelephony telephony) - { - telephony.addCallListener(listener); - } - - /** - * Handles changes in the state of a Call this policy applies - * to in order to detect when new calls become in-progress and when the - * other calls should be put on hold. - * - * @param callChangeEvent - * a CallChangeEvent value which describes the - * Call and the change in its state - */ - private void callStateChanged(CallChangeEvent callChangeEvent) - { - Call call = callChangeEvent.getSourceCall(); - - if (CallState.CALL_INITIALIZATION.equals(callChangeEvent.getOldValue()) - && CallState.CALL_IN_PROGRESS.equals(call.getCallState()) - && ProtocolProviderActivator - .getConfigurationService() - .getBoolean( - PNAME_SINGLE_CALL_IN_PROGRESS_POLICY_ENABLED, - true)) - { - synchronized (calls) - { - for (Call otherCall : calls) - if (!call.equals(otherCall) - && CallState.CALL_IN_PROGRESS - .equals(otherCall.getCallState())) - putOnHold(otherCall); - } - } - } - - /** - * Performs end-of-life cleanup associated with this instance e.g. removes - * added listeners. - */ - public void dispose() - { - bundleContext.removeServiceListener(listener); - } - - /** - * Handles the start and end of the Calls this policy applies - * to in order to have them or stop having them put the other existing calls - * on hold when the former change their states to - * CallState.CALL_IN_PROGRESS. - * - * @param type - * one of {@link CallEvent#CALL_ENDED}, - * {@link CallEvent#CALL_INITIATED} and - * {@link CallEvent#CALL_RECEIVED} which described the type of - * the event to be handled - * @param callEvent - * a CallEvent value which describes the change and - * the Call associated with it - */ - private void handleCallEvent(int type, CallEvent callEvent) - { - Call call = callEvent.getSourceCall(); - - switch (type) - { - case CallEvent.CALL_ENDED: - removeCallListener(call); - break; - - case CallEvent.CALL_INITIATED: - case CallEvent.CALL_RECEIVED: - addCallListener(call); - break; - } - } - - /** - * Puts the CallPeers of a specific Call on - * hold. - * - * @param call - * the Call the CallPeers of - * which are to be put on hold - */ - private void putOnHold(Call call) - { - OperationSetBasicTelephony telephony = - (OperationSetBasicTelephony) call.getProtocolProvider() - .getOperationSet(OperationSetBasicTelephony.class); - - if (telephony != null) - { - for (Iterator peerIter = - call.getCallPeers(); peerIter.hasNext();) - { - CallPeer peer = peerIter.next(); - CallPeerState peerState = peer.getState(); - - if (!CallPeerState.DISCONNECTED.equals(peerState) - && !CallPeerState.FAILED.equals(peerState) - && !CallPeerState.isOnHold(peerState)) - { - try - { - telephony.putOnHold(peer); - } - catch (OperationFailedException ex) - { - logger.error("Failed to put " + peer - + " on hold.", ex); - } - } - } - } - } - - /** - * Unregisters a specific Call from this policy in order to - * have the rules of the latter no longer applied to the former. - * - * @param call - * the Call to unregister from this policy in order - * to have the rules of the latter no longer apply to the former - */ - private void removeCallListener(Call call) - { - call.removeCallChangeListener(listener); - - synchronized (calls) - { - calls.remove(call); - } - } - - /** - * Unregisters a specific OperationSetBasicTelephony from this - * policy in order to have the rules of the latter no longer apply to the - * Calls created by the former. - * - * @param telephony - * the OperationSetBasicTelephony to unregister from - * this policy in order to have the rules of the latter apply to - * the Calls created by the former - */ - private void removeOperationSetBasicTelephonyListener( - OperationSetBasicTelephony telephony) - { - telephony.removeCallListener(listener); - } - - /** - * Handles the registering and unregistering of - * OperationSetBasicTelephony instances in order to apply or - * unapply the rules of this policy to the Calls originating - * from them. - * - * @param serviceEvent - * a ServiceEvent value which described a change in - * a OSGi service and which is to be examined for the registering - * or unregistering of a ProtocolProviderService and - * thus a OperationSetBasicTelephony - */ - private void serviceChanged(ServiceEvent serviceEvent) - { - Object service = - bundleContext.getService(serviceEvent.getServiceReference()); - - if (service instanceof ProtocolProviderService) - { - OperationSetBasicTelephony telephony = - (OperationSetBasicTelephony) ((ProtocolProviderService) service) - .getOperationSet(OperationSetBasicTelephony.class); - - if (telephony != null) - { - switch (serviceEvent.getType()) - { - case ServiceEvent.REGISTERED: - addOperationSetBasicTelephonyListener(telephony); - break; - case ServiceEvent.UNREGISTERING: - removeOperationSetBasicTelephonyListener(telephony); - break; - } - } - } - } -} +/* + * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package net.java.sip.communicator.impl.protocol; + +import java.util.*; + +import org.osgi.framework.*; + +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.service.protocol.event.*; +import net.java.sip.communicator.util.*; + +/** + * Imposes the policy to have one call in progress i.e. to put existing calls on + * hold when a new call enters in progress. + * + * @author Lubomir Marinov + */ +public class SingleCallInProgressPolicy +{ + + /** + * The name of the configuration property which specifies whether + * SingleCallInProgressPolicy is enabled i.e. whether it should + * put existing calls on hold when a new call enters in progress. + */ + private static final String PNAME_SINGLE_CALL_IN_PROGRESS_POLICY_ENABLED + = "net.java.sip.communicator.impl.protocol.SingleCallInProgressPolicy.enabled"; + + /** + * Implements the listeners interfaces used by this policy. + */ + private class SingleCallInProgressPolicyListener + implements CallChangeListener, + CallListener, + ServiceListener + { + /** + * Stops tracking the state of a specific Call and no + * longer tries to put it on hold when it ends. + * + * @see CallListener#callEnded(CallEvent) + */ + public void callEnded(CallEvent callEvent) + { + SingleCallInProgressPolicy.this.handleCallEvent( + CallEvent.CALL_ENDED, callEvent); + } + + /** + * Does nothing because adding CallPeers to + * Calls isn't related to the policy to put existing calls + * on hold when a new call becomes in-progress and just implements + * CallChangeListener. + * + * @see CallChangeListener#callPeerAdded(CallPeerEvent) + */ + public void callPeerAdded( CallPeerEvent callPeerEvent) + { + + /* + * Not of interest, just implementing CallChangeListener in which + * only #callStateChanged(CallChangeEvent) is of interest. + */ + } + + /** + * Does nothing because removing CallPeers to + * Calls isn't related to the policy to put existing calls + * on hold when a new call becomes in-progress and just implements + * CallChangeListener. + * + * @see CallChangeListener#callPeerRemoved(CallPeerEvent) + */ + public void callPeerRemoved( CallPeerEvent callPeerEvent) + { + + /* + * Not of interest, just implementing CallChangeListener in which + * only #callStateChanged(CallChangeEvent) is of interest. + */ + } + + /** + * Upon a Call changing its state to + * CallState.CALL_IN_PROGRESS, puts the other existing + * Calls on hold. + * + * @param callChangeEvent the CallChangeEvent that we are to + * deliver. + * + * @see CallChangeListener#callStateChanged(CallChangeEvent) + */ + public void callStateChanged(CallChangeEvent callChangeEvent) + { + SingleCallInProgressPolicy.this.callStateChanged(callChangeEvent); + } + + /** + * Remembers an incoming Call so that it can put the other + * existing Calls on hold when it changes its state to + * CallState.CALL_IN_PROGRESS. + * + * @see CallListener#incomingCallReceived(CallEvent) + */ + public void incomingCallReceived(CallEvent callEvent) + { + SingleCallInProgressPolicy.this.handleCallEvent( + CallEvent.CALL_RECEIVED, callEvent); + } + + /** + * Remembers an outgoing Call so that it can put the other + * existing Calls on hold when it changes its state to + * CallState.CALL_IN_PROGRESS. + * + * @see CallListener#outgoingCallCreated(CallEvent) + */ + public void outgoingCallCreated(CallEvent callEvent) + { + SingleCallInProgressPolicy.this.handleCallEvent( + CallEvent.CALL_INITIATED, callEvent); + } + + /** + * Starts/stops tracking the new Calls originating from a + * specific ProtocolProviderService when it + * registers/unregisters in order to take them into account when putting + * existing calls on hold upon a new call entering its in-progress + * state. + * + * @param serviceEvent + * the ServiceEvent event describing a change in + * the state of a service registration which may be a + * ProtocolProviderService supporting + * OperationSetBasicTelephony and thus being + * able to create new Calls + */ + public void serviceChanged(ServiceEvent serviceEvent) + { + SingleCallInProgressPolicy.this.serviceChanged(serviceEvent); + } + } + + /** + * Our class logger + */ + private static final Logger logger = + Logger.getLogger(SingleCallInProgressPolicy.class); + + /** + * The BundleContext to the Calls of which this policy applies. + */ + private final BundleContext bundleContext; + + /** + * The Calls this policy manages i.e. put on hold when one of + * them enters in progress. + */ + private final List calls = new ArrayList(); + + /** + * The listener utilized by this policy to discover new Call + * and track their in-progress state. + */ + private final SingleCallInProgressPolicyListener listener = + new SingleCallInProgressPolicyListener(); + + /** + * Initializes a new SingleCallInProgressPolicy instance which + * will apply to the Calls of a specific + * BundleContext. + * + * @param bundleContext + * the BundleContext to the + * Calls of which the new policy should apply + */ + public SingleCallInProgressPolicy(BundleContext bundleContext) + { + this.bundleContext = bundleContext; + + this.bundleContext.addServiceListener(listener); + } + + /** + * Registers a specific Call with this policy in order to have + * the rules of the latter apply to the former. + * + * @param call + * the Call to register with this policy in order to + * have the rules of the latter apply to the former + */ + private void addCallListener(Call call) + { + synchronized (calls) + { + if (!calls.contains(call)) + { + CallState callState = call.getCallState(); + + if ((callState != null) + && !callState.equals(CallState.CALL_ENDED)) + { + calls.add(call); + } + } + } + + call.addCallChangeListener(listener); + } + + /** + * Registers a specific OperationSetBasicTelephony with this + * policy in order to have the rules of the latter apply to the + * Calls created by the former. + * + * @param telephony + * the OperationSetBasicTelephony to register with + * this policy in order to have the rules of the latter apply to + * the Calls created by the former + */ + private void addOperationSetBasicTelephonyListener( + OperationSetBasicTelephony telephony) + { + telephony.addCallListener(listener); + } + + /** + * Handles changes in the state of a Call this policy applies + * to in order to detect when new calls become in-progress and when the + * other calls should be put on hold. + * + * @param callChangeEvent + * a CallChangeEvent value which describes the + * Call and the change in its state + */ + private void callStateChanged(CallChangeEvent callChangeEvent) + { + Call call = callChangeEvent.getSourceCall(); + + if (CallState.CALL_INITIALIZATION.equals(callChangeEvent.getOldValue()) + && CallState.CALL_IN_PROGRESS.equals(call.getCallState()) + && ProtocolProviderActivator + .getConfigurationService() + .getBoolean( + PNAME_SINGLE_CALL_IN_PROGRESS_POLICY_ENABLED, + true)) + { + synchronized (calls) + { + for (Call otherCall : calls) + if (!call.equals(otherCall) + && CallState.CALL_IN_PROGRESS + .equals(otherCall.getCallState())) + putOnHold(otherCall); + } + } + } + + /** + * Performs end-of-life cleanup associated with this instance e.g. removes + * added listeners. + */ + public void dispose() + { + bundleContext.removeServiceListener(listener); + } + + /** + * Handles the start and end of the Calls this policy applies + * to in order to have them or stop having them put the other existing calls + * on hold when the former change their states to + * CallState.CALL_IN_PROGRESS. + * + * @param type + * one of {@link CallEvent#CALL_ENDED}, + * {@link CallEvent#CALL_INITIATED} and + * {@link CallEvent#CALL_RECEIVED} which described the type of + * the event to be handled + * @param callEvent + * a CallEvent value which describes the change and + * the Call associated with it + */ + private void handleCallEvent(int type, CallEvent callEvent) + { + Call call = callEvent.getSourceCall(); + + switch (type) + { + case CallEvent.CALL_ENDED: + removeCallListener(call); + break; + + case CallEvent.CALL_INITIATED: + case CallEvent.CALL_RECEIVED: + addCallListener(call); + break; + } + } + + /** + * Puts the CallPeers of a specific Call on + * hold. + * + * @param call + * the Call the CallPeers of + * which are to be put on hold + */ + private void putOnHold(Call call) + { + OperationSetBasicTelephony telephony = + call.getProtocolProvider() + .getOperationSet(OperationSetBasicTelephony.class); + + if (telephony != null) + { + for (Iterator peerIter = + call.getCallPeers(); peerIter.hasNext();) + { + CallPeer peer = peerIter.next(); + CallPeerState peerState = peer.getState(); + + if (!CallPeerState.DISCONNECTED.equals(peerState) + && !CallPeerState.FAILED.equals(peerState) + && !CallPeerState.isOnHold(peerState)) + { + try + { + telephony.putOnHold(peer); + } + catch (OperationFailedException ex) + { + logger.error("Failed to put " + peer + + " on hold.", ex); + } + } + } + } + } + + /** + * Unregisters a specific Call from this policy in order to + * have the rules of the latter no longer applied to the former. + * + * @param call + * the Call to unregister from this policy in order + * to have the rules of the latter no longer apply to the former + */ + private void removeCallListener(Call call) + { + call.removeCallChangeListener(listener); + + synchronized (calls) + { + calls.remove(call); + } + } + + /** + * Unregisters a specific OperationSetBasicTelephony from this + * policy in order to have the rules of the latter no longer apply to the + * Calls created by the former. + * + * @param telephony + * the OperationSetBasicTelephony to unregister from + * this policy in order to have the rules of the latter apply to + * the Calls created by the former + */ + private void removeOperationSetBasicTelephonyListener( + OperationSetBasicTelephony telephony) + { + telephony.removeCallListener(listener); + } + + /** + * Handles the registering and unregistering of + * OperationSetBasicTelephony instances in order to apply or + * unapply the rules of this policy to the Calls originating + * from them. + * + * @param serviceEvent + * a ServiceEvent value which described a change in + * a OSGi service and which is to be examined for the registering + * or unregistering of a ProtocolProviderService and + * thus a OperationSetBasicTelephony + */ + private void serviceChanged(ServiceEvent serviceEvent) + { + Object service = + bundleContext.getService(serviceEvent.getServiceReference()); + + if (service instanceof ProtocolProviderService) + { + OperationSetBasicTelephony telephony = + ((ProtocolProviderService) service) + .getOperationSet(OperationSetBasicTelephony.class); + + if (telephony != null) + { + switch (serviceEvent.getType()) + { + case ServiceEvent.REGISTERED: + addOperationSetBasicTelephonyListener(telephony); + break; + case ServiceEvent.UNREGISTERING: + removeOperationSetBasicTelephonyListener(telephony); + break; + } + } + } + } +} diff --git a/src/net/java/sip/communicator/impl/protocol/facebook/FacebookAdapter.java b/src/net/java/sip/communicator/impl/protocol/facebook/FacebookAdapter.java index 1403391b1..c08384b71 100644 --- a/src/net/java/sip/communicator/impl/protocol/facebook/FacebookAdapter.java +++ b/src/net/java/sip/communicator/impl/protocol/facebook/FacebookAdapter.java @@ -1,396 +1,395 @@ -/* - * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.protocol.facebook; - -import java.io.*; -import java.util.*; - -import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.protocol.event.*; -import net.java.sip.communicator.util.*; - -import org.apache.http.*; -import org.json.*; - -/** - * Adapter for the Facebook protocol. This class works as a bridge between the - * Facebook specific classes and the sip communication interfaces. It manages - * the lifecycle of the classes responsible of accessing Facebook servers and - * also manage the necessary {@link Thread threads} used to update the state - * with the latest server changes. - * - * @author Dai Zhiwei - * @author Lubomir Marinov - * @author Edgar Poce - */ -public class FacebookAdapter - implements FacebookSessionListener -{ - private static Logger logger = Logger.getLogger(FacebookAdapter.class); - - private final OperationSetBasicInstantMessagingFacebookImpl - basicInstantMessaging; - - /** - * Parent service provider - */ - private final ProtocolProviderServiceFacebookImpl parentProvider; - - private final OperationSetPersistentPresenceFacebookImpl persistentPresence; - - /** - * The Facebook session - */ - private FacebookSession session; - - private final OperationSetTypingNotificationsFacebookImpl - typingNotifications; - - /** - * Cache of typing notifications - */ - private final Map typingNotificationRecord - = new HashMap(); - - /** - * Adapter for each Facebook Chat account. - * - * @param parentProvider the parent service provider - * @param persistentPresence - * @param basicInstantMessaging - * @param typingNotifications - */ - public FacebookAdapter( - ProtocolProviderServiceFacebookImpl parentProvider, - OperationSetPersistentPresenceFacebookImpl persistentPresence, - OperationSetBasicInstantMessagingFacebookImpl basicInstantMessaging, - OperationSetTypingNotificationsFacebookImpl typingNotifications) - { - this.parentProvider = parentProvider; - this.persistentPresence = persistentPresence; - this.basicInstantMessaging = basicInstantMessaging; - this.typingNotifications = typingNotifications; - } - - /** - * Get the facebook id of this account - * - * @return the facebook id of this account - */ - public String getUID() - { - return this.session.getUid(); - } - - /** - * Get the parent service provider - * - * @return parent service provider - */ - public ProtocolProviderServiceFacebookImpl getParentProvider() - { - return parentProvider; - } - - /** - * Initializes the {@link FacebookSession},
- * Initializes the {@link Thread}s to update the buddy list and to poll - * messages - * - * @param email - * @param password - * @return true if the user is logged in - * @throws IOException - * @throws BrokenFacebookProtocolException - */ - public synchronized boolean initialize( - final String email, - final String password) - throws OperationFailedException - { - if (this.session != null && this.session.isLoggedIn()) - return true; - - logger.info("initializing facebook adapter. account"); - try - { - this.session = new FacebookSession(); - boolean loggedIn = session.login(email, password); - if (loggedIn) - session.addListener(this); - return loggedIn; - } - catch (Exception e) - { - throw - new OperationFailedException( - "unable to initialize adapter", - FacebookErrorException.kError_Login_GenericError, - e); - } - } - - /** - * Post typing notification to the given contact. - * - * @param notifiedContact - * the contact we want to notify - * @param typingState - * our current typing state(SC) - * @throws HttpException - * the http exception - * @throws IOException - * IO exception - * @throws JSONException - * JSON parsing exception - * @throws Exception - * the general exception - */ - public void postTypingNotification(Contact notifiedContact, int typingState) - throws HttpException, - IOException, - JSONException, - Exception - { - TypingNotificationRecord record - = typingNotificationRecord.get(notifiedContact.getAddress()); - if (record == null) - { - record = new TypingNotificationRecord(-1l, -1); - synchronized (typingNotificationRecord) - { - typingNotificationRecord - .put(notifiedContact.getAddress(), record); - } - } - - if (record.getTime() < System.currentTimeMillis() - 1000) - { - FacebookOutgoingTypingNotification msg - = new FacebookOutgoingTypingNotification(session); - msg.setAddress(notifiedContact.getAddress()); - msg.setTypingState(typingState); - msg.send(); - record.setTime(System.currentTimeMillis()); - record.setType(typingState); - } - } - - public void setStatusMessage(String statusMessage) - throws OperationFailedException - { - try - { - this.session.setStatusMessage(statusMessage); - } - catch (IOException e) - { - throw - new OperationFailedException( - "unable to change facebook status message", - -1, - e); - } - } - - public synchronized void shutdown() - { - if (session != null) - { - logger.info("shutting down facebook adapter"); - session.logout(); - } - } - - /** - * - * @param message - * @param to - * @return - */ - public synchronized MessageDeliveryFailedEvent postMessage( - Message message, - Contact to) - { - FacebookOutgoingMailboxMessage msg - = new FacebookOutgoingMailboxMessage(session); - msg.setAddress(to.getAddress()); - msg.setContent(message.getContent()); - msg.setSubject(message.getSubject()); - msg.setUid(message.getMessageUID()); - try - { - msg.send(); - return null; - } - catch (BrokenFacebookProtocolException e) - { - logger.error(e); - return new MessageDeliveryFailedEvent(message, to, -1, System - .currentTimeMillis(), e.getMessage()); - } - catch (IOException e) - { - logger.warn(e); - return new MessageDeliveryFailedEvent(message, to, -1, System - .currentTimeMillis(), e.getMessage()); - } - catch (FacebookErrorException e) - { - return new MessageDeliveryFailedEvent(message, to, e.getCode()); - } - } - - public MessageDeliveryFailedEvent postFacebookChatMessage( - Message message, - Contact to) - { - FacebookOutgoingChatMessage msg - = new FacebookOutgoingChatMessage(session); - msg.setAddress(to.getAddress()); - msg.setContent(message.getContent()); - msg.setMessageUid(message.getMessageUID()); - try - { - msg.send(); - return null; - } - catch (BrokenFacebookProtocolException e) - { - logger.error(e); - return new MessageDeliveryFailedEvent(message, to, -1, System - .currentTimeMillis(), e.getMessage()); - } - catch (IOException e) - { - logger.warn(e); - return new MessageDeliveryFailedEvent(message, to, -1, System - .currentTimeMillis(), e.getMessage()); - } - catch (FacebookErrorException e) - { - return new MessageDeliveryFailedEvent(message, to, e.getCode()); - } - } - - /** - * Promotes the incoming message to the GUI - * - * @see FacebookIncomingMessageListener#onIncomingChatMessage(FacebookMessage) - */ - public void onIncomingChatMessage(FacebookMessage msg) - { - if (!msg.getFrom().equals(this.session.getUid())) - basicInstantMessaging.receivedInstantMessage(msg); - } - - /** - * Promotes the incoming notification to the GUI - * - * @see FacebookIncomingMessageListener#onIncomingTypingNotification(String, - * int) - */ - public void onIncomingTypingNotification(String buddyUid, int state) - { - if (!buddyUid.equals(this.session.getUid())) - { - Contact fromContact = persistentPresence.findContactByID(buddyUid); - if (fromContact == null) - fromContact - = persistentPresence.createVolatileContact(buddyUid); - - int typingState = OperationSetTypingNotifications.STATE_UNKNOWN; - switch (state) - { - case 1: - typingState = OperationSetTypingNotifications.STATE_TYPING; - break; - case 0: - typingState = OperationSetTypingNotifications.STATE_STOPPED; - break; - default: - typingState = OperationSetTypingNotifications.STATE_UNKNOWN; - } - - typingNotifications - .receivedTypingNotification(fromContact, typingState); - } - } - - /** - * notifies SC that the connection is lost - */ - public void onFacebookConnectionLost() { - if (parentProvider.isRegistered()) - { - try - { - parentProvider.unregister(); - } - catch (OperationFailedException e) - { - logger.error("unable to unregister", e); - } - } - - // tag all the buddies as offline - persistentPresence - .setPresenceStatusForAllContacts(FacebookStatusEnum.OFFLINE); - } - - public void onBuddyListUpdated() - { - for (FacebookUser user : this.session.getBuddyList().getBuddies()) - { - PresenceStatus newStatus; - if (user.isOnline && user.isIdle) - newStatus = FacebookStatusEnum.IDLE; - else if (user.isOnline) - newStatus = FacebookStatusEnum.ONLINE; - else - newStatus = FacebookStatusEnum.OFFLINE; - - persistentPresence.setPresenceStatusForContact(user.uid, newStatus); - } - } - - public FacebookSession getSession() - { - return session; - } - - private static class TypingNotificationRecord - { - private long time; - private int type; - - public TypingNotificationRecord(long time, int type) - { - this.time = time; - this.type = type; - } - - public long getTime() - { - return time; - } - - public int getType() - { - return type; - } - - public void setTime(long time) - { - this.time = time; - } - - public void setType(int type) - { - this.type = type; - } - } -} +/* + * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. See terms of license at gnu.org. + */ +package net.java.sip.communicator.impl.protocol.facebook; + +import java.io.*; +import java.util.*; + +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.service.protocol.event.*; +import net.java.sip.communicator.util.*; + +import org.apache.http.*; +import org.json.*; + +/** + * Adapter for the Facebook protocol. This class works as a bridge between the + * Facebook specific classes and the sip communication interfaces. It manages + * the lifecycle of the classes responsible of accessing Facebook servers and + * also manage the necessary {@link Thread threads} used to update the state + * with the latest server changes. + * + * @author Dai Zhiwei + * @author Lubomir Marinov + * @author Edgar Poce + */ +public class FacebookAdapter + implements FacebookSessionListener +{ + private static Logger logger = Logger.getLogger(FacebookAdapter.class); + + private final OperationSetBasicInstantMessagingFacebookImpl + basicInstantMessaging; + + /** + * Parent service provider + */ + private final ProtocolProviderServiceFacebookImpl parentProvider; + + private final OperationSetPersistentPresenceFacebookImpl persistentPresence; + + /** + * The Facebook session + */ + private FacebookSession session; + + private final OperationSetTypingNotificationsFacebookImpl + typingNotifications; + + /** + * Cache of typing notifications + */ + private final Map typingNotificationRecord + = new HashMap(); + + /** + * Adapter for each Facebook Chat account. + * + * @param parentProvider the parent service provider + * @param persistentPresence + * @param basicInstantMessaging + * @param typingNotifications + */ + public FacebookAdapter( + ProtocolProviderServiceFacebookImpl parentProvider, + OperationSetPersistentPresenceFacebookImpl persistentPresence, + OperationSetBasicInstantMessagingFacebookImpl basicInstantMessaging, + OperationSetTypingNotificationsFacebookImpl typingNotifications) + { + this.parentProvider = parentProvider; + this.persistentPresence = persistentPresence; + this.basicInstantMessaging = basicInstantMessaging; + this.typingNotifications = typingNotifications; + } + + /** + * Get the facebook id of this account + * + * @return the facebook id of this account + */ + public String getUID() + { + return this.session.getUid(); + } + + /** + * Get the parent service provider + * + * @return parent service provider + */ + public ProtocolProviderServiceFacebookImpl getParentProvider() + { + return parentProvider; + } + + /** + * Initializes the {@link FacebookSession},
+ * Initializes the {@link Thread}s to update the buddy list and to poll + * messages + * + * @param email + * @param password + * @return true if the user is logged in + * @throws IOException + * @throws BrokenFacebookProtocolException + */ + public synchronized boolean initialize( + final String email, + final String password) + throws OperationFailedException + { + if (this.session != null && this.session.isLoggedIn()) + return true; + + logger.info("initializing facebook adapter. account"); + try + { + this.session = new FacebookSession(); + boolean loggedIn = session.login(email, password); + if (loggedIn) + session.addListener(this); + return loggedIn; + } + catch (Exception e) + { + throw + new OperationFailedException( + "unable to initialize adapter", + FacebookErrorException.kError_Login_GenericError, + e); + } + } + + /** + * Post typing notification to the given contact. + * + * @param notifiedContact + * the contact we want to notify + * @param typingState + * our current typing state(SC) + * @throws HttpException + * the http exception + * @throws IOException + * IO exception + * @throws JSONException + * JSON parsing exception + * @throws Exception + * the general exception + */ + public void postTypingNotification(Contact notifiedContact, int typingState) + throws HttpException, + IOException, + JSONException, + Exception + { + TypingNotificationRecord record + = typingNotificationRecord.get(notifiedContact.getAddress()); + if (record == null) + { + record = new TypingNotificationRecord(-1l, -1); + synchronized (typingNotificationRecord) + { + typingNotificationRecord + .put(notifiedContact.getAddress(), record); + } + } + + if (record.getTime() < System.currentTimeMillis() - 1000) + { + FacebookOutgoingTypingNotification msg + = new FacebookOutgoingTypingNotification(session); + msg.setAddress(notifiedContact.getAddress()); + msg.setTypingState(typingState); + msg.send(); + record.setTime(System.currentTimeMillis()); + record.setType(typingState); + } + } + + public void setStatusMessage(String statusMessage) + throws OperationFailedException + { + try + { + this.session.setStatusMessage(statusMessage); + } + catch (IOException e) + { + throw + new OperationFailedException( + "unable to change facebook status message", + -1, + e); + } + } + + public synchronized void shutdown() + { + if (session != null) + { + logger.info("shutting down facebook adapter"); + session.logout(); + } + } + + /** + * + * @param message + * @param to + * @return + */ + public synchronized MessageDeliveryFailedEvent postMessage( + Message message, + Contact to) + { + FacebookOutgoingMailboxMessage msg + = new FacebookOutgoingMailboxMessage(session); + msg.setAddress(to.getAddress()); + msg.setContent(message.getContent()); + msg.setSubject(message.getSubject()); + msg.setUid(message.getMessageUID()); + try + { + msg.send(); + return null; + } + catch (BrokenFacebookProtocolException e) + { + logger.error(e); + return new MessageDeliveryFailedEvent(message, to, -1, System + .currentTimeMillis(), e.getMessage()); + } + catch (IOException e) + { + logger.warn(e); + return new MessageDeliveryFailedEvent(message, to, -1, System + .currentTimeMillis(), e.getMessage()); + } + catch (FacebookErrorException e) + { + return new MessageDeliveryFailedEvent(message, to, e.getCode()); + } + } + + public MessageDeliveryFailedEvent postFacebookChatMessage( + Message message, + Contact to) + { + FacebookOutgoingChatMessage msg + = new FacebookOutgoingChatMessage(session); + msg.setAddress(to.getAddress()); + msg.setContent(message.getContent()); + msg.setMessageUid(message.getMessageUID()); + try + { + msg.send(); + return null; + } + catch (BrokenFacebookProtocolException e) + { + logger.error(e); + return new MessageDeliveryFailedEvent(message, to, -1, System + .currentTimeMillis(), e.getMessage()); + } + catch (IOException e) + { + logger.warn(e); + return new MessageDeliveryFailedEvent(message, to, -1, System + .currentTimeMillis(), e.getMessage()); + } + catch (FacebookErrorException e) + { + return new MessageDeliveryFailedEvent(message, to, e.getCode()); + } + } + + /** + * Promotes the incoming message to the GUI + * + * @see FacebookSessionListener#onIncomingChatMessage(FacebookMessage) + */ + public void onIncomingChatMessage(FacebookMessage msg) + { + if (!msg.getFrom().equals(this.session.getUid())) + basicInstantMessaging.receivedInstantMessage(msg); + } + + /** + * Promotes the incoming notification to the GUI + * + * @see FacebookSessionListener#onIncomingTypingNotification(String, int) + */ + public void onIncomingTypingNotification(String buddyUid, int state) + { + if (!buddyUid.equals(this.session.getUid())) + { + Contact fromContact = persistentPresence.findContactByID(buddyUid); + if (fromContact == null) + fromContact + = persistentPresence.createVolatileContact(buddyUid); + + int typingState = OperationSetTypingNotifications.STATE_UNKNOWN; + switch (state) + { + case 1: + typingState = OperationSetTypingNotifications.STATE_TYPING; + break; + case 0: + typingState = OperationSetTypingNotifications.STATE_STOPPED; + break; + default: + typingState = OperationSetTypingNotifications.STATE_UNKNOWN; + } + + typingNotifications + .receivedTypingNotification(fromContact, typingState); + } + } + + /** + * notifies SC that the connection is lost + */ + public void onFacebookConnectionLost() { + if (parentProvider.isRegistered()) + { + try + { + parentProvider.unregister(); + } + catch (OperationFailedException e) + { + logger.error("unable to unregister", e); + } + } + + // tag all the buddies as offline + persistentPresence + .setPresenceStatusForAllContacts(FacebookStatusEnum.OFFLINE); + } + + public void onBuddyListUpdated() + { + for (FacebookUser user : this.session.getBuddyList().getBuddies()) + { + PresenceStatus newStatus; + if (user.isOnline && user.isIdle) + newStatus = FacebookStatusEnum.IDLE; + else if (user.isOnline) + newStatus = FacebookStatusEnum.ONLINE; + else + newStatus = FacebookStatusEnum.OFFLINE; + + persistentPresence.setPresenceStatusForContact(user.uid, newStatus); + } + } + + public FacebookSession getSession() + { + return session; + } + + private static class TypingNotificationRecord + { + private long time; + private int type; + + public TypingNotificationRecord(long time, int type) + { + this.time = time; + this.type = type; + } + + public long getTime() + { + return time; + } + + public int getType() + { + return type; + } + + public void setTime(long time) + { + this.time = time; + } + + public void setType(int type) + { + this.type = type; + } + } +} diff --git a/src/net/java/sip/communicator/impl/protocol/facebook/FacebookBuddyList.java b/src/net/java/sip/communicator/impl/protocol/facebook/FacebookBuddyList.java index 49529ce2d..680047d5e 100644 --- a/src/net/java/sip/communicator/impl/protocol/facebook/FacebookBuddyList.java +++ b/src/net/java/sip/communicator/impl/protocol/facebook/FacebookBuddyList.java @@ -1,288 +1,287 @@ -/* - * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.protocol.facebook; - -import java.io.*; -import java.util.*; - -import net.java.sip.communicator.util.*; - -import org.apache.http.*; -import org.apache.http.client.entity.*; -import org.apache.http.client.methods.*; -import org.apache.http.message.*; -import org.apache.http.protocol.HTTP; -import org.apache.http.util.*; -import org.json.*; - -/** - * Facebook buddy list that store the online buddies information we got from the - * server since we logged in. Some information of ourselves also included.
- * This class is responsible of establishing the http connections and updating - * its state when requested. - * - * @author Dai Zhiwei - * @author Edgar Poce - */ -public class FacebookBuddyList -{ - private static Logger logger = Logger.getLogger(FacebookBuddyList.class); - - /** - * The url of the update - */ - private static final String BUDDYLIST_URL - = "http://www.facebook.com/ajax/chat/buddy_list.php"; - - /** - * The Facebook Session - */ - private final FacebookSession session; - - /** - * Our (online) buddies' information cache - */ - private transient Map cache - = new LinkedHashMap(); - - /** - * Some information of ourselves/myself. - */ - private transient FacebookUser me; - - /** - * Listener of this buddy list - */ - private List listeners - = new ArrayList(); - - /** - * Init the cache and the parent adapter. - * - * @param adapter - */ - public FacebookBuddyList(FacebookSession session) - { - this.session = session; - } - - public void update() - throws BrokenFacebookProtocolException, - IOException, - FacebookErrorException - { - // reconnecting - this.session.reconnect(); - logger.info("Updating buddy list..."); - // perform POST request - List nvps = new ArrayList(); - nvps.add(new BasicNameValuePair("buddy_list", "1")); - nvps.add(new BasicNameValuePair("notifications", "1")); - nvps.add(new BasicNameValuePair("force_render", "true")); - nvps.add(new BasicNameValuePair("post_form_id", session.getFormId())); - nvps.add(new BasicNameValuePair("user", session.getUid())); - HttpPost post = new HttpPost(BUDDYLIST_URL); - post.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8)); - HttpResponse response = this.session.getHttpClient().execute(post); - String body = EntityUtils.toString(response.getEntity()); - if (response.getStatusLine().getStatusCode() != 200) - { - throw new BrokenFacebookProtocolException("Code " - + response.getStatusLine().getStatusCode() - + ". Unable to update Facebook buddy list."); - } - this.update(body); - } - - /** - * Get meta info of this account - * - * @return meta info of this account - */ - public FacebookUser getMyMetaInfo() - { - return me; - } - - /** - * Get our buddy who has the given id from the cache. - * - * @param contactID - * the id we wanna look up - * @return the buddy who has the given id - * @throws FacebookErrorException - * @throws IOException - * @throws BrokenFacebookProtocolException - */ - public FacebookUser getBuddyByUID(String uid) - throws BrokenFacebookProtocolException, - IOException, - FacebookErrorException - { - FacebookUser buddy = this.cache.get(uid); - if (buddy == null && this.me != null && this.me.uid.equals(uid)) - { - buddy = me; - } - return buddy; - } - - /** - * @return the users in the cache - */ - public Collection getBuddies() - { - return Collections.unmodifiableCollection(this.cache.values()); - } - - /** - * Release the resource - */ - public void clear() - { - for (FacebookUser u : this.cache.values()) - { - u.isOnline = false; - } - } - - /** - * Updates the buddy list
- * If the {@link FacebookSession} is logged out then this method returns - * without modifying the state of the buddy list. - * - * @param body - * @throws BrokenFacebookProtocolException - * @throws FacebookErrorException - */ - @SuppressWarnings("unchecked") - public void update(String body) - throws BrokenFacebookProtocolException, - FacebookErrorException - { - // the session might be getting closed by another thread - // do nothing if it's logged out - synchronized (session) - { - if (!session.isLoggedIn()) - { - return; - } - } - - JSONObject jsonBuddyList = parseBody(body); - try { - /* - * If listChanged, then we can get the buddies available via looking - * at the nowAvailableList else. we can only get the buddies' info, - * and the nowAvailableList is empty. - */ - JSONObject userInfos = (JSONObject) jsonBuddyList.get("userInfos"); - if (userInfos != null) - { - // Then add the new buddies and set them as online(constructor) - Iterator it = userInfos.keys(); - while (it.hasNext()) - { - String key = it.next(); - JSONObject jsonUser = (JSONObject) userInfos.get(key); - if (jsonUser == null) - { - throw new BrokenFacebookProtocolException( - "unable to get user info. " + userInfos); - } - FacebookUser buddy = new FacebookUser(key, jsonUser); - if (buddy.uid.equals(this.session.getUid())) - { - this.me = buddy; - } - else - { - this.cache.put(key, buddy); - } - } - } - - JSONObject nowAvailableList = jsonBuddyList - .getJSONObject("nowAvailableList"); - - if (nowAvailableList == null) - { - throw new BrokenFacebookProtocolException( - "Unable to read Facebook now available list"); - } - - for (FacebookUser user : this.cache.values()) - { - if (nowAvailableList.has(user.uid)) - { - user.isOnline = true; - user.lastSeen = Calendar.getInstance().getTimeInMillis(); - user.isIdle = nowAvailableList.getJSONObject(user.uid) - .getBoolean("i"); - } - else - { - user.isOnline = false; - } - } - // notify listeners - for (FacebookSessionListener l : this.listeners) - l.onBuddyListUpdated(); - } - catch (JSONException e) - { - throw new BrokenFacebookProtocolException(e); - } - } - - private JSONObject parseBody(String body) - throws BrokenFacebookProtocolException, - FacebookErrorException - { - FacebookJsonResponse jsonResponse = new FacebookJsonResponse(session, - body); - try - { - JSONObject json = jsonResponse.getJson(); - JSONObject payload = (JSONObject) json.get("payload"); - if (payload == null) - { - throw new BrokenFacebookProtocolException( - "unable to parse buddy list. there's no payload field. " - + jsonResponse); - } - JSONObject jsonBuddyList = (JSONObject) payload.get("buddy_list"); - if (jsonBuddyList == null) - { - throw new BrokenFacebookProtocolException( - "unable to parse buddy list. there's no buddy list field. " - + jsonResponse); - } - return jsonBuddyList; - } - catch (JSONException e) - { - throw new BrokenFacebookProtocolException( - "unable to parse json response"); - } - } - - public int getSize() - { - return this.cache.size(); - } - - /** - * Adds a listener which is notified when the buddy list state changes - * - * @param listener - */ - public void addListener(FacebookSessionListener listener) - { - this.listeners.add(listener); - } -} +/* + * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. See terms of license at gnu.org. + */ +package net.java.sip.communicator.impl.protocol.facebook; + +import java.io.*; +import java.util.*; + +import net.java.sip.communicator.util.*; + +import org.apache.http.*; +import org.apache.http.client.entity.*; +import org.apache.http.client.methods.*; +import org.apache.http.message.*; +import org.apache.http.protocol.HTTP; +import org.apache.http.util.*; +import org.json.*; + +/** + * Facebook buddy list that store the online buddies information we got from the + * server since we logged in. Some information of ourselves also included.
+ * This class is responsible of establishing the http connections and updating + * its state when requested. + * + * @author Dai Zhiwei + * @author Edgar Poce + */ +public class FacebookBuddyList +{ + private static Logger logger = Logger.getLogger(FacebookBuddyList.class); + + /** + * The url of the update + */ + private static final String BUDDYLIST_URL + = "http://www.facebook.com/ajax/chat/buddy_list.php"; + + /** + * The Facebook Session + */ + private final FacebookSession session; + + /** + * Our (online) buddies' information cache + */ + private transient Map cache + = new LinkedHashMap(); + + /** + * Some information of ourselves/myself. + */ + private transient FacebookUser me; + + /** + * Listener of this buddy list + */ + private List listeners + = new ArrayList(); + + /** + * Init the cache and the parent adapter. + * + * @param session the Facebook session + */ + public FacebookBuddyList(FacebookSession session) + { + this.session = session; + } + + public void update() + throws BrokenFacebookProtocolException, + IOException, + FacebookErrorException + { + // reconnecting + this.session.reconnect(); + logger.info("Updating buddy list..."); + // perform POST request + List nvps = new ArrayList(); + nvps.add(new BasicNameValuePair("buddy_list", "1")); + nvps.add(new BasicNameValuePair("notifications", "1")); + nvps.add(new BasicNameValuePair("force_render", "true")); + nvps.add(new BasicNameValuePair("post_form_id", session.getFormId())); + nvps.add(new BasicNameValuePair("user", session.getUid())); + HttpPost post = new HttpPost(BUDDYLIST_URL); + post.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8)); + HttpResponse response = this.session.getHttpClient().execute(post); + String body = EntityUtils.toString(response.getEntity()); + if (response.getStatusLine().getStatusCode() != 200) + { + throw new BrokenFacebookProtocolException("Code " + + response.getStatusLine().getStatusCode() + + ". Unable to update Facebook buddy list."); + } + this.update(body); + } + + /** + * Get meta info of this account + * + * @return meta info of this account + */ + public FacebookUser getMyMetaInfo() + { + return me; + } + + /** + * Get our buddy who has the given id from the cache. + * + * @param uid the id we want to look up + * @return the buddy who has the given id + * @throws FacebookErrorException + * @throws IOException + * @throws BrokenFacebookProtocolException + */ + public FacebookUser getBuddyByUID(String uid) + throws BrokenFacebookProtocolException, + IOException, + FacebookErrorException + { + FacebookUser buddy = this.cache.get(uid); + if (buddy == null && this.me != null && this.me.uid.equals(uid)) + { + buddy = me; + } + return buddy; + } + + /** + * @return the users in the cache + */ + public Collection getBuddies() + { + return Collections.unmodifiableCollection(this.cache.values()); + } + + /** + * Release the resource + */ + public void clear() + { + for (FacebookUser u : this.cache.values()) + { + u.isOnline = false; + } + } + + /** + * Updates the buddy list
+ * If the {@link FacebookSession} is logged out then this method returns + * without modifying the state of the buddy list. + * + * @param body + * @throws BrokenFacebookProtocolException + * @throws FacebookErrorException + */ + @SuppressWarnings("unchecked") + public void update(String body) + throws BrokenFacebookProtocolException, + FacebookErrorException + { + // the session might be getting closed by another thread + // do nothing if it's logged out + synchronized (session) + { + if (!session.isLoggedIn()) + { + return; + } + } + + JSONObject jsonBuddyList = parseBody(body); + try { + /* + * If listChanged, then we can get the buddies available via looking + * at the nowAvailableList else. we can only get the buddies' info, + * and the nowAvailableList is empty. + */ + JSONObject userInfos = (JSONObject) jsonBuddyList.get("userInfos"); + if (userInfos != null) + { + // Then add the new buddies and set them as online(constructor) + Iterator it = userInfos.keys(); + while (it.hasNext()) + { + String key = it.next(); + JSONObject jsonUser = (JSONObject) userInfos.get(key); + if (jsonUser == null) + { + throw new BrokenFacebookProtocolException( + "unable to get user info. " + userInfos); + } + FacebookUser buddy = new FacebookUser(key, jsonUser); + if (buddy.uid.equals(this.session.getUid())) + { + this.me = buddy; + } + else + { + this.cache.put(key, buddy); + } + } + } + + JSONObject nowAvailableList = jsonBuddyList + .getJSONObject("nowAvailableList"); + + if (nowAvailableList == null) + { + throw new BrokenFacebookProtocolException( + "Unable to read Facebook now available list"); + } + + for (FacebookUser user : this.cache.values()) + { + if (nowAvailableList.has(user.uid)) + { + user.isOnline = true; + user.lastSeen = Calendar.getInstance().getTimeInMillis(); + user.isIdle = nowAvailableList.getJSONObject(user.uid) + .getBoolean("i"); + } + else + { + user.isOnline = false; + } + } + // notify listeners + for (FacebookSessionListener l : this.listeners) + l.onBuddyListUpdated(); + } + catch (JSONException e) + { + throw new BrokenFacebookProtocolException(e); + } + } + + private JSONObject parseBody(String body) + throws BrokenFacebookProtocolException, + FacebookErrorException + { + FacebookJsonResponse jsonResponse = new FacebookJsonResponse(session, + body); + try + { + JSONObject json = jsonResponse.getJson(); + JSONObject payload = (JSONObject) json.get("payload"); + if (payload == null) + { + throw new BrokenFacebookProtocolException( + "unable to parse buddy list. there's no payload field. " + + jsonResponse); + } + JSONObject jsonBuddyList = (JSONObject) payload.get("buddy_list"); + if (jsonBuddyList == null) + { + throw new BrokenFacebookProtocolException( + "unable to parse buddy list. there's no buddy list field. " + + jsonResponse); + } + return jsonBuddyList; + } + catch (JSONException e) + { + throw new BrokenFacebookProtocolException( + "unable to parse json response"); + } + } + + public int getSize() + { + return this.cache.size(); + } + + /** + * Adds a listener which is notified when the buddy list state changes + * + * @param listener + */ + public void addListener(FacebookSessionListener listener) + { + this.listeners.add(listener); + } +} diff --git a/src/net/java/sip/communicator/impl/protocol/facebook/FacebookIncomingMessagePoller.java b/src/net/java/sip/communicator/impl/protocol/facebook/FacebookIncomingMessagePoller.java index 299c5e50e..80fd31198 100644 --- a/src/net/java/sip/communicator/impl/protocol/facebook/FacebookIncomingMessagePoller.java +++ b/src/net/java/sip/communicator/impl/protocol/facebook/FacebookIncomingMessagePoller.java @@ -17,12 +17,12 @@ /** * This poller checks for new messages in Facebook servers and notifies to the - * registered {@link FacebookIncomingMessageListener listeners} if a new + * registered {@link FacebookSessionListener listeners} if a new * {@link FacebookMessage} is found.
- * Registered {@link FacebookIncomingMessageListener listeners} are notified - * upon arrival of both messages from other buddies and own messages.
- * It's responsibility of the {@link FacebookIncomingMessageListener listeners} - * to discard undesired notifications, e.g. own messages. + * Registered {@link FacebookSessionListener listeners} are notified upon + * arrival of both messages from other buddies and own messages.
+ * It's the responsibility of the {@link FacebookSessionListener listeners} to + * discard undesired notifications, e.g. own messages. * * @author Edgar Poce */ diff --git a/src/net/java/sip/communicator/impl/protocol/facebook/FacebookOutgoingChatMessage.java b/src/net/java/sip/communicator/impl/protocol/facebook/FacebookOutgoingChatMessage.java index a8ce61dd3..71fa0a281 100644 --- a/src/net/java/sip/communicator/impl/protocol/facebook/FacebookOutgoingChatMessage.java +++ b/src/net/java/sip/communicator/impl/protocol/facebook/FacebookOutgoingChatMessage.java @@ -45,7 +45,6 @@ public FacebookOutgoingChatMessage(FacebookSession session) * Only one message can be sent at a time for a given * {@link FacebookSession} * - * @return true if the message was sent successfully * @throws BrokenFacebookProtocolException * @throws IOException */ diff --git a/src/net/java/sip/communicator/impl/protocol/facebook/OperationSetBasicInstantMessagingFacebookImpl.java b/src/net/java/sip/communicator/impl/protocol/facebook/OperationSetBasicInstantMessagingFacebookImpl.java index a40cf6335..26a525954 100644 --- a/src/net/java/sip/communicator/impl/protocol/facebook/OperationSetBasicInstantMessagingFacebookImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/facebook/OperationSetBasicInstantMessagingFacebookImpl.java @@ -1,266 +1,265 @@ -/* - * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.protocol.facebook; - -import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.protocol.event.*; -import net.java.sip.communicator.util.*; - -/** - * Instant messaging functionality for the Facebook protocol. - * - * @author Dai Zhiwei - * @author Lubomir Marinov - */ -public class OperationSetBasicInstantMessagingFacebookImpl - extends AbstractOperationSetBasicInstantMessaging -{ - private static final Logger logger - = Logger.getLogger(OperationSetBasicInstantMessagingFacebookImpl.class); - - /** - * The currently valid persistent presence operation set.. - */ - private OperationSetPersistentPresenceFacebookImpl opSetPersPresence = null; - - /** - * The protocol provider that created us. - */ - private ProtocolProviderServiceFacebookImpl parentProvider = null; - - /** - * Creates an instance of this operation set keeping a reference to the - * parent protocol provider and presence operation set. - * - * @param provider The provider instance that creates us. - * @param opSetPersPresence the currently valid - * OperationSetPersistentPresenceFacebookImpl - * instance. - */ - public OperationSetBasicInstantMessagingFacebookImpl( - ProtocolProviderServiceFacebookImpl provider, - OperationSetPersistentPresenceFacebookImpl opSetPersPresence) - { - this.opSetPersPresence = opSetPersPresence; - this.parentProvider = provider; - } - - /* - * Implements - * AbstractOperationSetBasicInstantMessaging#createMessage(String, String, - * String, String). Creates a new MessageFacebookImpl instance with the - * specified properties. - */ - public Message createMessage( - String content, String contentType, String encoding, String subject) - { - return - new MessageFacebookImpl(content, contentType, encoding, subject); - } - - /** - * Sends the message to the destination indicated by the - * to contact. - * - * @param to the Contact to send message to - * @param message the Message to send. - * @throws IllegalStateException if the underlying ICQ stack is not - * registered and initialized. - * @throws IllegalArgumentException if to is not an instance - * belonging to the underlying implementation. - */ - public void sendInstantMessage(final Contact to, final Message message) - throws IllegalStateException, - IllegalArgumentException - { - if (!(to instanceof ContactFacebookImpl)) - throw new IllegalArgumentException( - "The specified contact is not a Facebook contact." + to); - - Thread sender = new Thread(new Runnable() - { - - public void run() - { - // deliver the facebook chat Message - MessageDeliveryFailedEvent errorEvent = null; - errorEvent = - OperationSetBasicInstantMessagingFacebookImpl.this.parentProvider - .getAdapter().postFacebookChatMessage(message, to); - if (errorEvent == null) - { - fireMessageDelivered(message, to); - return; - } - if(errorEvent.getErrorCode() == FacebookErrorException.kError_Async_NotLoggedIn - || errorEvent.getErrorCode() == FacebookErrorException.kError_Async_LoginChanged) - { - try - { - parentProvider.unregister(RegistrationStateChangeEvent.REASON_MULTIPLE_LOGINS); - } - catch (OperationFailedException e1) - { - logger.error( - "Unable to unregister the protocol provider: " - + this - + " due to the following exception: " + e1); - } - fireMessageDeliveryFailed( - message, - to, - MessageDeliveryFailedEvent.PROVIDER_NOT_REGISTERED); - return; - } - - // if the above delivery failed, we try again! - try - { - // wait a moment - Thread.sleep(1000); - errorEvent = - OperationSetBasicInstantMessagingFacebookImpl.this.parentProvider - .getAdapter().postFacebookChatMessage(message, to); - if (errorEvent == null) - { - fireMessageDelivered(message, to); - return; - } - if(errorEvent.getErrorCode() == FacebookErrorException.kError_Async_NotLoggedIn - || errorEvent.getErrorCode() == FacebookErrorException.kError_Async_LoginChanged) - { - try - { - parentProvider.unregister(RegistrationStateChangeEvent.REASON_MULTIPLE_LOGINS); - } - catch (OperationFailedException e1) - { - logger.error( - "Unable to unregister the protocol provider: " - + this - + " due to the following exception: " + e1); - } - } - } - catch (InterruptedException e) - { - logger.warn(e.getMessage()); - } - // if we get here, we have failed to deliver this message, - // twice. - fireMessageDeliveryFailed( - message, - to, - MessageDeliveryFailedEvent.UNKNOWN_ERROR); - // now do message delivery.----what's this? - // in case that the "to" we deliver this message to is - // ourselves? - // deliverMessageToMyself(message, (ContactFacebookImpl)to); - } - }); - sender.start(); - } - - /** - * Invoked by the facebook adapter when we got messages from the server. - * - * @param message - * @param from - */ - public void receivedInstantMessage(FacebookMessage fbmsg) - { - Message message = this.createMessage(fbmsg.getText()); - String fromID = fbmsg.getFrom(); - - // TODO handle the msgID. - // it's generated when we createMessage() by now. - // We should set the message id according to the fbmsg.msgID. - // But it's not important. - - Contact fromContact = opSetPersPresence.findContactByID(fromID); - if (fromContact == null) - { - // from facebook user who are not on our contact list - // TODO creat volatile contact, fire event. - fromContact = opSetPersPresence.createVolatileContact(fromID); - // opSetPersPresence.subscribe(fromID); - } - fireMessageReceived(message, fromContact); - } - - /** - * Notifies all registered message listeners that a message has been - * delivered successfully to its addressee.. - * - * @param message - * the Message that has been delivered. - * @param to - * the Contact that message was delivered to. - */ - protected void fireMessageDelivered(Message message, Contact to) - { - // we succeeded in sending a message to contact "to", - // so we know he is online - // but -- if we support the "invisible" status, - // this line could be commented - opSetPersPresence - .setPresenceStatusForContact( - (ContactFacebookImpl) to, - FacebookStatusEnum.ONLINE); - - super.fireMessageDelivered(message, to); - } - - /** - * Notifies all registered message listeners that a message has been - * received. - * - * @param message the Message that has been received. - * @param from the Contact that message was received - * from. - */ - protected void fireMessageReceived(Message message, Contact from) - { - // we got a message from contact "from", so we know he is online - opSetPersPresence - .setPresenceStatusForContact( - (ContactFacebookImpl) from, - FacebookStatusEnum.ONLINE); - - super.fireMessageReceived(message, from); - } - - /** - * Determines whether the protocol provider (or the protocol itself) support - * sending and receiving offline messages. Most often this method would - * return true for protocols that support offline messages and false for - * those that don't. It is however possible for a protocol to support these - * messages and yet have a particular account that does not (i.e. feature - * not enabled on the protocol server). In cases like this it is possible - * for this method to return true even when offline messaging is not - * supported, and then have the sendMessage method throw an - * OperationFailedException with code - OFFLINE_MESSAGES_NOT_SUPPORTED. - * - * @return true if the protocol supports offline messages and - * false otherwise. - */ - public boolean isOfflineMessagingSupported() - { - return false; - } - - /** - * Determines wheter the protocol supports the supplied content type - * - * @param contentType the type we want to check - * @return true if the protocol supports it and false - * otherwise. - */ - public boolean isContentTypeSupported(String contentType) - { - return contentType.equals(DEFAULT_MIME_TYPE); - } -} +/* + * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. See terms of license at gnu.org. + */ +package net.java.sip.communicator.impl.protocol.facebook; + +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.service.protocol.event.*; +import net.java.sip.communicator.util.*; + +/** + * Instant messaging functionality for the Facebook protocol. + * + * @author Dai Zhiwei + * @author Lubomir Marinov + */ +public class OperationSetBasicInstantMessagingFacebookImpl + extends AbstractOperationSetBasicInstantMessaging +{ + private static final Logger logger + = Logger.getLogger(OperationSetBasicInstantMessagingFacebookImpl.class); + + /** + * The currently valid persistent presence operation set.. + */ + private OperationSetPersistentPresenceFacebookImpl opSetPersPresence = null; + + /** + * The protocol provider that created us. + */ + private ProtocolProviderServiceFacebookImpl parentProvider = null; + + /** + * Creates an instance of this operation set keeping a reference to the + * parent protocol provider and presence operation set. + * + * @param provider The provider instance that creates us. + * @param opSetPersPresence the currently valid + * OperationSetPersistentPresenceFacebookImpl + * instance. + */ + public OperationSetBasicInstantMessagingFacebookImpl( + ProtocolProviderServiceFacebookImpl provider, + OperationSetPersistentPresenceFacebookImpl opSetPersPresence) + { + this.opSetPersPresence = opSetPersPresence; + this.parentProvider = provider; + } + + /* + * Implements + * AbstractOperationSetBasicInstantMessaging#createMessage(String, String, + * String, String). Creates a new MessageFacebookImpl instance with the + * specified properties. + */ + public Message createMessage( + String content, String contentType, String encoding, String subject) + { + return + new MessageFacebookImpl(content, contentType, encoding, subject); + } + + /** + * Sends the message to the destination indicated by the + * to contact. + * + * @param to the Contact to send message to + * @param message the Message to send. + * @throws IllegalStateException if the underlying ICQ stack is not + * registered and initialized. + * @throws IllegalArgumentException if to is not an instance + * belonging to the underlying implementation. + */ + public void sendInstantMessage(final Contact to, final Message message) + throws IllegalStateException, + IllegalArgumentException + { + if (!(to instanceof ContactFacebookImpl)) + throw new IllegalArgumentException( + "The specified contact is not a Facebook contact." + to); + + Thread sender = new Thread(new Runnable() + { + + public void run() + { + // deliver the facebook chat Message + MessageDeliveryFailedEvent errorEvent = null; + errorEvent = + OperationSetBasicInstantMessagingFacebookImpl.this.parentProvider + .getAdapter().postFacebookChatMessage(message, to); + if (errorEvent == null) + { + fireMessageDelivered(message, to); + return; + } + if(errorEvent.getErrorCode() == FacebookErrorException.kError_Async_NotLoggedIn + || errorEvent.getErrorCode() == FacebookErrorException.kError_Async_LoginChanged) + { + try + { + parentProvider.unregister(RegistrationStateChangeEvent.REASON_MULTIPLE_LOGINS); + } + catch (OperationFailedException e1) + { + logger.error( + "Unable to unregister the protocol provider: " + + this + + " due to the following exception: " + e1); + } + fireMessageDeliveryFailed( + message, + to, + MessageDeliveryFailedEvent.PROVIDER_NOT_REGISTERED); + return; + } + + // if the above delivery failed, we try again! + try + { + // wait a moment + Thread.sleep(1000); + errorEvent = + OperationSetBasicInstantMessagingFacebookImpl.this.parentProvider + .getAdapter().postFacebookChatMessage(message, to); + if (errorEvent == null) + { + fireMessageDelivered(message, to); + return; + } + if(errorEvent.getErrorCode() == FacebookErrorException.kError_Async_NotLoggedIn + || errorEvent.getErrorCode() == FacebookErrorException.kError_Async_LoginChanged) + { + try + { + parentProvider.unregister(RegistrationStateChangeEvent.REASON_MULTIPLE_LOGINS); + } + catch (OperationFailedException e1) + { + logger.error( + "Unable to unregister the protocol provider: " + + this + + " due to the following exception: " + e1); + } + } + } + catch (InterruptedException e) + { + logger.warn(e.getMessage()); + } + // if we get here, we have failed to deliver this message, + // twice. + fireMessageDeliveryFailed( + message, + to, + MessageDeliveryFailedEvent.UNKNOWN_ERROR); + // now do message delivery.----what's this? + // in case that the "to" we deliver this message to is + // ourselves? + // deliverMessageToMyself(message, (ContactFacebookImpl)to); + } + }); + sender.start(); + } + + /** + * Invoked by the facebook adapter when we got messages from the server. + * + * @param fbmsg the received Facebook instant message + */ + public void receivedInstantMessage(FacebookMessage fbmsg) + { + Message message = this.createMessage(fbmsg.getText()); + String fromID = fbmsg.getFrom(); + + // TODO handle the msgID. + // it's generated when we createMessage() by now. + // We should set the message id according to the fbmsg.msgID. + // But it's not important. + + Contact fromContact = opSetPersPresence.findContactByID(fromID); + if (fromContact == null) + { + // from facebook user who are not on our contact list + // TODO creat volatile contact, fire event. + fromContact = opSetPersPresence.createVolatileContact(fromID); + // opSetPersPresence.subscribe(fromID); + } + fireMessageReceived(message, fromContact); + } + + /** + * Notifies all registered message listeners that a message has been + * delivered successfully to its addressee.. + * + * @param message + * the Message that has been delivered. + * @param to + * the Contact that message was delivered to. + */ + protected void fireMessageDelivered(Message message, Contact to) + { + // we succeeded in sending a message to contact "to", + // so we know he is online + // but -- if we support the "invisible" status, + // this line could be commented + opSetPersPresence + .setPresenceStatusForContact( + (ContactFacebookImpl) to, + FacebookStatusEnum.ONLINE); + + super.fireMessageDelivered(message, to); + } + + /** + * Notifies all registered message listeners that a message has been + * received. + * + * @param message the Message that has been received. + * @param from the Contact that message was received + * from. + */ + protected void fireMessageReceived(Message message, Contact from) + { + // we got a message from contact "from", so we know he is online + opSetPersPresence + .setPresenceStatusForContact( + (ContactFacebookImpl) from, + FacebookStatusEnum.ONLINE); + + super.fireMessageReceived(message, from); + } + + /** + * Determines whether the protocol provider (or the protocol itself) support + * sending and receiving offline messages. Most often this method would + * return true for protocols that support offline messages and false for + * those that don't. It is however possible for a protocol to support these + * messages and yet have a particular account that does not (i.e. feature + * not enabled on the protocol server). In cases like this it is possible + * for this method to return true even when offline messaging is not + * supported, and then have the sendMessage method throw an + * OperationFailedException with code - OFFLINE_MESSAGES_NOT_SUPPORTED. + * + * @return true if the protocol supports offline messages and + * false otherwise. + */ + public boolean isOfflineMessagingSupported() + { + return false; + } + + /** + * Determines wheter the protocol supports the supplied content type + * + * @param contentType the type we want to check + * @return true if the protocol supports it and false + * otherwise. + */ + public boolean isContentTypeSupported(String contentType) + { + return contentType.equals(DEFAULT_MIME_TYPE); + } +} diff --git a/src/net/java/sip/communicator/impl/protocol/icq/AdHocChatRoomIcqImpl.java b/src/net/java/sip/communicator/impl/protocol/icq/AdHocChatRoomIcqImpl.java index bc851b60a..8825d84bc 100644 --- a/src/net/java/sip/communicator/impl/protocol/icq/AdHocChatRoomIcqImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/icq/AdHocChatRoomIcqImpl.java @@ -377,7 +377,7 @@ public void leave() { Map.Entry memberEntry = membersSet.next(); - Contact participant = (Contact) memberEntry.getValue(); + Contact participant = memberEntry.getValue(); fireParticipantPresenceEvent(participant, AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_LEFT, diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerJabberImpl.java index 0aa226427..e929c816b 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerJabberImpl.java @@ -107,8 +107,8 @@ public String getDisplayName() if (call != null) { ProtocolProviderService pps = call.getProtocolProvider(); - OperationSetPresence opSetPresence = (OperationSetPresence) pps - .getOperationSet(OperationSetPresence.class); + OperationSetPresence opSetPresence + = pps.getOperationSet(OperationSetPresence.class); Contact cont = opSetPresence.findContactByID(getAddress()); if (cont != null) @@ -243,8 +243,8 @@ public ProtocolProviderService getProtocolProvider() public Contact getContact() { ProtocolProviderService pps = call.getProtocolProvider(); - OperationSetPresence opSetPresence = (OperationSetPresence) pps - .getOperationSet(OperationSetPresence.class); + OperationSetPresence opSetPresence + = pps.getOperationSet(OperationSetPresence.class); return opSetPresence.findContactByID(getAddress()); } diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetGeolocationJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetGeolocationJabberImpl.java index 78fd7a9ed..dbc8f9a6c 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetGeolocationJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetGeolocationJabberImpl.java @@ -63,8 +63,9 @@ public OperationSetGeolocationJabberImpl( { this.jabberProvider = provider; - this.opsetprez = (OperationSetPersistentPresence) - provider.getOperationSet(OperationSetPersistentPresence.class); + this.opsetprez + = provider + .getOperationSet(OperationSetPersistentPresence.class); this.jabberProvider.addRegistrationStateChangeListener( new RegistrationStateListener()); diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetMultiUserChatJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetMultiUserChatJabberImpl.java index 6f278d267..7bc84fc34 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetMultiUserChatJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetMultiUserChatJabberImpl.java @@ -63,7 +63,7 @@ public class OperationSetMultiUserChatJabberImpl jabberProvider.addRegistrationStateChangeListener(providerRegListener); OperationSetPersistentPresence presenceOpSet - = (OperationSetPersistentPresence) jabberProvider + = jabberProvider .getOperationSet(OperationSetPersistentPresence.class); presenceOpSet.addSubscriptionListener(this); diff --git a/src/net/java/sip/communicator/impl/protocol/rss/UriHandlerRssImpl.java b/src/net/java/sip/communicator/impl/protocol/rss/UriHandlerRssImpl.java index 573ff2433..d85bfcf85 100644 --- a/src/net/java/sip/communicator/impl/protocol/rss/UriHandlerRssImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/rss/UriHandlerRssImpl.java @@ -151,8 +151,7 @@ public void handleUri(String uri) } OperationSetPresence presenceOpSet - = (OperationSetPresence) provider - .getOperationSet(OperationSetPresence.class); + = provider.getOperationSet(OperationSetPresence.class); try { diff --git a/src/net/java/sip/communicator/impl/protocol/ssh/ContactSSHImpl.java b/src/net/java/sip/communicator/impl/protocol/ssh/ContactSSHImpl.java index 339275ddf..b1c21099f 100644 --- a/src/net/java/sip/communicator/impl/protocol/ssh/ContactSSHImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/ssh/ContactSSHImpl.java @@ -710,7 +710,8 @@ public boolean equals(Object obj) public OperationSetPersistentPresence getParentPresenceOperationSet() { - return (OperationSetPersistentPresence)parentProvider + return + parentProvider .getOperationSet(OperationSetPersistentPresence.class); } @@ -724,7 +725,8 @@ public boolean equals(Object obj) public OperationSetBasicInstantMessaging getParentBasicInstantMessagingOperationSet() { - return (OperationSetBasicInstantMessaging)parentProvider + return + parentProvider .getOperationSet(OperationSetBasicInstantMessaging.class); } @@ -738,8 +740,7 @@ public boolean equals(Object obj) public OperationSetFileTransfer getFileTransferOperationSet() { - return (OperationSetFileTransfer)parentProvider - .getOperationSet(OperationSetFileTransfer.class); + return parentProvider.getOperationSet(OperationSetFileTransfer.class); } diff --git a/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetAdHocMultiUserChatYahooImpl.java b/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetAdHocMultiUserChatYahooImpl.java index 88c66f472..a3a5af339 100644 --- a/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetAdHocMultiUserChatYahooImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetAdHocMultiUserChatYahooImpl.java @@ -369,7 +369,6 @@ public void rejectInvitation(AdHocChatRoomInvitation invitation, * @param targetChatRoom the room that invitation refers to * @param inviter the inviter that sent the invitation * @param reason the reason why the inviter sent the invitation - * @param password the password to use when joining the room */ public void fireInvitationEvent(AdHocChatRoom targetChatRoom, String inviter, String reason) diff --git a/src/net/java/sip/communicator/plugin/accountinfo/AccountDetailsPanel.java b/src/net/java/sip/communicator/plugin/accountinfo/AccountDetailsPanel.java index ff419d879..619936a14 100644 --- a/src/net/java/sip/communicator/plugin/accountinfo/AccountDetailsPanel.java +++ b/src/net/java/sip/communicator/plugin/accountinfo/AccountDetailsPanel.java @@ -1,795 +1,796 @@ -/* - * SIP Communicator, 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.accountinfo; - -import java.awt.*; -import java.awt.event.*; -import java.io.*; -import java.text.*; -import java.util.*; - -import javax.imageio.*; -import javax.swing.*; -import javax.swing.event.*; -import javax.swing.filechooser.FileFilter; - -import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.protocol.ServerStoredDetails.*; -import net.java.sip.communicator.util.*; -import net.java.sip.communicator.util.swing.*; - -/** - * The right side panel of AccountDetailsDialog. Shows one tab of a summary of - * contact information for the selected subcontact, and has an extended tab - * listing all of the details. - * - * @author Yana Stamcheva - */ -public class AccountDetailsPanel - extends TransparentPanel -{ - private Logger logger = Logger.getLogger(AccountDetailsPanel.class); - - /** - * The operation set giving access to the server stored account details. - */ - private OperationSetServerStoredAccountInfo accountInfoOpSet; - - /** - * The protocol provider. - */ - private ProtocolProviderService protocolProvider; - - private JTextField firstNameField = new JTextField(); - - private JTextField middleNameField = new JTextField(); - - private JTextField lastNameField = new JTextField(); - - private JTextField genderField = new JTextField(); - - private JTextField ageField = new JTextField(); - - private JTextField birthdayField = new JTextField(); - - private JTextField emailField = new JTextField(); - - private JTextField phoneField = new JTextField(); - - private JLabel avatarLabel = new JLabel(); - - private JButton applyButton - = new JButton(Resources.getString("service.gui.APPLY")); - - private JPanel buttonPanel = - new TransparentPanel(new FlowLayout(FlowLayout.CENTER)); - - private JPanel mainPanel = new TransparentPanel(new BorderLayout()); - - private JScrollPane mainScrollPane = new JScrollPane(); - - private boolean isDataLoaded = false; - - private FirstNameDetail firstNameDetail; - - private MiddleNameDetail middleNameDetail; - - private LastNameDetail lastNameDetail; - - private GenderDetail genderDetail; - - private BirthDateDetail birthDateDetail; - - private EmailAddressDetail emailDetail; - - private PhoneNumberDetail phoneDetail; - - private BinaryDetail avatarDetail; - - private byte[] newAvatarImage; - - /** - * The last avatar file directory open. - */ - private File lastAvatarDir; - - /** - * Construct a panel containing all account details for the given protocol - * provider. - * - * @param protocolProvider the protocol provider service - */ - public AccountDetailsPanel(ProtocolProviderService protocolProvider) - { - super(new BorderLayout()); - - this.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); -// this.setPreferredSize(new Dimension(500, 400)); - - accountInfoOpSet = - (OperationSetServerStoredAccountInfo) protocolProvider - .getOperationSet(OperationSetServerStoredAccountInfo.class); - - this.protocolProvider = protocolProvider; - - if (accountInfoOpSet == null) - { - initUnsupportedPanel(); - } - else - { - this.initSummaryPanel(); - - if (protocolProvider.isRegistered()) - { - loadDetails(); - } - } - } - - private void initSummaryPanel() - { - JPanel summaryPanel = new TransparentPanel(new BorderLayout(10, 10)); - - summaryPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - summaryPanel.setSize(this.getWidth(), this.getHeight()); - - // Create the avatar panel. - JPanel leftPanel = new TransparentPanel(new BorderLayout()); - JPanel avatarPanel = new TransparentPanel(new BorderLayout()); - JButton changeAvatarButton = new JButton(Resources.getString("plugin.accountinfo.CHANGE")); - JPanel changeButtonPanel - = new TransparentPanel(new FlowLayout(FlowLayout.CENTER)); - - changeAvatarButton.addActionListener(new ChangeAvatarActionListener()); - - avatarLabel.setIcon(Resources.getImage("accountInfoDefaultPersonIcon")); - - changeButtonPanel.add(changeAvatarButton); - - avatarPanel.add(avatarLabel, BorderLayout.CENTER); - avatarPanel.add(changeButtonPanel, BorderLayout.SOUTH); - - leftPanel.add(avatarPanel, BorderLayout.NORTH); - - summaryPanel.add(leftPanel, BorderLayout.WEST); - - // Create the summary details panel. - JPanel detailsPanel = new TransparentPanel(new BorderLayout(10, 10)); - detailsPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); - - summaryPanel.add(detailsPanel, BorderLayout.CENTER); - - // Labels panel. - JPanel labelsPanel = new TransparentPanel(new GridLayout(0, 1, 5, 5)); - - labelsPanel.add(new JLabel( - Resources.getString("plugin.accountinfo.FIRST_NAME"))); -// labelsPanel.add(new JLabel(Resources.getString("plugin.accountinfo.MIDDLE_NAME"))); - labelsPanel.add(new JLabel( - Resources.getString("plugin.accountinfo.LAST_NAME"))); - labelsPanel.add(new JLabel( - Resources.getString("plugin.accountinfo.GENDER"))); - labelsPanel.add(new JLabel( - Resources.getString("plugin.accountinfo.AGE"))); - labelsPanel.add(new JLabel( - Resources.getString("plugin.accountinfo.BDAY"))); - labelsPanel.add(new JLabel( - Resources.getString("plugin.accountinfo.EMAIL"))); - labelsPanel.add(new JLabel( - Resources.getString("plugin.accountinfo.PHONE"))); - - detailsPanel.add(labelsPanel, BorderLayout.WEST); - - // Values panel. - JPanel valuesPanel = new TransparentPanel(new GridLayout(0, 1, 5, 5)); - - valuesPanel.add(firstNameField); -// valuesPanel.add(middleNameField); - valuesPanel.add(lastNameField); - valuesPanel.add(genderField); - valuesPanel.add(ageField); - valuesPanel.add(birthdayField); - valuesPanel.add(emailField); - valuesPanel.add(phoneField); - - detailsPanel.add(valuesPanel, BorderLayout.CENTER); - - this.mainScrollPane.getViewport().add(summaryPanel); - - this.add(mainScrollPane, BorderLayout.NORTH); - - this.applyButton.addActionListener(new SubmitActionListener()); - - this.buttonPanel.add(applyButton); - - this.add(buttonPanel, BorderLayout.SOUTH); - } - - /** - * Loads details for - */ - public void loadDetails() - { - this.loadSummaryDetails(); - this.isDataLoaded = true; - } - - /** - * Creates the panel that indicates to the user that the currently selected - * contact does not support server stored contact info. - * - * @return the panel that is added and shows a message that the selected - * sub-contact does not have the operation set for server stored - * contact info supported. - */ - private void initUnsupportedPanel() - { - JTextArea unsupportedTextArea = - new JTextArea(Resources.getString("plugin.accountinfo.NOT_SUPPORTED")); - - unsupportedTextArea.setEditable(false); - unsupportedTextArea.setLineWrap(true); - - JPanel unsupportedPanel = new TransparentPanel(new FlowLayout(FlowLayout.CENTER)); - - unsupportedTextArea.setPreferredSize(new Dimension(200, 200)); - - unsupportedPanel.setBorder( - BorderFactory.createEmptyBorder(50, 20, 50, 20)); - - unsupportedPanel.add(unsupportedTextArea); - - this.add(unsupportedPanel); - } - - /** - * Creates a panel that can be added as the summary tab that displays the - * following details: - - *

- * Avatar(Contact image) - FirstNameDetail - MiddleNameDetail - - * LastNameDetail - BirthdateDetail (and calculate age) - GenderDetail - - * EmailAddressDetail - PhoneNumberDetail. All other details will be* added - * to our list of extended details. - * - * @return the panel that will be added as the summary tab. - */ - private void loadSummaryDetails() - { - Iterator contactDetails; - - // Avatar details. - contactDetails - = accountInfoOpSet.getDetails(BinaryDetail.class); - - byte[] avatarImage = null; - if (contactDetails.hasNext()) - { - avatarDetail = (BinaryDetail) contactDetails.next(); - - avatarImage = avatarDetail.getBytes(); - } - - if (avatarImage != null && avatarImage.length > 0) - avatarLabel.setIcon(new ImageIcon( - getScaledImageInstance(avatarImage))); - - // First name details. - contactDetails = - accountInfoOpSet.getDetails(FirstNameDetail.class); - - String firstNameDetailString = ""; - while (contactDetails.hasNext()) - { - firstNameDetail = (FirstNameDetail) contactDetails.next(); - - firstNameDetailString = - firstNameDetailString + " " + firstNameDetail.getDetailValue(); - } - - firstNameField.setText(firstNameDetailString); - - // Middle name details. - contactDetails = - accountInfoOpSet.getDetails(MiddleNameDetail.class); - - String middleNameDetailString = ""; - while (contactDetails.hasNext()) - { - middleNameDetail = (MiddleNameDetail) contactDetails.next(); - middleNameDetailString = - middleNameDetailString + " " + middleNameDetail.getDetailValue(); - } - - middleNameField.setText(middleNameDetailString); - - // Last name details. - contactDetails = - accountInfoOpSet.getDetails(LastNameDetail.class); - - String lastNameDetailString = ""; - while (contactDetails.hasNext()) - { - lastNameDetail = (LastNameDetail) contactDetails.next(); - - lastNameDetailString = - lastNameDetailString + " " + lastNameDetail.getDetailValue(); - } - - lastNameField.setText(lastNameDetailString); - - // Gender details. - contactDetails = - accountInfoOpSet.getDetails(GenderDetail.class); - - String genderDetailString = ""; - while (contactDetails.hasNext()) - { - genderDetail = (GenderDetail) contactDetails.next(); - genderDetailString = genderDetailString + " " - + genderDetail.getDetailValue(); - } - - genderField.setText(genderDetailString); - - // Birthday details. - contactDetails = - accountInfoOpSet.getDetails(BirthDateDetail.class); - - String birthDateDetailString = ""; - String ageDetail = ""; - if (contactDetails.hasNext()) - { - birthDateDetail = (BirthDateDetail) contactDetails.next(); - - Calendar calendarDetail = - (Calendar) birthDateDetail.getDetailValue(); - - Date birthDate = calendarDetail.getTime(); - DateFormat dateFormat = DateFormat.getDateInstance(); - - birthDateDetailString = dateFormat.format(birthDate).trim(); - - Calendar c = Calendar.getInstance(); - int age = c.get(Calendar.YEAR) - calendarDetail.get(Calendar.YEAR); - - if (c.get(Calendar.MONTH) < calendarDetail.get(Calendar.MONTH)) - age--; - - ageDetail = Integer.toString(age).trim(); - } - - birthdayField.setText(birthDateDetailString); - ageField.setText(ageDetail); - - // Email details. - contactDetails = - accountInfoOpSet.getDetails(EmailAddressDetail.class); - - String emailDetailString = ""; - while (contactDetails.hasNext()) - { - emailDetail = (EmailAddressDetail) contactDetails.next(); - emailDetailString = emailDetailString + " " - + emailDetail.getDetailValue(); - } - - emailField.setText(emailDetailString); - - // Phone number details. - contactDetails = - accountInfoOpSet.getDetails(PhoneNumberDetail.class); - - String phoneNumberDetailString = ""; - while (contactDetails.hasNext()) - { - phoneDetail = (PhoneNumberDetail) contactDetails.next(); - phoneNumberDetailString = - phoneNumberDetailString + " " + phoneDetail.getDetailValue(); - } - - phoneField.setText(phoneNumberDetailString); - } - - /** - * A panel that displays all of the details retrieved from the opSet. - */ - private void initExtendedPanel() - { - JPanel mainExtendedPanel = new TransparentPanel(new BorderLayout()); - - JPanel extendedPanel = new TransparentPanel(); - extendedPanel.setLayout(new BoxLayout(extendedPanel, BoxLayout.Y_AXIS)); - - JPanel imagePanel = new TransparentPanel(); - - // The imagePanel will be used for any BinaryDetails and will be added at - // the bottom so we don't disrupt the standard look of the other details - imagePanel.setLayout(new BoxLayout(imagePanel, BoxLayout.LINE_AXIS)); - imagePanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory - .createTitledBorder(Resources.getString("plugin.accountinfo.USER_PICTURES")), - BorderFactory.createEmptyBorder(0, 5, 5, 5))); - - // Obtain all the details for a contact. - Iterator iter = accountInfoOpSet.getAllAvailableDetails(); - - GenericDetail detail; - JLabel detailLabel; - JTextArea detailValueArea; - JPanel detailPanel; - - while (iter.hasNext()) - { - detail = iter.next(); - - if (detail.getDetailValue().toString().equals("")) - continue; - - detailLabel = new JLabel(); - detailValueArea = new JTextArea(); - detailPanel = new TransparentPanel(new BorderLayout(10, 10)); - - detailValueArea.setAlignmentX(JTextArea.CENTER_ALIGNMENT); - detailValueArea.setLineWrap(true); - detailValueArea.setEditable(true); - - detailPanel.add(detailLabel, BorderLayout.WEST); - detailPanel.add(detailValueArea, BorderLayout.CENTER); - detailPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - - extendedPanel.add(detailPanel); - - if (detail instanceof BinaryDetail) - { - JLabel imageLabel = - new JLabel(new ImageIcon((byte[]) detail - .getDetailValue())); - - imagePanel.add(imageLabel); - } - else if (detail instanceof CalendarDetail) - { - detailLabel.setText(detail.getDetailDisplayName() + ": "); - - Date detailDate = - ((Calendar) detail.getDetailValue()).getTime(); - DateFormat df = DateFormat.getDateInstance(); - - detailValueArea.setText(df.format(detailDate).trim()); - } - else if (detail instanceof LocaleDetail) - { - detailLabel.setText(detail.getDetailDisplayName() + ": "); - - detailValueArea.setText(((Locale) detail.getDetailValue()) - .getDisplayName().trim()); - } - else if (detail instanceof TimeZoneDetail) - { - detailLabel.setText(detail.getDetailDisplayName() + ": "); - - detailValueArea.setText(((TimeZone) detail.getDetailValue()) - .getDisplayName().trim()); - } - else - { - detailLabel.setText(detail.getDetailDisplayName() + ": "); - - detailValueArea.setText( - detail.getDetailValue().toString().trim()); - } - } - - // If the contact's protocol supports web info, give them a button to - // get it - if (protocolProvider.getOperationSet( - OperationSetWebContactInfo.class) != null) - { - final String urlString - = ((OperationSetWebContactInfo) protocolProvider - .getOperationSet(OperationSetWebContactInfo.class)) - .getWebContactInfo( - protocolProvider.getAccountID().getAccountAddress()) - .toString(); - - JLabel webInfoLabel = new JLabel("Click to see web info: "); - JEditorPane webInfoValue = new JEditorPane(); - JPanel webInfoPanel = new TransparentPanel(new BorderLayout()); - - webInfoPanel.add(webInfoLabel, BorderLayout.WEST); - webInfoPanel.add(webInfoValue, BorderLayout.CENTER); - - extendedPanel.add(webInfoPanel); - - webInfoValue.setOpaque(false); - webInfoValue.setContentType("text/html"); - webInfoValue.setEditable(false); - webInfoValue.setText( "" - + protocolProvider.getAccountID().getUserID() - + " web info"); - - webInfoValue.addHyperlinkListener(new HyperlinkListener() - { - public void hyperlinkUpdate(HyperlinkEvent e) - { - if (e.getEventType() - .equals(HyperlinkEvent.EventType.ACTIVATED)) - { - AccountInfoActivator - .getBrowserLauncher().openURL(urlString); - } - } - }); - } - - if (imagePanel.getComponentCount() > 0) - mainExtendedPanel.add(imagePanel, BorderLayout.CENTER); - - mainExtendedPanel.add(extendedPanel, BorderLayout.NORTH); - - this.mainPanel.add(mainExtendedPanel); - - this.mainPanel.revalidate(); - this.mainPanel.repaint(); - } - - private class SubmitActionListener implements ActionListener - { - public void actionPerformed(ActionEvent e) - { - String firstName = firstNameField.getText(); -// String middleName = middleNameField.getText(); - String lastName = lastNameField.getText(); - String gender = genderField.getText(); - String email = emailField.getText(); - String phoneNumber = phoneField.getText(); - - Calendar birthDateCalendar = Calendar.getInstance(); - - if(birthdayField.getText() != null - && birthdayField.getText().length() > 0) - { - try - { - DateFormat dateFormat - = DateFormat.getDateInstance(DateFormat.DEFAULT); - - Date birthDate = dateFormat.parse(birthdayField.getText()); - - birthDateCalendar.setTime(birthDate); - } - catch (ParseException e2) - { - logger.error("Failed to parse birth date.", e2); - } - } - - try - { - FirstNameDetail newFirstNameDetail - = new ServerStoredDetails.FirstNameDetail(firstName); - - if (firstNameDetail == null) - accountInfoOpSet.addDetail(newFirstNameDetail); - else - accountInfoOpSet.replaceDetail( firstNameDetail, - newFirstNameDetail); - -// MiddleNameDetail newMiddleNameDetail -// = new ServerStoredDetails.MiddleNameDetail(middleName); -// -// if (middleNameDetail == null) -// accountInfoOpSet.addDetail(newMiddleNameDetail); -// else -// accountInfoOpSet.replaceDetail( middleNameDetail, -// newMiddleNameDetail); - - LastNameDetail newLastNameDetail - = new ServerStoredDetails.LastNameDetail(lastName); - - if (lastNameDetail == null) - accountInfoOpSet.addDetail(newLastNameDetail); - else - accountInfoOpSet.replaceDetail( lastNameDetail, - newLastNameDetail); - - GenderDetail newGenderDetail - = new ServerStoredDetails.GenderDetail(gender); - - if (genderDetail == null) - accountInfoOpSet.addDetail(newGenderDetail); - else - accountInfoOpSet.replaceDetail( genderDetail, - newGenderDetail); - - BirthDateDetail newBirthDateDetail - = new ServerStoredDetails.BirthDateDetail(birthDateCalendar); - - if (birthDateDetail == null) - accountInfoOpSet.addDetail(newBirthDateDetail); - else - accountInfoOpSet.replaceDetail( birthDateDetail, - newBirthDateDetail); - - EmailAddressDetail newEmailDetail - = new ServerStoredDetails.EmailAddressDetail(email); - - if (emailDetail == null) - accountInfoOpSet.addDetail(newEmailDetail); - else - accountInfoOpSet.replaceDetail( emailDetail, - newEmailDetail); - - PhoneNumberDetail newPhoneDetail - = new ServerStoredDetails.PhoneNumberDetail(phoneNumber); - - if (phoneDetail == null) - accountInfoOpSet.addDetail(newPhoneDetail); - else - accountInfoOpSet.replaceDetail( phoneDetail, - newPhoneDetail); - - BinaryDetail newAvatarDetail - = new ServerStoredDetails.BinaryDetail( - "Avatar", - newAvatarImage); - - if (avatarDetail == null) - accountInfoOpSet.addDetail(newAvatarDetail); - else - accountInfoOpSet.replaceDetail( avatarDetail, - newAvatarDetail); - } - catch (ClassCastException e1) - { - logger.error("Failed to update account details.", e1); - } - catch (OperationFailedException e1) - { - logger.error("Failed to update account details.", e1); - } - } - } - - private class ChangeAvatarActionListener implements ActionListener - { - public void actionPerformed(ActionEvent e) - { - JFileChooser chooser = new JFileChooser(lastAvatarDir); - - chooser.addChoosableFileFilter(new ImageFilter()); - - int returnVal = chooser.showOpenDialog(null); - - if (returnVal == JFileChooser.APPROVE_OPTION) - { - try - { - File file = chooser.getSelectedFile(); - lastAvatarDir = file.getParentFile(); - - FileInputStream in = new FileInputStream(file); - byte buffer[] = new byte[in.available()]; - in.read(buffer); - - if (buffer == null || buffer.length <= 0) - return; - - newAvatarImage = buffer; - - avatarLabel.setIcon(new ImageIcon( - getScaledImageInstance(newAvatarImage))); - } - catch (IOException ex) - { - logger.error("Failed to load image.", ex); - } - } - } - } - - /** - * A custom filter that would accept only image files. - */ - private static class ImageFilter extends FileFilter - { - /** - * Accept all directories and all gif, jpg, tiff, or png files. - */ - public boolean accept(File f) - { - if (f.isDirectory()) - { - return true; - } - - String extension = getExtension(f); - if (extension != null) - { - if (extension.equals("tiff") || - extension.equals("tif") || - extension.equals("gif") || - extension.equals("jpeg") || - extension.equals("jpg") || - extension.equals("png")) - { - return true; - } - else - { - return false; - } - } - - return false; - } - - /** - * Get the extension of a file. - */ - public String getExtension(File f) - { - String ext = null; - String s = f.getName(); - int i = s.lastIndexOf('.'); - - if (i > 0 && i < s.length() - 1) { - ext = s.substring(i+1).toLowerCase(); - } - return ext; - } - - /** - * The description of this filter. - */ - public String getDescription() - { - return Resources.getString("plugin.accountinfo.ONLY_MESSAGE"); - } - } - - /** - * Returns a scaled Image instance of the given byte image. - * - * @param image the image in bytes - * @return a scaled Image instance of the given byte image. - */ - private Image getScaledImageInstance(byte[] image) - { - Image resultImage = null; - - try - { - resultImage = ImageIO.read( - new ByteArrayInputStream(image)); - } - catch (Exception e) - { - logger.error("Failed to convert bytes to image.", e); - } - - if(resultImage == null) - return null; - - return resultImage.getScaledInstance( - avatarLabel.getWidth(), - avatarLabel.getHeight(), - Image.SCALE_SMOOTH); - } - - /** - * Returns true if the account details are loaded, - * false - otherwise. - * - * @return true if the account details are loaded, - * false - otherwise - */ - public boolean isDataLoaded() - { - return isDataLoaded; - } -} +/* + * SIP Communicator, 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.accountinfo; + +import java.awt.*; +import java.awt.event.*; +import java.io.*; +import java.text.*; +import java.util.*; + +import javax.imageio.*; +import javax.swing.*; +import javax.swing.event.*; +import javax.swing.filechooser.FileFilter; + +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.service.protocol.ServerStoredDetails.*; +import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.swing.*; + +/** + * The right side panel of AccountDetailsDialog. Shows one tab of a summary of + * contact information for the selected subcontact, and has an extended tab + * listing all of the details. + * + * @author Yana Stamcheva + */ +public class AccountDetailsPanel + extends TransparentPanel +{ + private Logger logger = Logger.getLogger(AccountDetailsPanel.class); + + /** + * The operation set giving access to the server stored account details. + */ + private OperationSetServerStoredAccountInfo accountInfoOpSet; + + /** + * The protocol provider. + */ + private ProtocolProviderService protocolProvider; + + private JTextField firstNameField = new JTextField(); + + private JTextField middleNameField = new JTextField(); + + private JTextField lastNameField = new JTextField(); + + private JTextField genderField = new JTextField(); + + private JTextField ageField = new JTextField(); + + private JTextField birthdayField = new JTextField(); + + private JTextField emailField = new JTextField(); + + private JTextField phoneField = new JTextField(); + + private JLabel avatarLabel = new JLabel(); + + private JButton applyButton + = new JButton(Resources.getString("service.gui.APPLY")); + + private JPanel buttonPanel = + new TransparentPanel(new FlowLayout(FlowLayout.CENTER)); + + private JPanel mainPanel = new TransparentPanel(new BorderLayout()); + + private JScrollPane mainScrollPane = new JScrollPane(); + + private boolean isDataLoaded = false; + + private FirstNameDetail firstNameDetail; + + private MiddleNameDetail middleNameDetail; + + private LastNameDetail lastNameDetail; + + private GenderDetail genderDetail; + + private BirthDateDetail birthDateDetail; + + private EmailAddressDetail emailDetail; + + private PhoneNumberDetail phoneDetail; + + private BinaryDetail avatarDetail; + + private byte[] newAvatarImage; + + /** + * The last avatar file directory open. + */ + private File lastAvatarDir; + + /** + * Construct a panel containing all account details for the given protocol + * provider. + * + * @param protocolProvider the protocol provider service + */ + public AccountDetailsPanel(ProtocolProviderService protocolProvider) + { + super(new BorderLayout()); + + this.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); +// this.setPreferredSize(new Dimension(500, 400)); + + accountInfoOpSet + = protocolProvider + .getOperationSet(OperationSetServerStoredAccountInfo.class); + + this.protocolProvider = protocolProvider; + + if (accountInfoOpSet == null) + { + initUnsupportedPanel(); + } + else + { + this.initSummaryPanel(); + + if (protocolProvider.isRegistered()) + { + loadDetails(); + } + } + } + + private void initSummaryPanel() + { + JPanel summaryPanel = new TransparentPanel(new BorderLayout(10, 10)); + + summaryPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + summaryPanel.setSize(this.getWidth(), this.getHeight()); + + // Create the avatar panel. + JPanel leftPanel = new TransparentPanel(new BorderLayout()); + JPanel avatarPanel = new TransparentPanel(new BorderLayout()); + JButton changeAvatarButton = new JButton(Resources.getString("plugin.accountinfo.CHANGE")); + JPanel changeButtonPanel + = new TransparentPanel(new FlowLayout(FlowLayout.CENTER)); + + changeAvatarButton.addActionListener(new ChangeAvatarActionListener()); + + avatarLabel.setIcon(Resources.getImage("accountInfoDefaultPersonIcon")); + + changeButtonPanel.add(changeAvatarButton); + + avatarPanel.add(avatarLabel, BorderLayout.CENTER); + avatarPanel.add(changeButtonPanel, BorderLayout.SOUTH); + + leftPanel.add(avatarPanel, BorderLayout.NORTH); + + summaryPanel.add(leftPanel, BorderLayout.WEST); + + // Create the summary details panel. + JPanel detailsPanel = new TransparentPanel(new BorderLayout(10, 10)); + detailsPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + + summaryPanel.add(detailsPanel, BorderLayout.CENTER); + + // Labels panel. + JPanel labelsPanel = new TransparentPanel(new GridLayout(0, 1, 5, 5)); + + labelsPanel.add(new JLabel( + Resources.getString("plugin.accountinfo.FIRST_NAME"))); +// labelsPanel.add(new JLabel(Resources.getString("plugin.accountinfo.MIDDLE_NAME"))); + labelsPanel.add(new JLabel( + Resources.getString("plugin.accountinfo.LAST_NAME"))); + labelsPanel.add(new JLabel( + Resources.getString("plugin.accountinfo.GENDER"))); + labelsPanel.add(new JLabel( + Resources.getString("plugin.accountinfo.AGE"))); + labelsPanel.add(new JLabel( + Resources.getString("plugin.accountinfo.BDAY"))); + labelsPanel.add(new JLabel( + Resources.getString("plugin.accountinfo.EMAIL"))); + labelsPanel.add(new JLabel( + Resources.getString("plugin.accountinfo.PHONE"))); + + detailsPanel.add(labelsPanel, BorderLayout.WEST); + + // Values panel. + JPanel valuesPanel = new TransparentPanel(new GridLayout(0, 1, 5, 5)); + + valuesPanel.add(firstNameField); +// valuesPanel.add(middleNameField); + valuesPanel.add(lastNameField); + valuesPanel.add(genderField); + valuesPanel.add(ageField); + valuesPanel.add(birthdayField); + valuesPanel.add(emailField); + valuesPanel.add(phoneField); + + detailsPanel.add(valuesPanel, BorderLayout.CENTER); + + this.mainScrollPane.getViewport().add(summaryPanel); + + this.add(mainScrollPane, BorderLayout.NORTH); + + this.applyButton.addActionListener(new SubmitActionListener()); + + this.buttonPanel.add(applyButton); + + this.add(buttonPanel, BorderLayout.SOUTH); + } + + /** + * Loads details for + */ + public void loadDetails() + { + this.loadSummaryDetails(); + this.isDataLoaded = true; + } + + /** + * Creates the panel that indicates to the user that the currently selected + * contact does not support server stored contact info. + * + * @return the panel that is added and shows a message that the selected + * sub-contact does not have the operation set for server stored + * contact info supported. + */ + private void initUnsupportedPanel() + { + JTextArea unsupportedTextArea = + new JTextArea(Resources.getString("plugin.accountinfo.NOT_SUPPORTED")); + + unsupportedTextArea.setEditable(false); + unsupportedTextArea.setLineWrap(true); + + JPanel unsupportedPanel = new TransparentPanel(new FlowLayout(FlowLayout.CENTER)); + + unsupportedTextArea.setPreferredSize(new Dimension(200, 200)); + + unsupportedPanel.setBorder( + BorderFactory.createEmptyBorder(50, 20, 50, 20)); + + unsupportedPanel.add(unsupportedTextArea); + + this.add(unsupportedPanel); + } + + /** + * Creates a panel that can be added as the summary tab that displays the + * following details: - + *

+ * Avatar(Contact image) - FirstNameDetail - MiddleNameDetail - + * LastNameDetail - BirthdateDetail (and calculate age) - GenderDetail - + * EmailAddressDetail - PhoneNumberDetail. All other details will be* added + * to our list of extended details. + * + * @return the panel that will be added as the summary tab. + */ + private void loadSummaryDetails() + { + Iterator contactDetails; + + // Avatar details. + contactDetails + = accountInfoOpSet.getDetails(BinaryDetail.class); + + byte[] avatarImage = null; + if (contactDetails.hasNext()) + { + avatarDetail = (BinaryDetail) contactDetails.next(); + + avatarImage = avatarDetail.getBytes(); + } + + if (avatarImage != null && avatarImage.length > 0) + avatarLabel.setIcon(new ImageIcon( + getScaledImageInstance(avatarImage))); + + // First name details. + contactDetails = + accountInfoOpSet.getDetails(FirstNameDetail.class); + + String firstNameDetailString = ""; + while (contactDetails.hasNext()) + { + firstNameDetail = (FirstNameDetail) contactDetails.next(); + + firstNameDetailString = + firstNameDetailString + " " + firstNameDetail.getDetailValue(); + } + + firstNameField.setText(firstNameDetailString); + + // Middle name details. + contactDetails = + accountInfoOpSet.getDetails(MiddleNameDetail.class); + + String middleNameDetailString = ""; + while (contactDetails.hasNext()) + { + middleNameDetail = (MiddleNameDetail) contactDetails.next(); + middleNameDetailString = + middleNameDetailString + " " + middleNameDetail.getDetailValue(); + } + + middleNameField.setText(middleNameDetailString); + + // Last name details. + contactDetails = + accountInfoOpSet.getDetails(LastNameDetail.class); + + String lastNameDetailString = ""; + while (contactDetails.hasNext()) + { + lastNameDetail = (LastNameDetail) contactDetails.next(); + + lastNameDetailString = + lastNameDetailString + " " + lastNameDetail.getDetailValue(); + } + + lastNameField.setText(lastNameDetailString); + + // Gender details. + contactDetails = + accountInfoOpSet.getDetails(GenderDetail.class); + + String genderDetailString = ""; + while (contactDetails.hasNext()) + { + genderDetail = (GenderDetail) contactDetails.next(); + genderDetailString = genderDetailString + " " + + genderDetail.getDetailValue(); + } + + genderField.setText(genderDetailString); + + // Birthday details. + contactDetails = + accountInfoOpSet.getDetails(BirthDateDetail.class); + + String birthDateDetailString = ""; + String ageDetail = ""; + if (contactDetails.hasNext()) + { + birthDateDetail = (BirthDateDetail) contactDetails.next(); + + Calendar calendarDetail = + (Calendar) birthDateDetail.getDetailValue(); + + Date birthDate = calendarDetail.getTime(); + DateFormat dateFormat = DateFormat.getDateInstance(); + + birthDateDetailString = dateFormat.format(birthDate).trim(); + + Calendar c = Calendar.getInstance(); + int age = c.get(Calendar.YEAR) - calendarDetail.get(Calendar.YEAR); + + if (c.get(Calendar.MONTH) < calendarDetail.get(Calendar.MONTH)) + age--; + + ageDetail = Integer.toString(age).trim(); + } + + birthdayField.setText(birthDateDetailString); + ageField.setText(ageDetail); + + // Email details. + contactDetails = + accountInfoOpSet.getDetails(EmailAddressDetail.class); + + String emailDetailString = ""; + while (contactDetails.hasNext()) + { + emailDetail = (EmailAddressDetail) contactDetails.next(); + emailDetailString = emailDetailString + " " + + emailDetail.getDetailValue(); + } + + emailField.setText(emailDetailString); + + // Phone number details. + contactDetails = + accountInfoOpSet.getDetails(PhoneNumberDetail.class); + + String phoneNumberDetailString = ""; + while (contactDetails.hasNext()) + { + phoneDetail = (PhoneNumberDetail) contactDetails.next(); + phoneNumberDetailString = + phoneNumberDetailString + " " + phoneDetail.getDetailValue(); + } + + phoneField.setText(phoneNumberDetailString); + } + + /** + * A panel that displays all of the details retrieved from the opSet. + */ + private void initExtendedPanel() + { + JPanel mainExtendedPanel = new TransparentPanel(new BorderLayout()); + + JPanel extendedPanel = new TransparentPanel(); + extendedPanel.setLayout(new BoxLayout(extendedPanel, BoxLayout.Y_AXIS)); + + JPanel imagePanel = new TransparentPanel(); + + // The imagePanel will be used for any BinaryDetails and will be added at + // the bottom so we don't disrupt the standard look of the other details + imagePanel.setLayout(new BoxLayout(imagePanel, BoxLayout.LINE_AXIS)); + imagePanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory + .createTitledBorder(Resources.getString("plugin.accountinfo.USER_PICTURES")), + BorderFactory.createEmptyBorder(0, 5, 5, 5))); + + // Obtain all the details for a contact. + Iterator iter = accountInfoOpSet.getAllAvailableDetails(); + + GenericDetail detail; + JLabel detailLabel; + JTextArea detailValueArea; + JPanel detailPanel; + + while (iter.hasNext()) + { + detail = iter.next(); + + if (detail.getDetailValue().toString().equals("")) + continue; + + detailLabel = new JLabel(); + detailValueArea = new JTextArea(); + detailPanel = new TransparentPanel(new BorderLayout(10, 10)); + + detailValueArea.setAlignmentX(JTextArea.CENTER_ALIGNMENT); + detailValueArea.setLineWrap(true); + detailValueArea.setEditable(true); + + detailPanel.add(detailLabel, BorderLayout.WEST); + detailPanel.add(detailValueArea, BorderLayout.CENTER); + detailPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + + extendedPanel.add(detailPanel); + + if (detail instanceof BinaryDetail) + { + JLabel imageLabel = + new JLabel(new ImageIcon((byte[]) detail + .getDetailValue())); + + imagePanel.add(imageLabel); + } + else if (detail instanceof CalendarDetail) + { + detailLabel.setText(detail.getDetailDisplayName() + ": "); + + Date detailDate = + ((Calendar) detail.getDetailValue()).getTime(); + DateFormat df = DateFormat.getDateInstance(); + + detailValueArea.setText(df.format(detailDate).trim()); + } + else if (detail instanceof LocaleDetail) + { + detailLabel.setText(detail.getDetailDisplayName() + ": "); + + detailValueArea.setText(((Locale) detail.getDetailValue()) + .getDisplayName().trim()); + } + else if (detail instanceof TimeZoneDetail) + { + detailLabel.setText(detail.getDetailDisplayName() + ": "); + + detailValueArea.setText(((TimeZone) detail.getDetailValue()) + .getDisplayName().trim()); + } + else + { + detailLabel.setText(detail.getDetailDisplayName() + ": "); + + detailValueArea.setText( + detail.getDetailValue().toString().trim()); + } + } + + // If the contact's protocol supports web info, give them a button to + // get it + if (protocolProvider.getOperationSet( + OperationSetWebContactInfo.class) != null) + { + final String urlString + = protocolProvider + .getOperationSet(OperationSetWebContactInfo.class) + .getWebContactInfo( + protocolProvider + .getAccountID().getAccountAddress()) + .toString(); + + JLabel webInfoLabel = new JLabel("Click to see web info: "); + JEditorPane webInfoValue = new JEditorPane(); + JPanel webInfoPanel = new TransparentPanel(new BorderLayout()); + + webInfoPanel.add(webInfoLabel, BorderLayout.WEST); + webInfoPanel.add(webInfoValue, BorderLayout.CENTER); + + extendedPanel.add(webInfoPanel); + + webInfoValue.setOpaque(false); + webInfoValue.setContentType("text/html"); + webInfoValue.setEditable(false); + webInfoValue.setText( "" + + protocolProvider.getAccountID().getUserID() + + " web info"); + + webInfoValue.addHyperlinkListener(new HyperlinkListener() + { + public void hyperlinkUpdate(HyperlinkEvent e) + { + if (e.getEventType() + .equals(HyperlinkEvent.EventType.ACTIVATED)) + { + AccountInfoActivator + .getBrowserLauncher().openURL(urlString); + } + } + }); + } + + if (imagePanel.getComponentCount() > 0) + mainExtendedPanel.add(imagePanel, BorderLayout.CENTER); + + mainExtendedPanel.add(extendedPanel, BorderLayout.NORTH); + + this.mainPanel.add(mainExtendedPanel); + + this.mainPanel.revalidate(); + this.mainPanel.repaint(); + } + + private class SubmitActionListener implements ActionListener + { + public void actionPerformed(ActionEvent e) + { + String firstName = firstNameField.getText(); +// String middleName = middleNameField.getText(); + String lastName = lastNameField.getText(); + String gender = genderField.getText(); + String email = emailField.getText(); + String phoneNumber = phoneField.getText(); + + Calendar birthDateCalendar = Calendar.getInstance(); + + if(birthdayField.getText() != null + && birthdayField.getText().length() > 0) + { + try + { + DateFormat dateFormat + = DateFormat.getDateInstance(DateFormat.DEFAULT); + + Date birthDate = dateFormat.parse(birthdayField.getText()); + + birthDateCalendar.setTime(birthDate); + } + catch (ParseException e2) + { + logger.error("Failed to parse birth date.", e2); + } + } + + try + { + FirstNameDetail newFirstNameDetail + = new ServerStoredDetails.FirstNameDetail(firstName); + + if (firstNameDetail == null) + accountInfoOpSet.addDetail(newFirstNameDetail); + else + accountInfoOpSet.replaceDetail( firstNameDetail, + newFirstNameDetail); + +// MiddleNameDetail newMiddleNameDetail +// = new ServerStoredDetails.MiddleNameDetail(middleName); +// +// if (middleNameDetail == null) +// accountInfoOpSet.addDetail(newMiddleNameDetail); +// else +// accountInfoOpSet.replaceDetail( middleNameDetail, +// newMiddleNameDetail); + + LastNameDetail newLastNameDetail + = new ServerStoredDetails.LastNameDetail(lastName); + + if (lastNameDetail == null) + accountInfoOpSet.addDetail(newLastNameDetail); + else + accountInfoOpSet.replaceDetail( lastNameDetail, + newLastNameDetail); + + GenderDetail newGenderDetail + = new ServerStoredDetails.GenderDetail(gender); + + if (genderDetail == null) + accountInfoOpSet.addDetail(newGenderDetail); + else + accountInfoOpSet.replaceDetail( genderDetail, + newGenderDetail); + + BirthDateDetail newBirthDateDetail + = new ServerStoredDetails.BirthDateDetail(birthDateCalendar); + + if (birthDateDetail == null) + accountInfoOpSet.addDetail(newBirthDateDetail); + else + accountInfoOpSet.replaceDetail( birthDateDetail, + newBirthDateDetail); + + EmailAddressDetail newEmailDetail + = new ServerStoredDetails.EmailAddressDetail(email); + + if (emailDetail == null) + accountInfoOpSet.addDetail(newEmailDetail); + else + accountInfoOpSet.replaceDetail( emailDetail, + newEmailDetail); + + PhoneNumberDetail newPhoneDetail + = new ServerStoredDetails.PhoneNumberDetail(phoneNumber); + + if (phoneDetail == null) + accountInfoOpSet.addDetail(newPhoneDetail); + else + accountInfoOpSet.replaceDetail( phoneDetail, + newPhoneDetail); + + BinaryDetail newAvatarDetail + = new ServerStoredDetails.BinaryDetail( + "Avatar", + newAvatarImage); + + if (avatarDetail == null) + accountInfoOpSet.addDetail(newAvatarDetail); + else + accountInfoOpSet.replaceDetail( avatarDetail, + newAvatarDetail); + } + catch (ClassCastException e1) + { + logger.error("Failed to update account details.", e1); + } + catch (OperationFailedException e1) + { + logger.error("Failed to update account details.", e1); + } + } + } + + private class ChangeAvatarActionListener implements ActionListener + { + public void actionPerformed(ActionEvent e) + { + JFileChooser chooser = new JFileChooser(lastAvatarDir); + + chooser.addChoosableFileFilter(new ImageFilter()); + + int returnVal = chooser.showOpenDialog(null); + + if (returnVal == JFileChooser.APPROVE_OPTION) + { + try + { + File file = chooser.getSelectedFile(); + lastAvatarDir = file.getParentFile(); + + FileInputStream in = new FileInputStream(file); + byte buffer[] = new byte[in.available()]; + in.read(buffer); + + if (buffer == null || buffer.length <= 0) + return; + + newAvatarImage = buffer; + + avatarLabel.setIcon(new ImageIcon( + getScaledImageInstance(newAvatarImage))); + } + catch (IOException ex) + { + logger.error("Failed to load image.", ex); + } + } + } + } + + /** + * A custom filter that would accept only image files. + */ + private static class ImageFilter extends FileFilter + { + /** + * Accept all directories and all gif, jpg, tiff, or png files. + */ + public boolean accept(File f) + { + if (f.isDirectory()) + { + return true; + } + + String extension = getExtension(f); + if (extension != null) + { + if (extension.equals("tiff") || + extension.equals("tif") || + extension.equals("gif") || + extension.equals("jpeg") || + extension.equals("jpg") || + extension.equals("png")) + { + return true; + } + else + { + return false; + } + } + + return false; + } + + /** + * Get the extension of a file. + */ + public String getExtension(File f) + { + String ext = null; + String s = f.getName(); + int i = s.lastIndexOf('.'); + + if (i > 0 && i < s.length() - 1) { + ext = s.substring(i+1).toLowerCase(); + } + return ext; + } + + /** + * The description of this filter. + */ + public String getDescription() + { + return Resources.getString("plugin.accountinfo.ONLY_MESSAGE"); + } + } + + /** + * Returns a scaled Image instance of the given byte image. + * + * @param image the image in bytes + * @return a scaled Image instance of the given byte image. + */ + private Image getScaledImageInstance(byte[] image) + { + Image resultImage = null; + + try + { + resultImage = ImageIO.read( + new ByteArrayInputStream(image)); + } + catch (Exception e) + { + logger.error("Failed to convert bytes to image.", e); + } + + if(resultImage == null) + return null; + + return resultImage.getScaledInstance( + avatarLabel.getWidth(), + avatarLabel.getHeight(), + Image.SCALE_SMOOTH); + } + + /** + * Returns true if the account details are loaded, + * false - otherwise. + * + * @return true if the account details are loaded, + * false - otherwise + */ + public boolean isDataLoaded() + { + return isDataLoaded; + } +} diff --git a/src/net/java/sip/communicator/plugin/autoaway/StatusUpdateThread.java b/src/net/java/sip/communicator/plugin/autoaway/StatusUpdateThread.java index 4a93063d3..e6cde92d9 100644 --- a/src/net/java/sip/communicator/plugin/autoaway/StatusUpdateThread.java +++ b/src/net/java/sip/communicator/plugin/autoaway/StatusUpdateThread.java @@ -1,194 +1,192 @@ -/* - * SIP Communicator, 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.autoaway; - -import java.awt.*; -import java.util.*; - -import net.java.sip.communicator.service.configuration.*; -import net.java.sip.communicator.service.protocol.*; - -/** - * A Runnable, which permanently looks at the mouse position. If the mouse is - * not moved, all accounts are set to "Away" or similar states. - * - * @author Thomas Hofer - */ -public class StatusUpdateThread - implements Runnable -{ - private boolean run = false; - private Point lastPosition = null; - private final Map lastStates - = new HashMap(); - - private static final int IDLE_TIMER = 3000; - private static final int AWAY_DEFAULT_STATUS = 40; - - public void run() - { - run = true; - int timer = 0; - do - { - try - { - if (MouseInfo.getPointerInfo() != null) - { - PointerInfo info = MouseInfo.getPointerInfo(); - Point currentPosition - = (info != null) ? info.getLocation() : new Point(0, 0); - - if (!isNear(lastPosition, currentPosition)) - { - // position has changed - // check, if a minor state has been automatically set - // and - // reset this state to the former state. - for (ProtocolProviderService protocolProviderService - : AutoAwayActivator.getProtocolProviders()) - { - if (lastStates.get(protocolProviderService) != null) - { - PresenceStatus lastState - = lastStates.get(protocolProviderService); - OperationSetPresence presence - = (OperationSetPresence) - protocolProviderService - .getOperationSet( - OperationSetPresence.class); - try - { - presence - .publishPresenceStatus(lastState, ""); - } catch (IllegalArgumentException e) - { - } catch (IllegalStateException e) - { - } catch (OperationFailedException e) - { - } - lastStates.remove(protocolProviderService); - } - } - timer = getTimer() * 1000 * 60; - } else - { - // position has not changed! - // get all protocols and set them to away - for (ProtocolProviderService protocolProviderService - : AutoAwayActivator.getProtocolProviders()) - { - OperationSetPresence presence - = (OperationSetPresence) - protocolProviderService - .getOperationSet( - OperationSetPresence.class); - - PresenceStatus status = presence - .getPresenceStatus(); - - if (status.getStatus() - < PresenceStatus.AVAILABLE_THRESHOLD) - { - // already (manually) set to away or lower - continue; - } - - lastStates.put(protocolProviderService, status); - - PresenceStatus newStatus = findAwayStatus(presence); - - try - { - if (newStatus != null) - presence - .publishPresenceStatus( - newStatus, - newStatus.getStatusName()); - } catch (IllegalArgumentException e) - { - } catch (IllegalStateException e) - { - } catch (OperationFailedException e) - { - } - } - - timer = IDLE_TIMER; - } - lastPosition = currentPosition; - } - Thread.sleep(timer); - } catch (InterruptedException e) - { - } - } while (run && timer > 0); - } - - public void stop() - { - run = false; - } - - /** - * Finds the Away-Status of the protocols - * - * @param presence - * @return - */ - private PresenceStatus findAwayStatus(OperationSetPresence presence) - { - Iterator statusSet = presence.getSupportedStatusSet(); - PresenceStatus status = null; - - while (statusSet.hasNext()) - { - PresenceStatus possibleState = statusSet.next(); - int possibleStatus = possibleState.getStatus(); - - if ((possibleStatus < PresenceStatus.AVAILABLE_THRESHOLD) - && (possibleStatus >= PresenceStatus.ONLINE_THRESHOLD)) - { - if (status == null - || (Math.abs(possibleStatus - AWAY_DEFAULT_STATUS) - < Math.abs( - status.getStatus() - - AWAY_DEFAULT_STATUS))) - { - status = possibleState; - } - } - } - return status; - } - - private int getTimer() - { - ConfigurationService configService - = AutoAwayActivator.getConfigService(); - - return - configService.getBoolean(Preferences.ENABLE, false) - ? configService.getInt(Preferences.TIMER, 0) - : 0; - } - - public boolean isRunning() - { - return run; - } - - private boolean isNear(Point p1, Point p2) - { - return - (p1 != null) - && (p2 != null) - && (Math.abs(p1.x - p2.x) <= 10) - && (Math.abs(p1.y - p2.y) <= 10); - } -} +/* + * SIP Communicator, 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.autoaway; + +import java.awt.*; +import java.util.*; + +import net.java.sip.communicator.service.configuration.*; +import net.java.sip.communicator.service.protocol.*; + +/** + * A Runnable, which permanently looks at the mouse position. If the mouse is + * not moved, all accounts are set to "Away" or similar states. + * + * @author Thomas Hofer + */ +public class StatusUpdateThread + implements Runnable +{ + private boolean run = false; + private Point lastPosition = null; + private final Map lastStates + = new HashMap(); + + private static final int IDLE_TIMER = 3000; + private static final int AWAY_DEFAULT_STATUS = 40; + + public void run() + { + run = true; + int timer = 0; + do + { + try + { + if (MouseInfo.getPointerInfo() != null) + { + PointerInfo info = MouseInfo.getPointerInfo(); + Point currentPosition + = (info != null) ? info.getLocation() : new Point(0, 0); + + if (!isNear(lastPosition, currentPosition)) + { + // position has changed + // check, if a minor state has been automatically set + // and + // reset this state to the former state. + for (ProtocolProviderService protocolProviderService + : AutoAwayActivator.getProtocolProviders()) + { + if (lastStates.get(protocolProviderService) != null) + { + PresenceStatus lastState + = lastStates.get(protocolProviderService); + OperationSetPresence presence + = protocolProviderService + .getOperationSet( + OperationSetPresence.class); + try + { + presence + .publishPresenceStatus(lastState, ""); + } catch (IllegalArgumentException e) + { + } catch (IllegalStateException e) + { + } catch (OperationFailedException e) + { + } + lastStates.remove(protocolProviderService); + } + } + timer = getTimer() * 1000 * 60; + } else + { + // position has not changed! + // get all protocols and set them to away + for (ProtocolProviderService protocolProviderService + : AutoAwayActivator.getProtocolProviders()) + { + OperationSetPresence presence + = protocolProviderService + .getOperationSet( + OperationSetPresence.class); + + PresenceStatus status = presence + .getPresenceStatus(); + + if (status.getStatus() + < PresenceStatus.AVAILABLE_THRESHOLD) + { + // already (manually) set to away or lower + continue; + } + + lastStates.put(protocolProviderService, status); + + PresenceStatus newStatus = findAwayStatus(presence); + + try + { + if (newStatus != null) + presence + .publishPresenceStatus( + newStatus, + newStatus.getStatusName()); + } catch (IllegalArgumentException e) + { + } catch (IllegalStateException e) + { + } catch (OperationFailedException e) + { + } + } + + timer = IDLE_TIMER; + } + lastPosition = currentPosition; + } + Thread.sleep(timer); + } catch (InterruptedException e) + { + } + } while (run && timer > 0); + } + + public void stop() + { + run = false; + } + + /** + * Finds the Away-Status of the protocols + * + * @param presence + * @return + */ + private PresenceStatus findAwayStatus(OperationSetPresence presence) + { + Iterator statusSet = presence.getSupportedStatusSet(); + PresenceStatus status = null; + + while (statusSet.hasNext()) + { + PresenceStatus possibleState = statusSet.next(); + int possibleStatus = possibleState.getStatus(); + + if ((possibleStatus < PresenceStatus.AVAILABLE_THRESHOLD) + && (possibleStatus >= PresenceStatus.ONLINE_THRESHOLD)) + { + if (status == null + || (Math.abs(possibleStatus - AWAY_DEFAULT_STATUS) + < Math.abs( + status.getStatus() + - AWAY_DEFAULT_STATUS))) + { + status = possibleState; + } + } + } + return status; + } + + private int getTimer() + { + ConfigurationService configService + = AutoAwayActivator.getConfigService(); + + return + configService.getBoolean(Preferences.ENABLE, false) + ? configService.getInt(Preferences.TIMER, 0) + : 0; + } + + public boolean isRunning() + { + return run; + } + + private boolean isNear(Point p1, Point p2) + { + return + (p1 != null) + && (p2 != null) + && (Math.abs(p1.x - p2.x) <= 10) + && (Math.abs(p1.y - p2.y) <= 10); + } +} diff --git a/src/net/java/sip/communicator/plugin/chatalerter/ChatAlerterActivator.java b/src/net/java/sip/communicator/plugin/chatalerter/ChatAlerterActivator.java index 49d35fb69..a24d20e23 100644 --- a/src/net/java/sip/communicator/plugin/chatalerter/ChatAlerterActivator.java +++ b/src/net/java/sip/communicator/plugin/chatalerter/ChatAlerterActivator.java @@ -1,344 +1,340 @@ -/* - * SIP Communicator, 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.chatalerter; - -import javax.swing.*; - -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.*; -import org.osgi.framework.*; - -/** - * Chat Alerter plugin. - * - * Sends alerts to the user when new message arrives and the application is not - * in the foreground. On Mac OS X this will bounce the dock icon until the user - * selects the chat windows. On Windows, Gnome and KDE this will flash the - * taskbar button/icon until the user selects the chat window. - * - * @author Damian Minkov - */ -public class ChatAlerterActivator - implements BundleActivator, - ServiceListener, - MessageListener, - ChatRoomMessageListener, +/* + * SIP Communicator, 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.chatalerter; + +import javax.swing.*; + +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.*; +import org.osgi.framework.*; + +/** + * Chat Alerter plugin. + * + * Sends alerts to the user when new message arrives and the application is not + * in the foreground. On Mac OS X this will bounce the dock icon until the user + * selects the chat windows. On Windows, Gnome and KDE this will flash the + * taskbar button/icon until the user selects the chat window. + * + * @author Damian Minkov + */ +public class ChatAlerterActivator + implements BundleActivator, + ServiceListener, + MessageListener, + ChatRoomMessageListener, AdHocChatRoomMessageListener, LocalUserChatRoomPresenceListener, LocalUserAdHocChatRoomPresenceListener -{ - /** - * 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; - 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 (ServiceReference protocolProviderRef : protocolProviderRefs) - { - ProtocolProviderService provider - = (ProtocolProviderService) - bc.getService(protocolProviderRef); - - this.handleProviderAdded(provider); - } - } +{ + /** + * 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; + } - } - - public void stop(BundleContext bc) throws Exception - { - // start listening for newly register or removed protocol providers - bc.removeServiceListener(this); - - ServiceReference[] protocolProviderRefs; - 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 (ServiceReference protocolProviderRef : protocolProviderRefs) - { - ProtocolProviderService provider - = (ProtocolProviderService) - bc.getService(protocolProviderRef); - - 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 - .getOperationSet(OperationSetBasicInstantMessaging.class); - - 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 - .getOperationSet(OperationSetSmsMessaging.class); - - if (opSetSms != null) - { - opSetSms.addMessageListener(this); - } - else - { - logger.trace("Service did not have a sms op. set."); - } - - OperationSetMultiUserChat opSetMultiUChat = - (OperationSetMultiUserChat) provider - .getOperationSet(OperationSetMultiUserChat.class); - - if (opSetMultiUChat != null) - { - for (ChatRoom room : opSetMultiUChat.getCurrentlyJoinedChatRooms()) - 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 - .getOperationSet(OperationSetBasicInstantMessaging.class); - - if (opSetIm != null) - { - opSetIm.removeMessageListener(this); - } - - OperationSetMultiUserChat opSetMultiUChat = - (OperationSetMultiUserChat) provider - .getOperationSet(OperationSetMultiUserChat.class); - - if (opSetMultiUChat != null) - { - for (ChatRoom room : opSetMultiUChat.getCurrentlyJoinedChatRooms()) - 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) - { - alertChatWindow(); - } - - public void messageDelivered(MessageDeliveredEvent evt) - { - // do nothing - } - - public void messageDeliveryFailed(MessageDeliveryFailedEvent evt) - { - // do nothing - } - - public void messageReceived(ChatRoomMessageReceivedEvent evt) - { - alertChatWindow(); - } - - public void messageDelivered(ChatRoomMessageDeliveredEvent evt) - { - // do nothing - } - - public void messageDeliveryFailed(ChatRoomMessageDeliveryFailedEvent evt) - { - // do nothing - } - - /** - * Alerts that a message has been received in - * ExportedWindow.CHAT_WINDOW by using a platform-dependent - * visual clue such as flashing it in the task bar on Windows and Linux. - */ - private void alertChatWindow() - { - try - { - ExportedWindow win - = uiService.getExportedWindow(ExportedWindow.CHAT_WINDOW); - if (win == null) - return; - - Object winSource = win.getSource(); - if (!(winSource instanceof JFrame)) - return; - - JFrame fr = (JFrame) winSource; - - Alerter.newInstance().alert(fr); - } - catch (Exception ex) - { - logger.error("Cannot alert chat window!"); - } - } - - /** - * 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."); - switch (serviceEvent.getType()) - { - case ServiceEvent.REGISTERED: - this.handleProviderAdded((ProtocolProviderService)sService); - break; - - case ServiceEvent.UNREGISTERING: - this.handleProviderRemoved( (ProtocolProviderService) sService); - break; - } - } + 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; + 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 (ServiceReference protocolProviderRef : protocolProviderRefs) + { + ProtocolProviderService provider + = (ProtocolProviderService) + bc.getService(protocolProviderRef); + + this.handleProviderAdded(provider); + } + } + + } + + public void stop(BundleContext bc) throws Exception + { + // start listening for newly register or removed protocol providers + bc.removeServiceListener(this); + + ServiceReference[] protocolProviderRefs; + 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 (ServiceReference protocolProviderRef : protocolProviderRefs) + { + ProtocolProviderService provider + = (ProtocolProviderService) + bc.getService(protocolProviderRef); + + 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 + = provider + .getOperationSet(OperationSetBasicInstantMessaging.class); + + 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 + = provider.getOperationSet(OperationSetSmsMessaging.class); + + if (opSetSms != null) + { + opSetSms.addMessageListener(this); + } + else + { + logger.trace("Service did not have a sms op. set."); + } + + OperationSetMultiUserChat opSetMultiUChat + = provider.getOperationSet(OperationSetMultiUserChat.class); + + if (opSetMultiUChat != null) + { + for (ChatRoom room : opSetMultiUChat.getCurrentlyJoinedChatRooms()) + 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 + = provider.getOperationSet(OperationSetBasicInstantMessaging.class); + + if (opSetIm != null) + { + opSetIm.removeMessageListener(this); + } + + OperationSetMultiUserChat opSetMultiUChat + = provider.getOperationSet(OperationSetMultiUserChat.class); + + if (opSetMultiUChat != null) + { + for (ChatRoom room : opSetMultiUChat.getCurrentlyJoinedChatRooms()) + 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) + { + alertChatWindow(); + } + + public void messageDelivered(MessageDeliveredEvent evt) + { + // do nothing + } + + public void messageDeliveryFailed(MessageDeliveryFailedEvent evt) + { + // do nothing + } + + public void messageReceived(ChatRoomMessageReceivedEvent evt) + { + alertChatWindow(); + } + + public void messageDelivered(ChatRoomMessageDeliveredEvent evt) + { + // do nothing + } + + public void messageDeliveryFailed(ChatRoomMessageDeliveryFailedEvent evt) + { + // do nothing + } + + /** + * Alerts that a message has been received in + * ExportedWindow.CHAT_WINDOW by using a platform-dependent + * visual clue such as flashing it in the task bar on Windows and Linux. + */ + private void alertChatWindow() + { + try + { + ExportedWindow win + = uiService.getExportedWindow(ExportedWindow.CHAT_WINDOW); + if (win == null) + return; + + Object winSource = win.getSource(); + if (!(winSource instanceof JFrame)) + return; + + JFrame fr = (JFrame) winSource; + + Alerter.newInstance().alert(fr); + } + catch (Exception ex) + { + logger.error("Cannot alert chat window!"); + } + } + + /** + * 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."); + switch (serviceEvent.getType()) + { + case ServiceEvent.REGISTERED: + this.handleProviderAdded((ProtocolProviderService)sService); + break; + + case ServiceEvent.UNREGISTERING: + this.handleProviderRemoved( (ProtocolProviderService) sService); + break; + } + } public void messageDelivered(AdHocChatRoomMessageDeliveredEvent evt) { @@ -377,4 +373,4 @@ public void localUserAdHocPresenceChanged( evt.getAdHocChatRoom().removeMessageListener(this); } } -} +} diff --git a/src/net/java/sip/communicator/plugin/mailbox/Mailbox.java b/src/net/java/sip/communicator/plugin/mailbox/Mailbox.java index 150a566e7..1ebce2d7b 100644 --- a/src/net/java/sip/communicator/plugin/mailbox/Mailbox.java +++ b/src/net/java/sip/communicator/plugin/mailbox/Mailbox.java @@ -349,8 +349,7 @@ public void handleProviderAdded(ProtocolProviderService provider) // check whether the provider has a basic telephony operation set OperationSetBasicTelephony opSetTelephony = - (OperationSetBasicTelephony) provider - .getOperationSet(OperationSetBasicTelephony.class); + provider.getOperationSet(OperationSetBasicTelephony.class); if (opSetTelephony != null) { @@ -360,7 +359,6 @@ public void handleProviderAdded(ProtocolProviderService provider) { logger.trace("Service did not have a basic telephony op. set."); } - } /** @@ -372,8 +370,7 @@ public void handleProviderAdded(ProtocolProviderService provider) private void handleProviderRemoved(ProtocolProviderService provider) { OperationSetBasicTelephony opSetTelephony = - (OperationSetBasicTelephony) provider - .getOperationSet(OperationSetBasicTelephony.class); + provider.getOperationSet(OperationSetBasicTelephony.class); if (opSetTelephony != null) { @@ -574,9 +571,9 @@ private void waitForCallEnd(Call call) private void answerCall(Call call) { OperationSetBasicTelephony telephony - = (OperationSetBasicTelephony)call - .getProtocolProvider().getOperationSet( - OperationSetBasicTelephony.class); + = call + .getProtocolProvider() + .getOperationSet(OperationSetBasicTelephony.class); Iterator peers = call.getCallPeers(); while(peers.hasNext()) @@ -607,9 +604,9 @@ private void answerCall(Call call) private void hangupCall(Call call) { OperationSetBasicTelephony telephony - = (OperationSetBasicTelephony)call - .getProtocolProvider().getOperationSet( - OperationSetBasicTelephony.class); + = call + .getProtocolProvider() + .getOperationSet(OperationSetBasicTelephony.class); logger.info("Max Message Length Reached, Mailbox is" +" disconnecting the call"); Iterator callPeers = call.getCallPeers(); diff --git a/src/net/java/sip/communicator/plugin/otr/OtrActivator.java b/src/net/java/sip/communicator/plugin/otr/OtrActivator.java index 02b750397..0a9441ef6 100644 --- a/src/net/java/sip/communicator/plugin/otr/OtrActivator.java +++ b/src/net/java/sip/communicator/plugin/otr/OtrActivator.java @@ -176,8 +176,8 @@ public void start(BundleContext bc) throws Exception private void handleProviderAdded(ProtocolProviderService provider) { - OperationSetInstantMessageTransform opSetMessageTransform = - (OperationSetInstantMessageTransform) provider + OperationSetInstantMessageTransform opSetMessageTransform + = provider .getOperationSet(OperationSetInstantMessageTransform.class); if (opSetMessageTransform != null) @@ -244,8 +244,8 @@ public void stop(BundleContext bc) throws Exception private void handleProviderRemoved(ProtocolProviderService provider) { // check whether the provider has a basic im operation set - OperationSetInstantMessageTransform opSetMessageTransform = - (OperationSetInstantMessageTransform) provider + OperationSetInstantMessageTransform opSetMessageTransform + = provider .getOperationSet(OperationSetInstantMessageTransform.class); if (opSetMessageTransform != null) diff --git a/src/net/java/sip/communicator/plugin/whiteboard/WhiteboardActivator.java b/src/net/java/sip/communicator/plugin/whiteboard/WhiteboardActivator.java index 87bd8c5b6..bc45d91d0 100644 --- a/src/net/java/sip/communicator/plugin/whiteboard/WhiteboardActivator.java +++ b/src/net/java/sip/communicator/plugin/whiteboard/WhiteboardActivator.java @@ -109,8 +109,7 @@ public static List getWhiteboardOperationSets() = (ProtocolProviderService) bundleContext.getService(serRef); OperationSetWhiteboarding opSet - = (OperationSetWhiteboarding) - protocolProvider + = protocolProvider .getOperationSet(OperationSetWhiteboarding.class); if(opSet != null) diff --git a/src/net/java/sip/communicator/plugin/whiteboard/WhiteboardSessionManager.java b/src/net/java/sip/communicator/plugin/whiteboard/WhiteboardSessionManager.java index 69a0d81ed..aa6c0a655 100644 --- a/src/net/java/sip/communicator/plugin/whiteboard/WhiteboardSessionManager.java +++ b/src/net/java/sip/communicator/plugin/whiteboard/WhiteboardSessionManager.java @@ -59,9 +59,10 @@ public WhiteboardSessionManager() */ public void initWhiteboard (final Contact contact) { - opSetWb = (OperationSetWhiteboarding) - contact.getProtocolProvider(). - getOperationSet(OperationSetWhiteboarding.class); + opSetWb + = contact + .getProtocolProvider() + .getOperationSet(OperationSetWhiteboarding.class); if (opSetWb == null) { diff --git a/test/net/java/sip/communicator/slick/contactlist/TestMetaContactGroup.java b/test/net/java/sip/communicator/slick/contactlist/TestMetaContactGroup.java index a628560ff..5ccd92ede 100644 --- a/test/net/java/sip/communicator/slick/contactlist/TestMetaContactGroup.java +++ b/test/net/java/sip/communicator/slick/contactlist/TestMetaContactGroup.java @@ -46,7 +46,7 @@ protected void setUp() throws Exception fixture.setUp(); OperationSetPersistentPresence opSetPresence = - (OperationSetPersistentPresence) fixture.mockProvider + fixture.mockProvider .getOperationSet(OperationSetPersistentPresence.class); mockGroup = (MockContactGroup)opSetPresence diff --git a/test/net/java/sip/communicator/slick/contactlist/TestMetaContactListPersistence.java b/test/net/java/sip/communicator/slick/contactlist/TestMetaContactListPersistence.java index 6011b14e7..fdfbee7bf 100644 --- a/test/net/java/sip/communicator/slick/contactlist/TestMetaContactListPersistence.java +++ b/test/net/java/sip/communicator/slick/contactlist/TestMetaContactListPersistence.java @@ -190,8 +190,8 @@ public void testPartialContactListRestauration() //verify that contents of the meta contact list matches contents of //the mock provider we removed. ContactGroup oldProtoRoot = - ((OperationSetPersistentPresence) fixture.mockProvider - .getOperationSet(OperationSetPersistentPresence.class)) + fixture.mockProvider + .getOperationSet(OperationSetPersistentPresence.class) .getServerStoredContactListRoot(); fixture.assertGroupEquals( @@ -203,8 +203,8 @@ public void testPartialContactListRestauration() //verify that the new mock provider has created unresolved contacts //for all contacts in the meta cl. ContactGroup newProtoRoot = - ((OperationSetPersistentPresence) fixture.replacementMockPr - .getOperationSet(OperationSetPersistentPresence.class)) + fixture.replacementMockPr + .getOperationSet(OperationSetPersistentPresence.class) .getServerStoredContactListRoot(); assertEquals("Newly loaded provider does not match the old one." @@ -240,21 +240,21 @@ public void testCompleteContactListRestauration() //Get references to the root groups of the 2 providers we removed ContactGroup oldProtoMockP1Root = - ((OperationSetPersistentPresence) fixture.mockP1 - .getOperationSet(OperationSetPersistentPresence.class)) + fixture.mockP1 + .getOperationSet(OperationSetPersistentPresence.class) .getServerStoredContactListRoot(); ContactGroup oldProtoMockP2Root = - ((OperationSetPersistentPresence) fixture.mockP2 - .getOperationSet(OperationSetPersistentPresence.class)) + fixture.mockP2 + .getOperationSet(OperationSetPersistentPresence.class) .getServerStoredContactListRoot(); //verify that contacts tnat unresolved contacts that have been created //inside that the replacement mock providers match those in the //providers we removed. ContactGroup newProtoMockP1Root = - ((OperationSetPersistentPresence) fixture.replacementMockP1 - .getOperationSet(OperationSetPersistentPresence.class)) + fixture.replacementMockP1 + .getOperationSet(OperationSetPersistentPresence.class) .getServerStoredContactListRoot(); assertEquals("Newly loaded provider does not match the old one." @@ -262,8 +262,8 @@ public void testCompleteContactListRestauration() , newProtoMockP1Root); ContactGroup newProtoMockP2Root = - ((OperationSetPersistentPresence) fixture.replacementMockP2 - .getOperationSet(OperationSetPersistentPresence.class)) + fixture.replacementMockP2 + .getOperationSet(OperationSetPersistentPresence.class) .getServerStoredContactListRoot(); assertEquals("Newly loaded provider does not match the old one." diff --git a/test/net/java/sip/communicator/slick/protocol/generic/PredictableTransformLayer.java b/test/net/java/sip/communicator/slick/protocol/generic/PredictableTransformLayer.java index 02818741e..035cc9b23 100644 --- a/test/net/java/sip/communicator/slick/protocol/generic/PredictableTransformLayer.java +++ b/test/net/java/sip/communicator/slick/protocol/generic/PredictableTransformLayer.java @@ -74,7 +74,7 @@ private Message createMessage(Contact contact, Message message, String action) { OperationSetBasicInstantMessaging imOpSet = - (OperationSetBasicInstantMessaging) contact.getProtocolProvider() + contact.getProtocolProvider() .getOperationSet(OperationSetBasicInstantMessaging.class); return imOpSet.createMessage("__" + action + "__" + message.getContent()); diff --git a/test/net/java/sip/communicator/slick/protocol/icq/TestProtocolProviderServiceIcqImpl.java b/test/net/java/sip/communicator/slick/protocol/icq/TestProtocolProviderServiceIcqImpl.java index 0c37d565a..8425d5c5e 100644 --- a/test/net/java/sip/communicator/slick/protocol/icq/TestProtocolProviderServiceIcqImpl.java +++ b/test/net/java/sip/communicator/slick/protocol/icq/TestProtocolProviderServiceIcqImpl.java @@ -147,8 +147,7 @@ public void testRegister() // This message is supposed to be offline message and as one is tested // in TestOperationSetBasicInstantMessaging.testReceiveOfflineMessages() OperationSetBasicInstantMessaging opSetBasicIM = - (OperationSetBasicInstantMessaging) fixture.provider - .getOperationSet(OperationSetBasicInstantMessaging.class); + fixture.provider.getOperationSet(OperationSetBasicInstantMessaging.class); fixture.offlineMsgCollector.register(opSetBasicIM); //give time for the AIM server to notify everyone of our arrival diff --git a/test/net/java/sip/communicator/slick/protocol/jabber/TestOperationSetBasicTelephonyJabberImpl.java b/test/net/java/sip/communicator/slick/protocol/jabber/TestOperationSetBasicTelephonyJabberImpl.java index f3c17b6fc..33810d7db 100644 --- a/test/net/java/sip/communicator/slick/protocol/jabber/TestOperationSetBasicTelephonyJabberImpl.java +++ b/test/net/java/sip/communicator/slick/protocol/jabber/TestOperationSetBasicTelephonyJabberImpl.java @@ -1,1063 +1,1063 @@ -/* - * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.slick.protocol.jabber; - -import junit.framework.*; -import net.java.sip.communicator.util.*; -import net.java.sip.communicator.service.protocol.*; -import java.text.ParseException; -import net.java.sip.communicator.service.protocol.event.*; -import java.util.*; - -/** - * Tests Basic telephony functionality by making one provider call the other. - * - * @author Emil Ivov - * @author Symphorien Wanko - */ -public class TestOperationSetBasicTelephonyJabberImpl - extends TestCase -{ - private static final Logger logger - = Logger.getLogger(TestOperationSetBasicTelephonyJabberImpl.class); - - /** - * Provides constants and some utilities method. - */ - private JabberSlickFixture fixture = new JabberSlickFixture(); - - /** - * Initializes the test with the specified name. - * - * @param name the name of the test to initialize. - */ - public TestOperationSetBasicTelephonyJabberImpl(String name) - { - super(name); - } - - /** - * JUnit setup method. - * @throws Exception in case anything goes wrong. - */ - protected void setUp() throws Exception - { - super.setUp(); - fixture.setUp(); - } - - /** - * JUnit teardown method. - * @throws Exception in case anything goes wrong. - */ - protected void tearDown() throws Exception - { - fixture.tearDown(); - super.tearDown(); - } - - /** - * Creates a call from provider1 to provider2 then cancels it without - * waiting for provider1 to answer. - * - * @throws ParseException if we hand a malformed URI to someone - * @throws OperationFailedException if something weird happens. - */ - public void testCreateCancelCall() - throws ParseException, OperationFailedException - { - OperationSetBasicTelephony basicTelephonyP1 - = (OperationSetBasicTelephony)fixture.provider1.getOperationSet( - OperationSetBasicTelephony.class); - OperationSetBasicTelephony basicTelephonyP2 - = (OperationSetBasicTelephony)fixture.provider2.getOperationSet( - OperationSetBasicTelephony.class); - - CallEventCollector call1Listener - = new CallEventCollector(basicTelephonyP1); - CallEventCollector call2Listener - = new CallEventCollector(basicTelephonyP2); - - //Provider1 calls Provider2 - String provider2Address - = fixture.provider2.getAccountID().getAccountAddress(); - - Call callAtP1 = basicTelephonyP1.createCall(provider2Address); - - call1Listener.waitForEvent(10000); - call2Listener.waitForEvent(10000); - - //make sure that both listeners have received their events. - assertEquals("The provider that created the call did not dispatch " - + "an event that it has done so." - , 1, call1Listener.collectedEvents.size()); - //call1 listener checks - CallEvent callCreatedEvent - = (CallEvent)call1Listener.collectedEvents.get(0); - - assertEquals("CallEvent.getEventID()" - ,CallEvent.CALL_INITIATED, callCreatedEvent.getEventID()); - assertSame("CallEvent.getSource()" - , callAtP1, callCreatedEvent.getSource()); - - //call2 listener checks - assertTrue("The callee provider did not receive a call or did " - +"not issue an event." - , call2Listener.collectedEvents.size() > 0); - CallEvent callReceivedEvent - = (CallEvent)call2Listener.collectedEvents.get(0); - Call callAtP2 = callReceivedEvent.getSourceCall(); - - assertEquals("CallEvent.getEventID()" - ,CallEvent.CALL_RECEIVED, callReceivedEvent.getEventID()); - assertNotNull("CallEvent.getSource()", callAtP2); - - //verify that call peers are properly created - assertEquals("callAtP1.getCallPeerCount()" - , 1, callAtP1.getCallPeerCount()); - assertEquals("callAtP2.getCallPeerCount()" - , 1, callAtP2.getCallPeerCount()); - - CallPeer peerAtP1 = callAtP1.getCallPeers().next(); - CallPeer peerAtP2 = callAtP2.getCallPeers().next(); - - //now add listeners to the peers and make sure they have entered - //the states they were expected to. - //check states for call peers at both parties - CallPeerStateEventCollector stateCollectorForPp1 - = new CallPeerStateEventCollector( - peerAtP1, CallPeerState.ALERTING_REMOTE_SIDE); - CallPeerStateEventCollector stateCollectorForPp2 - = new CallPeerStateEventCollector( - peerAtP2, CallPeerState.INCOMING_CALL); - - stateCollectorForPp1.waitForEvent(10000, true); - stateCollectorForPp2.waitForEvent(10000, true); - - assertSame("peerAtP1.getCall" - , peerAtP1.getCall(), callAtP1); - assertSame("peerAtP2.getCall" - , peerAtP2.getCall(), callAtP2); - - //make sure that the peers are in the proper state - assertEquals("The peer at provider one was not in the " - +"right state." - , CallPeerState.ALERTING_REMOTE_SIDE - , peerAtP1.getState()); - assertEquals("The peer at provider two was not in the " - +"right state." - , CallPeerState.INCOMING_CALL - , peerAtP2.getState()); - - - //test whether caller/callee info is properly distributed in case - //the server is said to support it. - if(Boolean.getBoolean("accounts.jabber.PRESERVE_PEER_INFO")) - { - //check properties on the remote call peer for the party that - //initiated the call. - String expectedPeer1Address - = fixture.provider2.getAccountID().getAccountAddress(); - String expectedPeer1DisplayName - = System.getProperty( - JabberProtocolProviderServiceLick.ACCOUNT_2_PREFIX - + ProtocolProviderFactory.DISPLAY_NAME); - - //do not asser equals here since one of the addresses may contain a - //display name or something of the kind - assertTrue("Provider 2 did not advertise their " - + "accountID.getAccoutAddress() address." - , expectedPeer1Address.indexOf( - peerAtP1.getAddress()) != -1 - || peerAtP1.getAddress().indexOf( - expectedPeer1Address) != -1); - assertEquals("Provider 2 did not properly advertise their " - + "display name." - , expectedPeer1DisplayName - , peerAtP1.getDisplayName()); - - //check properties on the remote call peer for the party that - //receives the call. - String expectedPeer2Address - = fixture.provider1.getAccountID().getAccountAddress(); - String expectedPeer2DisplayName - = System.getProperty( - JabberProtocolProviderServiceLick.ACCOUNT_1_PREFIX - + ProtocolProviderFactory.DISPLAY_NAME); - - //do not asser equals here since one of the addresses may contain a - //display name or something of the kind - assertTrue("Provider 1 did not advertise their " - + "accountID.getAccoutAddress() address." - , expectedPeer2Address.indexOf( - peerAtP2.getAddress()) != -1 - || peerAtP2.getAddress().indexOf( - expectedPeer2Address) != -1); - assertEquals("Provider 1 did not properly advertise their " - + "display name." - , expectedPeer2DisplayName - , peerAtP2.getDisplayName()); - } - - //we'll now try to cancel the call - - //listeners monitoring state change of the peer - stateCollectorForPp1 = new CallPeerStateEventCollector( - peerAtP1, CallPeerState.DISCONNECTED); - stateCollectorForPp2 = new CallPeerStateEventCollector( - peerAtP2, CallPeerState.DISCONNECTED); - - //listeners waiting for the op set to announce the end of the call - call1Listener = new CallEventCollector(basicTelephonyP1); - call2Listener = new CallEventCollector(basicTelephonyP2); - - //listeners monitoring the state of the call - CallStateEventCollector call1StateCollector - = new CallStateEventCollector(callAtP1, CallState.CALL_ENDED); - CallStateEventCollector call2StateCollector - = new CallStateEventCollector(callAtP2, CallState.CALL_ENDED); - - //Now make the caller CANCEL the call. - basicTelephonyP1.hangupCallPeer(peerAtP1); - - //wait for everything to happen - call1Listener.waitForEvent(10000); - call2Listener.waitForEvent(10000); - stateCollectorForPp1.waitForEvent(10000); - stateCollectorForPp2.waitForEvent(10000); - call1StateCollector.waitForEvent(10000); - call2StateCollector.waitForEvent(10000); - - - //make sure that the peer is disconnected - assertEquals("The peer at provider one was not in the " - +"right state." - , CallPeerState.DISCONNECTED - , peerAtP1.getState()); - - //make sure the telephony operation set distributed an event for the end - //of the call - assertEquals("The basic telephony operation set did not distribute " - +"an event to notify us that a call has been ended." - , 1 - , call1Listener.collectedEvents.size()); - - CallEvent collectedEvent - = (CallEvent)call1Listener.collectedEvents.get(0); - - assertEquals("The basic telephony operation set did not distribute " - +"an event to notify us that a call has been ended." - , CallEvent.CALL_ENDED - , collectedEvent.getEventID()); - - //same for provider 2 - - //make sure that the peer is disconnected - assertEquals("The peer at provider one was not in the " - +"right state." - , CallPeerState.DISCONNECTED - , peerAtP2.getState()); - - //make sure the telephony operation set distributed an event for the end - //of the call - assertEquals("The basic telephony operation set did not distribute " - +"an event to notify us that a call has been ended." - , 1 - , call2Listener.collectedEvents.size()); - - collectedEvent - = (CallEvent)call2Listener.collectedEvents.get(0); - - assertEquals("The basic telephony operation set did not distribute " - +"an event to notify us that a call has been ended." - , CallEvent.CALL_ENDED - , collectedEvent.getEventID()); - - //make sure that the call objects are in an ENDED state. - assertEquals("A call did not change its state to CallState.CALL_ENDED " - +"when it ended." - , CallState.CALL_ENDED - , callAtP1.getCallState()); - assertEquals("A call did not change its state to CallState.CALL_ENDED " - +"when it ended." - , CallState.CALL_ENDED - , callAtP2.getCallState()); - } - - /** - * Creates a call from provider1 to provider2 then rejects the call from the - * side of provider2 (provider2 replies with busy-tone). - * - * @throws ParseException if we hand a malformed URI to someone - * @throws OperationFailedException if something weird happens. - */ - public void testCreateRejectCall() - throws ParseException, OperationFailedException - { - OperationSetBasicTelephony basicTelephonyP1 - = (OperationSetBasicTelephony)fixture.provider1.getOperationSet( - OperationSetBasicTelephony.class); - OperationSetBasicTelephony basicTelephonyP2 - = (OperationSetBasicTelephony)fixture.provider2.getOperationSet( - OperationSetBasicTelephony.class); - - CallEventCollector call1Listener - = new CallEventCollector(basicTelephonyP1); - CallEventCollector call2Listener - = new CallEventCollector(basicTelephonyP2); - - //Provider1 calls Provider2 - String provider2Address - = fixture.provider2.getAccountID().getAccountAddress(); - - Call callAtP1 = basicTelephonyP1.createCall(provider2Address); - - call1Listener.waitForEvent(10000); - call2Listener.waitForEvent(10000); - - //make sure that both listeners have received their events. - assertEquals("The provider that created the call did not dispatch " - + "an event that it has done so." - , 1, call1Listener.collectedEvents.size()); - //call1 listener checks - CallEvent callCreatedEvent - = (CallEvent)call1Listener.collectedEvents.get(0); - - assertEquals("CallEvent.getEventID()" - ,CallEvent.CALL_INITIATED, callCreatedEvent.getEventID()); - assertSame("CallEvent.getSource()" - , callAtP1, callCreatedEvent.getSource()); - - //call2 listener checks - assertTrue("The callee provider did not receive a call or did " - +"not issue an event." - , call2Listener.collectedEvents.size() > 0); - CallEvent callReceivedEvent - = (CallEvent)call2Listener.collectedEvents.get(0); - Call callAtP2 = callReceivedEvent.getSourceCall(); - - assertEquals("CallEvent.getEventID()" - ,CallEvent.CALL_RECEIVED, callReceivedEvent.getEventID()); - assertNotNull("CallEvent.getSource()", callAtP2); - - //verify that call peers are properly created - assertEquals("callAtP1.getCallPeerCount()" - , 1, callAtP1.getCallPeerCount()); - assertEquals("callAtP2.getCallPeerCount()" - , 1, callAtP2.getCallPeerCount()); - - CallPeer peerAtP1 = callAtP1.getCallPeers().next(); - CallPeer peerAtP2 = callAtP2.getCallPeers().next(); - - //now add listeners to the peers and make sure they have entered - //the states they were expected to. - //check states for call peers at both parties - CallPeerStateEventCollector stateCollectorForPp1 - = new CallPeerStateEventCollector( - peerAtP1, CallPeerState.ALERTING_REMOTE_SIDE); - CallPeerStateEventCollector stateCollectorForPp2 - = new CallPeerStateEventCollector( - peerAtP2, CallPeerState.INCOMING_CALL); - - stateCollectorForPp1.waitForEvent(10000, true); - stateCollectorForPp2.waitForEvent(10000, true); - - assertSame("peerAtP1.getCall" - , peerAtP1.getCall(), callAtP1); - assertSame("peerAtP2.getCall" - , peerAtP2.getCall(), callAtP2); - - //make sure that the peers are in the proper state - assertEquals("The peer at provider one was not in the " - +"right state." - , CallPeerState.ALERTING_REMOTE_SIDE - , peerAtP1.getState()); - assertEquals("The peer at provider two was not in the " - +"right state." - , CallPeerState.INCOMING_CALL - , peerAtP2.getState()); - - - //test whether caller/callee info is properly distributed in case - //the server is said to support it. - if(Boolean.getBoolean("accounts.jabber.PRESERVE_PEER_INFO")) - { - //check properties on the remote call peer for the party that - //initiated the call. - String expectedPeer1Address - = fixture.provider2.getAccountID().getAccountAddress(); - String expectedPeer1DisplayName - = System.getProperty( - JabberProtocolProviderServiceLick.ACCOUNT_2_PREFIX - + ProtocolProviderFactory.DISPLAY_NAME); - - //do not asser equals here since one of the addresses may contain a - //display name or something of the kind - assertTrue("Provider 2 did not advertise their " - + "accountID.getAccoutAddress() address." - , expectedPeer1Address.indexOf( - peerAtP1.getAddress()) != -1 - || peerAtP1.getAddress().indexOf( - expectedPeer1Address) != -1); - assertEquals("Provider 2 did not properly advertise their " - + "display name." - , expectedPeer1DisplayName - , peerAtP1.getDisplayName()); - - //check properties on the remote call peer for the party that - //receives the call. - String expectedPeer2Address - = fixture.provider1.getAccountID().getAccountAddress(); - String expectedPeer2DisplayName - = System.getProperty( - JabberProtocolProviderServiceLick.ACCOUNT_1_PREFIX - + ProtocolProviderFactory.DISPLAY_NAME); - - //do not asser equals here since one of the addresses may contain a - //display name or something of the kind - assertTrue("Provider 1 did not advertise their " - + "accountID.getAccoutAddress() address." - , expectedPeer2Address.indexOf( - peerAtP2.getAddress()) != -1 - || peerAtP2.getAddress().indexOf( - expectedPeer2Address) != -1); - assertEquals("Provider 1 did not properly advertise their " - + "display name." - , expectedPeer2DisplayName - , peerAtP2.getDisplayName()); - } - - //we'll now try to send busy tone. - - //listeners monitoring state change of the peer - CallPeerStateEventCollector busyStateCollectorForPp1 - = new CallPeerStateEventCollector( - peerAtP1, CallPeerState.BUSY); - stateCollectorForPp1 = new CallPeerStateEventCollector( - peerAtP1, CallPeerState.DISCONNECTED); - stateCollectorForPp2 = new CallPeerStateEventCollector( - peerAtP2, CallPeerState.DISCONNECTED); - - //listeners waiting for the op set to announce the end of the call - call1Listener = new CallEventCollector(basicTelephonyP1); - call2Listener = new CallEventCollector(basicTelephonyP2); - - //listeners monitoring the state of the call - CallStateEventCollector call1StateCollector - = new CallStateEventCollector(callAtP1, CallState.CALL_ENDED); - CallStateEventCollector call2StateCollector - = new CallStateEventCollector(callAtP2, CallState.CALL_ENDED); - - //Now make the caller CANCEL the call. - basicTelephonyP2.hangupCallPeer(peerAtP2); - busyStateCollectorForPp1.waitForEvent(10000); - basicTelephonyP1.hangupCallPeer(peerAtP1); - - //wait for everything to happen - call1Listener.waitForEvent(10000); - call2Listener.waitForEvent(10000); - stateCollectorForPp1.waitForEvent(10000); - stateCollectorForPp2.waitForEvent(10000); - call1StateCollector.waitForEvent(10000); - call2StateCollector.waitForEvent(10000); - - - //make sure that the peer is disconnected - assertEquals("The peer at provider one was not in the " - +"right state." - , CallPeerState.DISCONNECTED - , peerAtP1.getState()); - - - - //make sure the telephony operation set distributed an event for the end - //of the call - assertEquals("The basic telephony operation set did not distribute " - +"an event to notify us that a call has been ended." - , 1 - , call1Listener.collectedEvents.size()); - - CallEvent collectedEvent - = (CallEvent)call1Listener.collectedEvents.get(0); - - assertEquals("The basic telephony operation set did not distribute " - +"an event to notify us that a call has been ended." - , CallEvent.CALL_ENDED - , collectedEvent.getEventID()); - - //same for provider 2 - - //make sure that the peer is disconnected - assertEquals("The peer at provider one was not in the " - +"right state." - , CallPeerState.DISCONNECTED - , peerAtP2.getState()); - - //make sure the telephony operation set distributed an event for the end - //of the call - assertEquals("The basic telephony operation set did not distribute " - +"an event to notify us that a call has been ended." - , 1 - , call2Listener.collectedEvents.size()); - - collectedEvent - = (CallEvent)call2Listener.collectedEvents.get(0); - - assertEquals("The basic telephony operation set did not distribute " - +"an event to notify us that a call has been ended." - , CallEvent.CALL_ENDED - , collectedEvent.getEventID()); - - //make sure that the call objects are in an ENDED state. - assertEquals("A call did not change its state to CallState.CALL_ENDED " - +"when it ended." - , CallState.CALL_ENDED - , callAtP1.getCallState()); - assertEquals("A call did not change its state to CallState.CALL_ENDED " - +"when it ended." - , CallState.CALL_ENDED - , callAtP2.getCallState()); - } - - /** - * Creates a call from provider1 to provider2, makes provider2 answer it - * and then reject it. - * - * @throws ParseException if we hand a malformed URI to someone - * @throws OperationFailedException if something weird happens. - */ - public void aTestCreateAnswerHangupCall() - throws ParseException, OperationFailedException - { - OperationSetBasicTelephony basicTelephonyP1 - = (OperationSetBasicTelephony)fixture.provider1.getOperationSet( - OperationSetBasicTelephony.class); - OperationSetBasicTelephony basicTelephonyP2 - = (OperationSetBasicTelephony)fixture.provider2.getOperationSet( - OperationSetBasicTelephony.class); - - CallEventCollector call1Listener - = new CallEventCollector(basicTelephonyP1); - CallEventCollector call2Listener - = new CallEventCollector(basicTelephonyP2); - - //Provider1 calls Provider2 - String provider2Address - = fixture.provider2.getAccountID().getAccountAddress(); - - Call callAtP1 = basicTelephonyP1.createCall(provider2Address); - - call1Listener.waitForEvent(10000); - call2Listener.waitForEvent(10000); - - //make sure that both listeners have received their events. - assertEquals("The provider that created the call did not dispatch " - + "an event that it has done so." - , 1, call1Listener.collectedEvents.size()); - //call1 listener checks - CallEvent callCreatedEvent - = (CallEvent)call1Listener.collectedEvents.get(0); - - assertEquals("CallEvent.getEventID()" - ,CallEvent.CALL_INITIATED, callCreatedEvent.getEventID()); - assertSame("CallEvent.getSource()" - , callAtP1, callCreatedEvent.getSource()); - - //call2 listener checks - assertTrue("The callee provider did not receive a call or did " - +"not issue an event." - , call2Listener.collectedEvents.size() > 0); - CallEvent callReceivedEvent - = (CallEvent)call2Listener.collectedEvents.get(0); - Call callAtP2 = callReceivedEvent.getSourceCall(); - - assertEquals("CallEvent.getEventID()" - ,CallEvent.CALL_RECEIVED, callReceivedEvent.getEventID()); - assertNotNull("CallEvent.getSource()", callAtP2); - - //verify that call peers are properly created - assertEquals("callAtP1.getCallPeerCount()" - , 1, callAtP1.getCallPeerCount()); - assertEquals("callAtP2.getCallPeerCount()" - , 1, callAtP2.getCallPeerCount()); - - CallPeer peerAtP1 = callAtP1.getCallPeers().next(); - CallPeer peerAtP2 = callAtP2.getCallPeers().next(); - - //now add listeners to the peers and make sure they have entered - //the states they were expected to. - //check states for call peers at both parties - CallPeerStateEventCollector stateCollectorForPp1 - = new CallPeerStateEventCollector( - peerAtP1, CallPeerState.ALERTING_REMOTE_SIDE); - CallPeerStateEventCollector stateCollectorForPp2 - = new CallPeerStateEventCollector( - peerAtP2, CallPeerState.INCOMING_CALL); - - stateCollectorForPp1.waitForEvent(10000, true); - stateCollectorForPp2.waitForEvent(10000, true); - - assertSame("peerAtP1.getCall" - , peerAtP1.getCall(), callAtP1); - assertSame("peerAtP2.getCall" - , peerAtP2.getCall(), callAtP2); - - //make sure that the peers are in the proper state - assertEquals("The peer at provider one was not in the " - +"right state." - , CallPeerState.ALERTING_REMOTE_SIDE - , peerAtP1.getState()); - assertEquals("The peer at provider two was not in the " - +"right state." - , CallPeerState.INCOMING_CALL - , peerAtP2.getState()); - - - //test whether caller/callee info is properly distributed in case - //the server is said to support it. - if(Boolean.getBoolean("accounts.jabber.PRESERVE_PEER_INFO")) - { - //check properties on the remote call peer for the party that - //initiated the call. - String expectedPeer1Address - = fixture.provider2.getAccountID().getAccountAddress(); - String expectedPeer1DisplayName - = System.getProperty( - JabberProtocolProviderServiceLick.ACCOUNT_2_PREFIX - + ProtocolProviderFactory.DISPLAY_NAME); - - //do not assert equals here since one of the addresses may contain a - //display name or something of the kind - assertTrue("Provider 2 did not advertise their " - + "accountID.getAccoutAddress() address." - , expectedPeer1Address.indexOf( - peerAtP1.getAddress()) != -1 - || peerAtP1.getAddress().indexOf( - expectedPeer1Address) != -1); - assertEquals("Provider 2 did not properly advertise their " - + "display name." - , expectedPeer1DisplayName - , peerAtP1.getDisplayName()); - - //check properties on the remote call peer for the party that - //receives the call. - String expectedPeer2Address - = fixture.provider1.getAccountID().getAccountAddress(); - String expectedPeer2DisplayName - = System.getProperty( - JabberProtocolProviderServiceLick.ACCOUNT_1_PREFIX - + ProtocolProviderFactory.DISPLAY_NAME); - - //do not asser equals here since one of the addresses may contain a - //display name or something of the kind - assertTrue("Provider 1 did not advertise their " - + "accountID.getAccoutAddress() address." - , expectedPeer2Address.indexOf( - peerAtP2.getAddress()) != -1 - || peerAtP2.getAddress().indexOf( - expectedPeer2Address) != -1); - assertEquals("Provider 1 did not properly advertise their " - + "display name." - , expectedPeer2DisplayName - , peerAtP2.getDisplayName()); - } - - //add listeners to the peers and make sure enter - //a connected state after we answer - stateCollectorForPp1 - = new CallPeerStateEventCollector( - peerAtP1, CallPeerState.CONNECTED); - stateCollectorForPp2 - = new CallPeerStateEventCollector( - peerAtP2, CallPeerState.CONNECTED); - - //we will now anser the call and verify that both parties change states - //accordingly. - basicTelephonyP2.answerCallPeer(peerAtP2); - - stateCollectorForPp1.waitForEvent(10000); - stateCollectorForPp2.waitForEvent(10000); - - //make sure that the peers are in the proper state - assertEquals("The peer at provider one was not in the " - +"right state." - , CallPeerState.CONNECTED - , peerAtP1.getState()); - assertEquals("The peer at provider two was not in the " - +"right state." - , CallPeerState.CONNECTED - , peerAtP2.getState()); - - //make sure that events have been distributed when states were changed. - assertEquals("No event was dispatched when a call peer changed " - +"its state." - , 1 - , stateCollectorForPp1.collectedEvents.size()); - assertEquals("No event was dispatched when a call peer changed " - +"its state." - , 1 - , stateCollectorForPp2.collectedEvents.size()); - - //add listeners to the peers and make sure they have entered - //the states they are expected to. - stateCollectorForPp1 - = new CallPeerStateEventCollector( - peerAtP1, CallPeerState.DISCONNECTED); - stateCollectorForPp2 - = new CallPeerStateEventCollector( - peerAtP2, CallPeerState.DISCONNECTED); - - //we will now end the call and verify that both parties change states - //accordingly. - basicTelephonyP2.hangupCallPeer(peerAtP2); - - stateCollectorForPp1.waitForEvent(10000); - stateCollectorForPp2.waitForEvent(10000); - - //make sure that the peers are in the proper state - assertEquals("The peer at provider one was not in the " - +"right state." - , CallPeerState.DISCONNECTED - , peerAtP1.getState()); - assertEquals("The peer at provider two was not in the " - +"right state." - , CallPeerState.DISCONNECTED - , peerAtP2.getState()); - - //make sure that the corresponding events were delivered. - assertEquals("a provider did not distribute an event when a call " - +"peer changed states." - , 1 - , stateCollectorForPp1.collectedEvents.size()); - assertEquals("a provider did not distribute an event when a call " - +"peer changed states." - , 1 - , stateCollectorForPp2.collectedEvents.size()); - - } - - /** - * Allows tests to wait for and collect events issued upon creation and - * reception of calls. - */ - public class CallEventCollector implements CallListener - { - public ArrayList collectedEvents = new ArrayList(); - public OperationSetBasicTelephony listenedOpSet = null; - - /** - * Creates an instance of this call event collector and registers it - * with listenedOpSet. - * @param listenedOpSet the operation set that we will be scanning for - * new calls. - */ - public CallEventCollector(OperationSetBasicTelephony listenedOpSet) - { - this.listenedOpSet = listenedOpSet; - this.listenedOpSet.addCallListener(this); - } - - /** - * Blocks until at least one event is received or until waitFor - * miliseconds pass (whichever happens first). - * - * @param waitFor the number of miliseconds that we should be waiting - * for an event before simply bailing out. - */ - public void waitForEvent(long waitFor) - { - logger.trace("Waiting for a CallEvent"); - - synchronized(this) - { - if(collectedEvents.size() > 0){ - logger.trace("Event already received. " + collectedEvents); - listenedOpSet.removeCallListener(this); - return; - } - - try{ - wait(waitFor); - if(collectedEvents.size() > 0) - logger.trace("Received a CallEvent."); - else - logger.trace("No CallEvent received for "+waitFor+"ms."); - - listenedOpSet.removeCallListener(this); - } - catch (InterruptedException ex) - { - logger.debug( - "Interrupted while waiting for a call event", ex); - } - } - } - - /** - * Stores the received event and notifies all waiting on this object - * @param event the event containing the source call. - */ - public void incomingCallReceived(CallEvent event) - { - synchronized(this) - { - logger.debug( - "Collected evt("+collectedEvents.size()+")= "+event); - - this.collectedEvents.add(event); - notifyAll(); - } - } - - /** - * Stores the received event and notifies all waiting on this object - * @param event the event containing the source call. - */ - public void outgoingCallCreated(CallEvent event) - { - synchronized(this) - { - logger.debug( - "Collected evt("+collectedEvents.size()+")= "+event); - - this.collectedEvents.add(event); - notifyAll(); - } - - } - - /** - * Stores the received event and notifies all waiting on this object - * @param event the event containing the source call. - */ - public void callEnded(CallEvent event) - { - synchronized(this) - { - logger.debug( - "Collected evt("+collectedEvents.size()+")= "+event); - - this.collectedEvents.add(event); - notifyAll(); - } - } - } - - /** - * Allows tests to wait for and collect events issued upon call peer - * status changes. - */ - public class CallPeerStateEventCollector - extends CallPeerAdapter - { - public ArrayList collectedEvents = new ArrayList(); - private CallPeer listenedCallPeer = null; - public CallPeerState awaitedState = null; - - /** - * Creates an instance of this collector and adds it as a listener - * to callPeer. - * @param callPeer the CallPeer that we will be listening - * to. - * @param awaitedState the state that we will be waiting for inside - * this collector. - */ - public CallPeerStateEventCollector( - CallPeer callPeer, - CallPeerState awaitedState) - { - this.listenedCallPeer = callPeer; - this.listenedCallPeer.addCallPeerListener(this); - this.awaitedState = awaitedState; - } - - /** - * Stores the received event and notifies all waiting on this object - * - * @param event the event containing the source call. - */ - public void peerStateChanged(CallPeerChangeEvent event) - { - synchronized(this) - { - logger.debug( - "Collected evt("+collectedEvents.size()+")= "+event); - - if(((CallPeerState)event.getNewValue()) - .equals(awaitedState)) - { - this.collectedEvents.add(event); - notifyAll(); - } - } - } - - /** - * Blocks until an event notifying us of the awaited state change is - * received or until waitFor miliseconds pass (whichever happens first). - * - * @param waitFor the number of miliseconds that we should be waiting - * for an event before simply bailing out. - */ - public void waitForEvent(long waitFor) - { - waitForEvent(waitFor, false); - } - - /** - * Blocks until an event notifying us of the awaited state change is - * received or until waitFor miliseconds pass (whichever happens first). - * - * @param waitFor the number of miliseconds that we should be waiting - * for an event before simply bailing out. - * @param exitIfAlreadyInState specifies whether the method is to return - * if the call peer is already in such a state even if no event - * has been received for the sate change. - */ - public void waitForEvent(long waitFor, boolean exitIfAlreadyInState) - { - logger.trace("Waiting for a CallPeerEvent with newState=" - + awaitedState + " for peer " - + this.listenedCallPeer); - synchronized (this) - { - if(exitIfAlreadyInState - && listenedCallPeer.getState().equals(awaitedState)) - { - logger.trace("Src peer is already in the awaited " - + "state." - + collectedEvents); - listenedCallPeer.removeCallPeerListener(this); - return; - } - if(collectedEvents.size() > 0) - { - CallPeerChangeEvent lastEvent - = (CallPeerChangeEvent) collectedEvents - .get(collectedEvents.size() - 1); - - if (lastEvent.getNewValue().equals(awaitedState)) - { - logger.trace("Event already received. " + - collectedEvents); - listenedCallPeer - .removeCallPeerListener(this); - return; - } - } - try - { - wait(waitFor); - - if (collectedEvents.size() > 0) - logger.trace("Received a CallParticpantStateEvent."); - else - logger.trace("No CallParticpantStateEvent received for " - + waitFor + "ms."); - - listenedCallPeer - .removeCallPeerListener(this); - } - catch (InterruptedException ex) - { - logger.debug("Interrupted while waiting for a " - + "CallParticpantEvent" - , ex); - } - } - } - } - - /** - * Allows tests to wait for and collect events issued upon call state - * changes. - */ - public class CallStateEventCollector - extends CallChangeAdapter - { - public ArrayList collectedEvents = new ArrayList(); - private Call listenedCall = null; - public CallState awaitedState = null; - - /** - * Creates an instance of this collector and adds it as a listener - * to call. - * @param call the Call that we will be listening to. - * @param awaitedState the state that we will be waiting for inside - * this collector. - */ - public CallStateEventCollector(Call call, - CallState awaitedState) - { - this.listenedCall = call; - this.listenedCall.addCallChangeListener(this); - this.awaitedState = awaitedState; - } - - /** - * Stores the received event and notifies all waiting on this object - * - * @param event the event containing the source call. - */ - public void callStateChanged(CallChangeEvent event) - { - synchronized(this) - { - logger.debug( - "Collected evt("+collectedEvents.size()+")= "+event); - - if(((CallState)event.getNewValue()).equals(awaitedState)) - { - this.collectedEvents.add(event); - notifyAll(); - } - } - } - - /** - * Blocks until an event notifying us of the awaited state change is - * received or until waitFor miliseconds pass (whichever happens first). - * - * @param waitFor the number of miliseconds that we should be waiting - * for an event before simply bailing out. - */ - public void waitForEvent(long waitFor) - { - logger.trace("Waiting for a CallParticpantEvent"); - synchronized (this) - { - if (listenedCall.getCallState() == awaitedState) - { - logger.trace("Event already received. " + - collectedEvents); - listenedCall.removeCallChangeListener(this); - return; - } - - try - { - wait(waitFor); - - if (collectedEvents.size() > 0) - logger.trace("Received a CallChangeEvent."); - else - logger.trace("No CallChangeEvent received for " - + waitFor + "ms."); - - listenedCall.removeCallChangeListener(this); - } - catch (InterruptedException ex) - { - logger.debug("Interrupted while waiting for a " - + "CallParticpantEvent" - , ex); - } - } - } - } - -} +/* + * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package net.java.sip.communicator.slick.protocol.jabber; + +import junit.framework.*; +import net.java.sip.communicator.util.*; +import net.java.sip.communicator.service.protocol.*; +import java.text.ParseException; +import net.java.sip.communicator.service.protocol.event.*; +import java.util.*; + +/** + * Tests Basic telephony functionality by making one provider call the other. + * + * @author Emil Ivov + * @author Symphorien Wanko + */ +public class TestOperationSetBasicTelephonyJabberImpl + extends TestCase +{ + private static final Logger logger + = Logger.getLogger(TestOperationSetBasicTelephonyJabberImpl.class); + + /** + * Provides constants and some utilities method. + */ + private JabberSlickFixture fixture = new JabberSlickFixture(); + + /** + * Initializes the test with the specified name. + * + * @param name the name of the test to initialize. + */ + public TestOperationSetBasicTelephonyJabberImpl(String name) + { + super(name); + } + + /** + * JUnit setup method. + * @throws Exception in case anything goes wrong. + */ + protected void setUp() throws Exception + { + super.setUp(); + fixture.setUp(); + } + + /** + * JUnit teardown method. + * @throws Exception in case anything goes wrong. + */ + protected void tearDown() throws Exception + { + fixture.tearDown(); + super.tearDown(); + } + + /** + * Creates a call from provider1 to provider2 then cancels it without + * waiting for provider1 to answer. + * + * @throws ParseException if we hand a malformed URI to someone + * @throws OperationFailedException if something weird happens. + */ + public void testCreateCancelCall() + throws ParseException, OperationFailedException + { + OperationSetBasicTelephony basicTelephonyP1 + = fixture.provider1.getOperationSet( + OperationSetBasicTelephony.class); + OperationSetBasicTelephony basicTelephonyP2 + = fixture.provider2.getOperationSet( + OperationSetBasicTelephony.class); + + CallEventCollector call1Listener + = new CallEventCollector(basicTelephonyP1); + CallEventCollector call2Listener + = new CallEventCollector(basicTelephonyP2); + + //Provider1 calls Provider2 + String provider2Address + = fixture.provider2.getAccountID().getAccountAddress(); + + Call callAtP1 = basicTelephonyP1.createCall(provider2Address); + + call1Listener.waitForEvent(10000); + call2Listener.waitForEvent(10000); + + //make sure that both listeners have received their events. + assertEquals("The provider that created the call did not dispatch " + + "an event that it has done so." + , 1, call1Listener.collectedEvents.size()); + //call1 listener checks + CallEvent callCreatedEvent + = (CallEvent)call1Listener.collectedEvents.get(0); + + assertEquals("CallEvent.getEventID()" + ,CallEvent.CALL_INITIATED, callCreatedEvent.getEventID()); + assertSame("CallEvent.getSource()" + , callAtP1, callCreatedEvent.getSource()); + + //call2 listener checks + assertTrue("The callee provider did not receive a call or did " + +"not issue an event." + , call2Listener.collectedEvents.size() > 0); + CallEvent callReceivedEvent + = (CallEvent)call2Listener.collectedEvents.get(0); + Call callAtP2 = callReceivedEvent.getSourceCall(); + + assertEquals("CallEvent.getEventID()" + ,CallEvent.CALL_RECEIVED, callReceivedEvent.getEventID()); + assertNotNull("CallEvent.getSource()", callAtP2); + + //verify that call peers are properly created + assertEquals("callAtP1.getCallPeerCount()" + , 1, callAtP1.getCallPeerCount()); + assertEquals("callAtP2.getCallPeerCount()" + , 1, callAtP2.getCallPeerCount()); + + CallPeer peerAtP1 = callAtP1.getCallPeers().next(); + CallPeer peerAtP2 = callAtP2.getCallPeers().next(); + + //now add listeners to the peers and make sure they have entered + //the states they were expected to. + //check states for call peers at both parties + CallPeerStateEventCollector stateCollectorForPp1 + = new CallPeerStateEventCollector( + peerAtP1, CallPeerState.ALERTING_REMOTE_SIDE); + CallPeerStateEventCollector stateCollectorForPp2 + = new CallPeerStateEventCollector( + peerAtP2, CallPeerState.INCOMING_CALL); + + stateCollectorForPp1.waitForEvent(10000, true); + stateCollectorForPp2.waitForEvent(10000, true); + + assertSame("peerAtP1.getCall" + , peerAtP1.getCall(), callAtP1); + assertSame("peerAtP2.getCall" + , peerAtP2.getCall(), callAtP2); + + //make sure that the peers are in the proper state + assertEquals("The peer at provider one was not in the " + +"right state." + , CallPeerState.ALERTING_REMOTE_SIDE + , peerAtP1.getState()); + assertEquals("The peer at provider two was not in the " + +"right state." + , CallPeerState.INCOMING_CALL + , peerAtP2.getState()); + + + //test whether caller/callee info is properly distributed in case + //the server is said to support it. + if(Boolean.getBoolean("accounts.jabber.PRESERVE_PEER_INFO")) + { + //check properties on the remote call peer for the party that + //initiated the call. + String expectedPeer1Address + = fixture.provider2.getAccountID().getAccountAddress(); + String expectedPeer1DisplayName + = System.getProperty( + JabberProtocolProviderServiceLick.ACCOUNT_2_PREFIX + + ProtocolProviderFactory.DISPLAY_NAME); + + //do not asser equals here since one of the addresses may contain a + //display name or something of the kind + assertTrue("Provider 2 did not advertise their " + + "accountID.getAccoutAddress() address." + , expectedPeer1Address.indexOf( + peerAtP1.getAddress()) != -1 + || peerAtP1.getAddress().indexOf( + expectedPeer1Address) != -1); + assertEquals("Provider 2 did not properly advertise their " + + "display name." + , expectedPeer1DisplayName + , peerAtP1.getDisplayName()); + + //check properties on the remote call peer for the party that + //receives the call. + String expectedPeer2Address + = fixture.provider1.getAccountID().getAccountAddress(); + String expectedPeer2DisplayName + = System.getProperty( + JabberProtocolProviderServiceLick.ACCOUNT_1_PREFIX + + ProtocolProviderFactory.DISPLAY_NAME); + + //do not asser equals here since one of the addresses may contain a + //display name or something of the kind + assertTrue("Provider 1 did not advertise their " + + "accountID.getAccoutAddress() address." + , expectedPeer2Address.indexOf( + peerAtP2.getAddress()) != -1 + || peerAtP2.getAddress().indexOf( + expectedPeer2Address) != -1); + assertEquals("Provider 1 did not properly advertise their " + + "display name." + , expectedPeer2DisplayName + , peerAtP2.getDisplayName()); + } + + //we'll now try to cancel the call + + //listeners monitoring state change of the peer + stateCollectorForPp1 = new CallPeerStateEventCollector( + peerAtP1, CallPeerState.DISCONNECTED); + stateCollectorForPp2 = new CallPeerStateEventCollector( + peerAtP2, CallPeerState.DISCONNECTED); + + //listeners waiting for the op set to announce the end of the call + call1Listener = new CallEventCollector(basicTelephonyP1); + call2Listener = new CallEventCollector(basicTelephonyP2); + + //listeners monitoring the state of the call + CallStateEventCollector call1StateCollector + = new CallStateEventCollector(callAtP1, CallState.CALL_ENDED); + CallStateEventCollector call2StateCollector + = new CallStateEventCollector(callAtP2, CallState.CALL_ENDED); + + //Now make the caller CANCEL the call. + basicTelephonyP1.hangupCallPeer(peerAtP1); + + //wait for everything to happen + call1Listener.waitForEvent(10000); + call2Listener.waitForEvent(10000); + stateCollectorForPp1.waitForEvent(10000); + stateCollectorForPp2.waitForEvent(10000); + call1StateCollector.waitForEvent(10000); + call2StateCollector.waitForEvent(10000); + + + //make sure that the peer is disconnected + assertEquals("The peer at provider one was not in the " + +"right state." + , CallPeerState.DISCONNECTED + , peerAtP1.getState()); + + //make sure the telephony operation set distributed an event for the end + //of the call + assertEquals("The basic telephony operation set did not distribute " + +"an event to notify us that a call has been ended." + , 1 + , call1Listener.collectedEvents.size()); + + CallEvent collectedEvent + = (CallEvent)call1Listener.collectedEvents.get(0); + + assertEquals("The basic telephony operation set did not distribute " + +"an event to notify us that a call has been ended." + , CallEvent.CALL_ENDED + , collectedEvent.getEventID()); + + //same for provider 2 + + //make sure that the peer is disconnected + assertEquals("The peer at provider one was not in the " + +"right state." + , CallPeerState.DISCONNECTED + , peerAtP2.getState()); + + //make sure the telephony operation set distributed an event for the end + //of the call + assertEquals("The basic telephony operation set did not distribute " + +"an event to notify us that a call has been ended." + , 1 + , call2Listener.collectedEvents.size()); + + collectedEvent + = (CallEvent)call2Listener.collectedEvents.get(0); + + assertEquals("The basic telephony operation set did not distribute " + +"an event to notify us that a call has been ended." + , CallEvent.CALL_ENDED + , collectedEvent.getEventID()); + + //make sure that the call objects are in an ENDED state. + assertEquals("A call did not change its state to CallState.CALL_ENDED " + +"when it ended." + , CallState.CALL_ENDED + , callAtP1.getCallState()); + assertEquals("A call did not change its state to CallState.CALL_ENDED " + +"when it ended." + , CallState.CALL_ENDED + , callAtP2.getCallState()); + } + + /** + * Creates a call from provider1 to provider2 then rejects the call from the + * side of provider2 (provider2 replies with busy-tone). + * + * @throws ParseException if we hand a malformed URI to someone + * @throws OperationFailedException if something weird happens. + */ + public void testCreateRejectCall() + throws ParseException, OperationFailedException + { + OperationSetBasicTelephony basicTelephonyP1 + = fixture.provider1.getOperationSet( + OperationSetBasicTelephony.class); + OperationSetBasicTelephony basicTelephonyP2 + = fixture.provider2.getOperationSet( + OperationSetBasicTelephony.class); + + CallEventCollector call1Listener + = new CallEventCollector(basicTelephonyP1); + CallEventCollector call2Listener + = new CallEventCollector(basicTelephonyP2); + + //Provider1 calls Provider2 + String provider2Address + = fixture.provider2.getAccountID().getAccountAddress(); + + Call callAtP1 = basicTelephonyP1.createCall(provider2Address); + + call1Listener.waitForEvent(10000); + call2Listener.waitForEvent(10000); + + //make sure that both listeners have received their events. + assertEquals("The provider that created the call did not dispatch " + + "an event that it has done so." + , 1, call1Listener.collectedEvents.size()); + //call1 listener checks + CallEvent callCreatedEvent + = (CallEvent)call1Listener.collectedEvents.get(0); + + assertEquals("CallEvent.getEventID()" + ,CallEvent.CALL_INITIATED, callCreatedEvent.getEventID()); + assertSame("CallEvent.getSource()" + , callAtP1, callCreatedEvent.getSource()); + + //call2 listener checks + assertTrue("The callee provider did not receive a call or did " + +"not issue an event." + , call2Listener.collectedEvents.size() > 0); + CallEvent callReceivedEvent + = (CallEvent)call2Listener.collectedEvents.get(0); + Call callAtP2 = callReceivedEvent.getSourceCall(); + + assertEquals("CallEvent.getEventID()" + ,CallEvent.CALL_RECEIVED, callReceivedEvent.getEventID()); + assertNotNull("CallEvent.getSource()", callAtP2); + + //verify that call peers are properly created + assertEquals("callAtP1.getCallPeerCount()" + , 1, callAtP1.getCallPeerCount()); + assertEquals("callAtP2.getCallPeerCount()" + , 1, callAtP2.getCallPeerCount()); + + CallPeer peerAtP1 = callAtP1.getCallPeers().next(); + CallPeer peerAtP2 = callAtP2.getCallPeers().next(); + + //now add listeners to the peers and make sure they have entered + //the states they were expected to. + //check states for call peers at both parties + CallPeerStateEventCollector stateCollectorForPp1 + = new CallPeerStateEventCollector( + peerAtP1, CallPeerState.ALERTING_REMOTE_SIDE); + CallPeerStateEventCollector stateCollectorForPp2 + = new CallPeerStateEventCollector( + peerAtP2, CallPeerState.INCOMING_CALL); + + stateCollectorForPp1.waitForEvent(10000, true); + stateCollectorForPp2.waitForEvent(10000, true); + + assertSame("peerAtP1.getCall" + , peerAtP1.getCall(), callAtP1); + assertSame("peerAtP2.getCall" + , peerAtP2.getCall(), callAtP2); + + //make sure that the peers are in the proper state + assertEquals("The peer at provider one was not in the " + +"right state." + , CallPeerState.ALERTING_REMOTE_SIDE + , peerAtP1.getState()); + assertEquals("The peer at provider two was not in the " + +"right state." + , CallPeerState.INCOMING_CALL + , peerAtP2.getState()); + + + //test whether caller/callee info is properly distributed in case + //the server is said to support it. + if(Boolean.getBoolean("accounts.jabber.PRESERVE_PEER_INFO")) + { + //check properties on the remote call peer for the party that + //initiated the call. + String expectedPeer1Address + = fixture.provider2.getAccountID().getAccountAddress(); + String expectedPeer1DisplayName + = System.getProperty( + JabberProtocolProviderServiceLick.ACCOUNT_2_PREFIX + + ProtocolProviderFactory.DISPLAY_NAME); + + //do not asser equals here since one of the addresses may contain a + //display name or something of the kind + assertTrue("Provider 2 did not advertise their " + + "accountID.getAccoutAddress() address." + , expectedPeer1Address.indexOf( + peerAtP1.getAddress()) != -1 + || peerAtP1.getAddress().indexOf( + expectedPeer1Address) != -1); + assertEquals("Provider 2 did not properly advertise their " + + "display name." + , expectedPeer1DisplayName + , peerAtP1.getDisplayName()); + + //check properties on the remote call peer for the party that + //receives the call. + String expectedPeer2Address + = fixture.provider1.getAccountID().getAccountAddress(); + String expectedPeer2DisplayName + = System.getProperty( + JabberProtocolProviderServiceLick.ACCOUNT_1_PREFIX + + ProtocolProviderFactory.DISPLAY_NAME); + + //do not asser equals here since one of the addresses may contain a + //display name or something of the kind + assertTrue("Provider 1 did not advertise their " + + "accountID.getAccoutAddress() address." + , expectedPeer2Address.indexOf( + peerAtP2.getAddress()) != -1 + || peerAtP2.getAddress().indexOf( + expectedPeer2Address) != -1); + assertEquals("Provider 1 did not properly advertise their " + + "display name." + , expectedPeer2DisplayName + , peerAtP2.getDisplayName()); + } + + //we'll now try to send busy tone. + + //listeners monitoring state change of the peer + CallPeerStateEventCollector busyStateCollectorForPp1 + = new CallPeerStateEventCollector( + peerAtP1, CallPeerState.BUSY); + stateCollectorForPp1 = new CallPeerStateEventCollector( + peerAtP1, CallPeerState.DISCONNECTED); + stateCollectorForPp2 = new CallPeerStateEventCollector( + peerAtP2, CallPeerState.DISCONNECTED); + + //listeners waiting for the op set to announce the end of the call + call1Listener = new CallEventCollector(basicTelephonyP1); + call2Listener = new CallEventCollector(basicTelephonyP2); + + //listeners monitoring the state of the call + CallStateEventCollector call1StateCollector + = new CallStateEventCollector(callAtP1, CallState.CALL_ENDED); + CallStateEventCollector call2StateCollector + = new CallStateEventCollector(callAtP2, CallState.CALL_ENDED); + + //Now make the caller CANCEL the call. + basicTelephonyP2.hangupCallPeer(peerAtP2); + busyStateCollectorForPp1.waitForEvent(10000); + basicTelephonyP1.hangupCallPeer(peerAtP1); + + //wait for everything to happen + call1Listener.waitForEvent(10000); + call2Listener.waitForEvent(10000); + stateCollectorForPp1.waitForEvent(10000); + stateCollectorForPp2.waitForEvent(10000); + call1StateCollector.waitForEvent(10000); + call2StateCollector.waitForEvent(10000); + + + //make sure that the peer is disconnected + assertEquals("The peer at provider one was not in the " + +"right state." + , CallPeerState.DISCONNECTED + , peerAtP1.getState()); + + + + //make sure the telephony operation set distributed an event for the end + //of the call + assertEquals("The basic telephony operation set did not distribute " + +"an event to notify us that a call has been ended." + , 1 + , call1Listener.collectedEvents.size()); + + CallEvent collectedEvent + = (CallEvent)call1Listener.collectedEvents.get(0); + + assertEquals("The basic telephony operation set did not distribute " + +"an event to notify us that a call has been ended." + , CallEvent.CALL_ENDED + , collectedEvent.getEventID()); + + //same for provider 2 + + //make sure that the peer is disconnected + assertEquals("The peer at provider one was not in the " + +"right state." + , CallPeerState.DISCONNECTED + , peerAtP2.getState()); + + //make sure the telephony operation set distributed an event for the end + //of the call + assertEquals("The basic telephony operation set did not distribute " + +"an event to notify us that a call has been ended." + , 1 + , call2Listener.collectedEvents.size()); + + collectedEvent + = (CallEvent)call2Listener.collectedEvents.get(0); + + assertEquals("The basic telephony operation set did not distribute " + +"an event to notify us that a call has been ended." + , CallEvent.CALL_ENDED + , collectedEvent.getEventID()); + + //make sure that the call objects are in an ENDED state. + assertEquals("A call did not change its state to CallState.CALL_ENDED " + +"when it ended." + , CallState.CALL_ENDED + , callAtP1.getCallState()); + assertEquals("A call did not change its state to CallState.CALL_ENDED " + +"when it ended." + , CallState.CALL_ENDED + , callAtP2.getCallState()); + } + + /** + * Creates a call from provider1 to provider2, makes provider2 answer it + * and then reject it. + * + * @throws ParseException if we hand a malformed URI to someone + * @throws OperationFailedException if something weird happens. + */ + public void aTestCreateAnswerHangupCall() + throws ParseException, OperationFailedException + { + OperationSetBasicTelephony basicTelephonyP1 + = fixture.provider1.getOperationSet( + OperationSetBasicTelephony.class); + OperationSetBasicTelephony basicTelephonyP2 + = fixture.provider2.getOperationSet( + OperationSetBasicTelephony.class); + + CallEventCollector call1Listener + = new CallEventCollector(basicTelephonyP1); + CallEventCollector call2Listener + = new CallEventCollector(basicTelephonyP2); + + //Provider1 calls Provider2 + String provider2Address + = fixture.provider2.getAccountID().getAccountAddress(); + + Call callAtP1 = basicTelephonyP1.createCall(provider2Address); + + call1Listener.waitForEvent(10000); + call2Listener.waitForEvent(10000); + + //make sure that both listeners have received their events. + assertEquals("The provider that created the call did not dispatch " + + "an event that it has done so." + , 1, call1Listener.collectedEvents.size()); + //call1 listener checks + CallEvent callCreatedEvent + = (CallEvent)call1Listener.collectedEvents.get(0); + + assertEquals("CallEvent.getEventID()" + ,CallEvent.CALL_INITIATED, callCreatedEvent.getEventID()); + assertSame("CallEvent.getSource()" + , callAtP1, callCreatedEvent.getSource()); + + //call2 listener checks + assertTrue("The callee provider did not receive a call or did " + +"not issue an event." + , call2Listener.collectedEvents.size() > 0); + CallEvent callReceivedEvent + = (CallEvent)call2Listener.collectedEvents.get(0); + Call callAtP2 = callReceivedEvent.getSourceCall(); + + assertEquals("CallEvent.getEventID()" + ,CallEvent.CALL_RECEIVED, callReceivedEvent.getEventID()); + assertNotNull("CallEvent.getSource()", callAtP2); + + //verify that call peers are properly created + assertEquals("callAtP1.getCallPeerCount()" + , 1, callAtP1.getCallPeerCount()); + assertEquals("callAtP2.getCallPeerCount()" + , 1, callAtP2.getCallPeerCount()); + + CallPeer peerAtP1 = callAtP1.getCallPeers().next(); + CallPeer peerAtP2 = callAtP2.getCallPeers().next(); + + //now add listeners to the peers and make sure they have entered + //the states they were expected to. + //check states for call peers at both parties + CallPeerStateEventCollector stateCollectorForPp1 + = new CallPeerStateEventCollector( + peerAtP1, CallPeerState.ALERTING_REMOTE_SIDE); + CallPeerStateEventCollector stateCollectorForPp2 + = new CallPeerStateEventCollector( + peerAtP2, CallPeerState.INCOMING_CALL); + + stateCollectorForPp1.waitForEvent(10000, true); + stateCollectorForPp2.waitForEvent(10000, true); + + assertSame("peerAtP1.getCall" + , peerAtP1.getCall(), callAtP1); + assertSame("peerAtP2.getCall" + , peerAtP2.getCall(), callAtP2); + + //make sure that the peers are in the proper state + assertEquals("The peer at provider one was not in the " + +"right state." + , CallPeerState.ALERTING_REMOTE_SIDE + , peerAtP1.getState()); + assertEquals("The peer at provider two was not in the " + +"right state." + , CallPeerState.INCOMING_CALL + , peerAtP2.getState()); + + + //test whether caller/callee info is properly distributed in case + //the server is said to support it. + if(Boolean.getBoolean("accounts.jabber.PRESERVE_PEER_INFO")) + { + //check properties on the remote call peer for the party that + //initiated the call. + String expectedPeer1Address + = fixture.provider2.getAccountID().getAccountAddress(); + String expectedPeer1DisplayName + = System.getProperty( + JabberProtocolProviderServiceLick.ACCOUNT_2_PREFIX + + ProtocolProviderFactory.DISPLAY_NAME); + + //do not assert equals here since one of the addresses may contain a + //display name or something of the kind + assertTrue("Provider 2 did not advertise their " + + "accountID.getAccoutAddress() address." + , expectedPeer1Address.indexOf( + peerAtP1.getAddress()) != -1 + || peerAtP1.getAddress().indexOf( + expectedPeer1Address) != -1); + assertEquals("Provider 2 did not properly advertise their " + + "display name." + , expectedPeer1DisplayName + , peerAtP1.getDisplayName()); + + //check properties on the remote call peer for the party that + //receives the call. + String expectedPeer2Address + = fixture.provider1.getAccountID().getAccountAddress(); + String expectedPeer2DisplayName + = System.getProperty( + JabberProtocolProviderServiceLick.ACCOUNT_1_PREFIX + + ProtocolProviderFactory.DISPLAY_NAME); + + //do not asser equals here since one of the addresses may contain a + //display name or something of the kind + assertTrue("Provider 1 did not advertise their " + + "accountID.getAccoutAddress() address." + , expectedPeer2Address.indexOf( + peerAtP2.getAddress()) != -1 + || peerAtP2.getAddress().indexOf( + expectedPeer2Address) != -1); + assertEquals("Provider 1 did not properly advertise their " + + "display name." + , expectedPeer2DisplayName + , peerAtP2.getDisplayName()); + } + + //add listeners to the peers and make sure enter + //a connected state after we answer + stateCollectorForPp1 + = new CallPeerStateEventCollector( + peerAtP1, CallPeerState.CONNECTED); + stateCollectorForPp2 + = new CallPeerStateEventCollector( + peerAtP2, CallPeerState.CONNECTED); + + //we will now anser the call and verify that both parties change states + //accordingly. + basicTelephonyP2.answerCallPeer(peerAtP2); + + stateCollectorForPp1.waitForEvent(10000); + stateCollectorForPp2.waitForEvent(10000); + + //make sure that the peers are in the proper state + assertEquals("The peer at provider one was not in the " + +"right state." + , CallPeerState.CONNECTED + , peerAtP1.getState()); + assertEquals("The peer at provider two was not in the " + +"right state." + , CallPeerState.CONNECTED + , peerAtP2.getState()); + + //make sure that events have been distributed when states were changed. + assertEquals("No event was dispatched when a call peer changed " + +"its state." + , 1 + , stateCollectorForPp1.collectedEvents.size()); + assertEquals("No event was dispatched when a call peer changed " + +"its state." + , 1 + , stateCollectorForPp2.collectedEvents.size()); + + //add listeners to the peers and make sure they have entered + //the states they are expected to. + stateCollectorForPp1 + = new CallPeerStateEventCollector( + peerAtP1, CallPeerState.DISCONNECTED); + stateCollectorForPp2 + = new CallPeerStateEventCollector( + peerAtP2, CallPeerState.DISCONNECTED); + + //we will now end the call and verify that both parties change states + //accordingly. + basicTelephonyP2.hangupCallPeer(peerAtP2); + + stateCollectorForPp1.waitForEvent(10000); + stateCollectorForPp2.waitForEvent(10000); + + //make sure that the peers are in the proper state + assertEquals("The peer at provider one was not in the " + +"right state." + , CallPeerState.DISCONNECTED + , peerAtP1.getState()); + assertEquals("The peer at provider two was not in the " + +"right state." + , CallPeerState.DISCONNECTED + , peerAtP2.getState()); + + //make sure that the corresponding events were delivered. + assertEquals("a provider did not distribute an event when a call " + +"peer changed states." + , 1 + , stateCollectorForPp1.collectedEvents.size()); + assertEquals("a provider did not distribute an event when a call " + +"peer changed states." + , 1 + , stateCollectorForPp2.collectedEvents.size()); + + } + + /** + * Allows tests to wait for and collect events issued upon creation and + * reception of calls. + */ + public class CallEventCollector implements CallListener + { + public ArrayList collectedEvents = new ArrayList(); + public OperationSetBasicTelephony listenedOpSet = null; + + /** + * Creates an instance of this call event collector and registers it + * with listenedOpSet. + * @param listenedOpSet the operation set that we will be scanning for + * new calls. + */ + public CallEventCollector(OperationSetBasicTelephony listenedOpSet) + { + this.listenedOpSet = listenedOpSet; + this.listenedOpSet.addCallListener(this); + } + + /** + * Blocks until at least one event is received or until waitFor + * miliseconds pass (whichever happens first). + * + * @param waitFor the number of miliseconds that we should be waiting + * for an event before simply bailing out. + */ + public void waitForEvent(long waitFor) + { + logger.trace("Waiting for a CallEvent"); + + synchronized(this) + { + if(collectedEvents.size() > 0){ + logger.trace("Event already received. " + collectedEvents); + listenedOpSet.removeCallListener(this); + return; + } + + try{ + wait(waitFor); + if(collectedEvents.size() > 0) + logger.trace("Received a CallEvent."); + else + logger.trace("No CallEvent received for "+waitFor+"ms."); + + listenedOpSet.removeCallListener(this); + } + catch (InterruptedException ex) + { + logger.debug( + "Interrupted while waiting for a call event", ex); + } + } + } + + /** + * Stores the received event and notifies all waiting on this object + * @param event the event containing the source call. + */ + public void incomingCallReceived(CallEvent event) + { + synchronized(this) + { + logger.debug( + "Collected evt("+collectedEvents.size()+")= "+event); + + this.collectedEvents.add(event); + notifyAll(); + } + } + + /** + * Stores the received event and notifies all waiting on this object + * @param event the event containing the source call. + */ + public void outgoingCallCreated(CallEvent event) + { + synchronized(this) + { + logger.debug( + "Collected evt("+collectedEvents.size()+")= "+event); + + this.collectedEvents.add(event); + notifyAll(); + } + + } + + /** + * Stores the received event and notifies all waiting on this object + * @param event the event containing the source call. + */ + public void callEnded(CallEvent event) + { + synchronized(this) + { + logger.debug( + "Collected evt("+collectedEvents.size()+")= "+event); + + this.collectedEvents.add(event); + notifyAll(); + } + } + } + + /** + * Allows tests to wait for and collect events issued upon call peer + * status changes. + */ + public class CallPeerStateEventCollector + extends CallPeerAdapter + { + public ArrayList collectedEvents = new ArrayList(); + private CallPeer listenedCallPeer = null; + public CallPeerState awaitedState = null; + + /** + * Creates an instance of this collector and adds it as a listener + * to callPeer. + * @param callPeer the CallPeer that we will be listening + * to. + * @param awaitedState the state that we will be waiting for inside + * this collector. + */ + public CallPeerStateEventCollector( + CallPeer callPeer, + CallPeerState awaitedState) + { + this.listenedCallPeer = callPeer; + this.listenedCallPeer.addCallPeerListener(this); + this.awaitedState = awaitedState; + } + + /** + * Stores the received event and notifies all waiting on this object + * + * @param event the event containing the source call. + */ + public void peerStateChanged(CallPeerChangeEvent event) + { + synchronized(this) + { + logger.debug( + "Collected evt("+collectedEvents.size()+")= "+event); + + if(((CallPeerState)event.getNewValue()) + .equals(awaitedState)) + { + this.collectedEvents.add(event); + notifyAll(); + } + } + } + + /** + * Blocks until an event notifying us of the awaited state change is + * received or until waitFor miliseconds pass (whichever happens first). + * + * @param waitFor the number of miliseconds that we should be waiting + * for an event before simply bailing out. + */ + public void waitForEvent(long waitFor) + { + waitForEvent(waitFor, false); + } + + /** + * Blocks until an event notifying us of the awaited state change is + * received or until waitFor miliseconds pass (whichever happens first). + * + * @param waitFor the number of miliseconds that we should be waiting + * for an event before simply bailing out. + * @param exitIfAlreadyInState specifies whether the method is to return + * if the call peer is already in such a state even if no event + * has been received for the sate change. + */ + public void waitForEvent(long waitFor, boolean exitIfAlreadyInState) + { + logger.trace("Waiting for a CallPeerEvent with newState=" + + awaitedState + " for peer " + + this.listenedCallPeer); + synchronized (this) + { + if(exitIfAlreadyInState + && listenedCallPeer.getState().equals(awaitedState)) + { + logger.trace("Src peer is already in the awaited " + + "state." + + collectedEvents); + listenedCallPeer.removeCallPeerListener(this); + return; + } + if(collectedEvents.size() > 0) + { + CallPeerChangeEvent lastEvent + = (CallPeerChangeEvent) collectedEvents + .get(collectedEvents.size() - 1); + + if (lastEvent.getNewValue().equals(awaitedState)) + { + logger.trace("Event already received. " + + collectedEvents); + listenedCallPeer + .removeCallPeerListener(this); + return; + } + } + try + { + wait(waitFor); + + if (collectedEvents.size() > 0) + logger.trace("Received a CallParticpantStateEvent."); + else + logger.trace("No CallParticpantStateEvent received for " + + waitFor + "ms."); + + listenedCallPeer + .removeCallPeerListener(this); + } + catch (InterruptedException ex) + { + logger.debug("Interrupted while waiting for a " + + "CallParticpantEvent" + , ex); + } + } + } + } + + /** + * Allows tests to wait for and collect events issued upon call state + * changes. + */ + public class CallStateEventCollector + extends CallChangeAdapter + { + public ArrayList collectedEvents = new ArrayList(); + private Call listenedCall = null; + public CallState awaitedState = null; + + /** + * Creates an instance of this collector and adds it as a listener + * to call. + * @param call the Call that we will be listening to. + * @param awaitedState the state that we will be waiting for inside + * this collector. + */ + public CallStateEventCollector(Call call, + CallState awaitedState) + { + this.listenedCall = call; + this.listenedCall.addCallChangeListener(this); + this.awaitedState = awaitedState; + } + + /** + * Stores the received event and notifies all waiting on this object + * + * @param event the event containing the source call. + */ + public void callStateChanged(CallChangeEvent event) + { + synchronized(this) + { + logger.debug( + "Collected evt("+collectedEvents.size()+")= "+event); + + if(((CallState)event.getNewValue()).equals(awaitedState)) + { + this.collectedEvents.add(event); + notifyAll(); + } + } + } + + /** + * Blocks until an event notifying us of the awaited state change is + * received or until waitFor miliseconds pass (whichever happens first). + * + * @param waitFor the number of miliseconds that we should be waiting + * for an event before simply bailing out. + */ + public void waitForEvent(long waitFor) + { + logger.trace("Waiting for a CallParticpantEvent"); + synchronized (this) + { + if (listenedCall.getCallState() == awaitedState) + { + logger.trace("Event already received. " + + collectedEvents); + listenedCall.removeCallChangeListener(this); + return; + } + + try + { + wait(waitFor); + + if (collectedEvents.size() > 0) + logger.trace("Received a CallChangeEvent."); + else + logger.trace("No CallChangeEvent received for " + + waitFor + "ms."); + + listenedCall.removeCallChangeListener(this); + } + catch (InterruptedException ex) + { + logger.debug("Interrupted while waiting for a " + + "CallParticpantEvent" + , ex); + } + } + } + } + +} diff --git a/test/net/java/sip/communicator/slick/protocol/sip/TestOperationSetBasicTelephonySipImpl.java b/test/net/java/sip/communicator/slick/protocol/sip/TestOperationSetBasicTelephonySipImpl.java index 4e607b703..26476fb13 100644 --- a/test/net/java/sip/communicator/slick/protocol/sip/TestOperationSetBasicTelephonySipImpl.java +++ b/test/net/java/sip/communicator/slick/protocol/sip/TestOperationSetBasicTelephonySipImpl.java @@ -70,10 +70,10 @@ public void testCreateCancelCall() throws ParseException, OperationFailedException { OperationSetBasicTelephony basicTelephonyP1 - = (OperationSetBasicTelephony)fixture.provider1.getOperationSet( + = fixture.provider1.getOperationSet( OperationSetBasicTelephony.class); OperationSetBasicTelephony basicTelephonyP2 - = (OperationSetBasicTelephony)fixture.provider2.getOperationSet( + = fixture.provider2.getOperationSet( OperationSetBasicTelephony.class); CallEventCollector call1Listener @@ -300,10 +300,10 @@ public void testCreateRejectCall() throws ParseException, OperationFailedException { OperationSetBasicTelephony basicTelephonyP1 - = (OperationSetBasicTelephony)fixture.provider1.getOperationSet( + = fixture.provider1.getOperationSet( OperationSetBasicTelephony.class); OperationSetBasicTelephony basicTelephonyP2 - = (OperationSetBasicTelephony)fixture.provider2.getOperationSet( + = fixture.provider2.getOperationSet( OperationSetBasicTelephony.class); CallEventCollector call1Listener @@ -537,10 +537,10 @@ public void aTestCreateAnswerHangupCall() throws ParseException, OperationFailedException { OperationSetBasicTelephony basicTelephonyP1 - = (OperationSetBasicTelephony)fixture.provider1.getOperationSet( + = fixture.provider1.getOperationSet( OperationSetBasicTelephony.class); OperationSetBasicTelephony basicTelephonyP2 - = (OperationSetBasicTelephony)fixture.provider2.getOperationSet( + = fixture.provider2.getOperationSet( OperationSetBasicTelephony.class); CallEventCollector call1Listener