[sip-comm-dev] Re: svn commit: r5964 - trunk/src/net/java/sip/communicator: impl/gui/main impl/gui/main/chat impl/gui/main/chat/conference impl/gui/main/chatroomslist...


#1

Hello Valentin and Yana,

Congratulations on the great work! I do mean not only the large amount of code written but also the continuous dedication which was expressed on this mailing list in the respective thread. You rock!

I hope you will not mind me sharing a few observations while reviewing r5964.

I still haven't finished the review so I'll just start with ChatAlerterActivator and its new method #messageReceived(AdHocChatRoomMessageReceivedEvent). The problem is that the implementation of this method is anything but new. This same implementation was already found in two separate methods in this same class and I replaced the duplication with #alertChatWindow(). I imagine the copy was made while there was still a duplication in trunk (which turns out to be called triplication) but it's still not a reason to do it. Please note that having three methods that do one and the same thing makes a class larger than necessary, hinders maintenance because changes to it has to be performed multiple times (you may notice that I've spared two null checks in #alertChatWindow()) and, most importantly, each of them needs to pass the JIT compiler invocation threshold before the decision is taken for them to be compiled into native code (in contrast replacing these three methods with #alertChatWindow() provides an optimization for all three regardless of which one is called the most often).

Best regards,
Lubomir

···

On 14.09.2009 18:51, yanas@dev.java.net wrote:

Author: yanas
Date: 2009-09-14 15:51:47+0000
New Revision: 5964

Added:
    trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocChatRoomProviderWrapper.java
    trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocChatRoomWrapper.java
    trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocConferenceChatContact.java
    trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocConferenceChatSession.java
    trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocConferenceChatTransport.java
    trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/AdHocChatRoomList.java
    trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/AdHocChatRoomListChangeEvent.java
    trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/AdHocChatRoomListChangeListener.java
    trunk/src/net/java/sip/communicator/impl/protocol/icq/AdHocChatRoomIcqImpl.java
    trunk/src/net/java/sip/communicator/impl/protocol/icq/AdHocChatRoomInvitationIcqImpl.java
    trunk/src/net/java/sip/communicator/impl/protocol/icq/OperationSetAdHocMultiUserChatIcqImpl.java
    trunk/src/net/java/sip/communicator/impl/protocol/msn/AdHocChatRoomInvitationMsnImpl.java (contents, props changed)
       - copied, changed from r5898, /trunk/src/net/java/sip/communicator/impl/protocol/msn/ChatRoomInvitationMsnImpl.java
    trunk/src/net/java/sip/communicator/impl/protocol/msn/AdHocChatRoomMsnImpl.java
    trunk/src/net/java/sip/communicator/impl/protocol/msn/OperationSetAdHocMultiUserChatMsnImpl.java
    trunk/src/net/java/sip/communicator/impl/protocol/yahoo/AdHocChatRoomInvitationYahooImpl.java
    trunk/src/net/java/sip/communicator/impl/protocol/yahoo/AdHocChatRoomYahooImpl.java
    trunk/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetAdHocMultiUserChatYahooImpl.java
    trunk/src/net/java/sip/communicator/service/protocol/AdHocChatRoom.java
    trunk/src/net/java/sip/communicator/service/protocol/AdHocChatRoomInvitation.java
    trunk/src/net/java/sip/communicator/service/protocol/OperationSetAdHocMultiUserChat.java
    trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomCreatedEvent.java
    trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomDestroyedEvent.java
    trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationListener.java
    trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationReceivedEvent.java
    trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationRejectedEvent.java
    trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationRejectionListener.java
    trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomListener.java
    trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageDeliveredEvent.java
    trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageDeliveryFailedEvent.java
    trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageListener.java
    trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageReceivedEvent.java
    trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomParticipantPresenceChangeEvent.java
    trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomParticipantPresenceListener.java
    trunk/src/net/java/sip/communicator/service/protocol/event/LocalUserAdHocChatRoomPresenceChangeEvent.java
    trunk/src/net/java/sip/communicator/service/protocol/event/LocalUserAdHocChatRoomPresenceListener.java
Removed:
    trunk/src/net/java/sip/communicator/impl/protocol/icq/ChatRoomIcqImpl.java
    trunk/src/net/java/sip/communicator/impl/protocol/icq/ChatRoomInvitationIcqImpl.java
    trunk/src/net/java/sip/communicator/impl/protocol/icq/ChatRoomMemberIcqImpl.java
    trunk/src/net/java/sip/communicator/impl/protocol/icq/OperationSetMultiUserChatIcqImpl.java
    trunk/src/net/java/sip/communicator/impl/protocol/msn/ChatRoomInvitationMsnImpl.java
    trunk/src/net/java/sip/communicator/impl/protocol/msn/ChatRoomMemberMsnImpl.java
    trunk/src/net/java/sip/communicator/impl/protocol/msn/ChatRoomMsnImpl.java
    trunk/src/net/java/sip/communicator/impl/protocol/msn/OperationSetMultiUserChatMsnImpl.java
    trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ChatRoomInvitationYahooImpl.java
    trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ChatRoomMemberYahooImpl.java
    trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ChatRoomYahooImpl.java
    trunk/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetMultiUserChatYahooImpl.java
Modified:
    trunk/src/net/java/sip/communicator/impl/gui/main/MainFrame.java
    trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java
    trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindow.java
    trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindowManager.java
    trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatContact.java
    trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatManager.java
    trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/InvitationReceivedDialog.java
    trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomList.java
    trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomListUI.java
    trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/createforms/CreateChatRoomDialog.java
    trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/createforms/CreateChatRoomWizard.java
    trunk/src/net/java/sip/communicator/impl/gui/main/login/LoginManager.java
    trunk/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java
    trunk/src/net/java/sip/communicator/impl/protocol/facebook/FacebookUser.java
    trunk/src/net/java/sip/communicator/impl/protocol/icq/ProtocolProviderServiceIcqImpl.java
    trunk/src/net/java/sip/communicator/impl/protocol/msn/OperationSetBasicInstantMessagingMsnImpl.java
    trunk/src/net/java/sip/communicator/impl/protocol/msn/ProtocolProviderServiceMsnImpl.java
    trunk/src/net/java/sip/communicator/impl/protocol/sip/SipLogger.java
    trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolProviderServiceYahooImpl.java
    trunk/src/net/java/sip/communicator/plugin/chatalerter/ChatAlerterActivator.java
    trunk/src/net/java/sip/communicator/plugin/contactinfo/resources/personPhoto.png
    trunk/src/net/java/sip/communicator/plugin/contactinfo/resources/userInfo16x16.png
    trunk/src/net/java/sip/communicator/plugin/facebookaccregwizz/FacebookAccountRegistrationWizard.java
    trunk/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java

Log:
Ongoing work on issue #725 ( Sepperate operation set for ad-hoc like chat rooms (Msn, Icq, Yahoo)) provided by Valentin Martinet. Introduces all the interfaces needed to represent an ad-hoc chat room and the corresponding implementations for Msn, Yahoo and Icq.

Also turns some tabs to spaces in the facebookaccregwizz and chatalerter plugins.

Modified: trunk/src/net/java/sip/communicator/impl/gui/main/MainFrame.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/MainFrame.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/gui/main/MainFrame.java&p2=trunk/src/net/java/sip/communicator/impl/gui/main/MainFrame.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/gui/main/MainFrame.java (original)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/MainFrame.java 2009-09-14 15:51:47+0000
@@ -386,6 +386,21 @@
              multiUserChat.addPresenceListener(conferenceManager);
          }

+ // Obtain the ad-hoc multi user chat operation set.
+ OperationSetAdHocMultiUserChat adHocMultiChatOpSet =
+ (OperationSetAdHocMultiUserChat) protocolProvider
+ .getOperationSet(OperationSetAdHocMultiUserChat.class);
+
+ if (adHocMultiChatOpSet != null)
+ {
+ ConferenceChatManager conferenceManager
+ = GuiActivator.getUIService().getConferenceChatManager();
+
+ adHocMultiChatOpSet.addInvitationListener(conferenceManager);
+ adHocMultiChatOpSet.addInvitationRejectionListener(conferenceManager);
+ adHocMultiChatOpSet.addPresenceListener(conferenceManager);
+ }
+
          // Obtain file transfer operation set.
          OperationSetFileTransfer fileTransferOpSet
              = (OperationSetFileTransfer) protocolProvider
@@ -586,6 +601,26 @@
       *
       * @param protocolProvider The protocol provider for which the multi user
       * chat operation set is about.
+ * @return OperationSetAdHocMultiUserChat The telephony operation
+ * set for the given protocol provider.
+ */
+ public OperationSetAdHocMultiUserChat getAdHocMultiUserChatOpSet(
+ ProtocolProviderService protocolProvider)
+ {
+ OperationSet opSet
+ = protocolProvider.getOperationSet(
+ OperationSetAdHocMultiUserChat.class);
+
+ return (opSet instanceof OperationSetAdHocMultiUserChat)
+ ? (OperationSetAdHocMultiUserChat) opSet
+ : null;
+ }
+
+ /**
+ * Returns the multi user chat operation set for the given protocol provider.
+ *
+ * @param protocolProvider The protocol provider for which the multi user
+ * chat operation set is about.
       * @return OperationSetMultiUserChat The telephony operation
       * set for the given protocol provider.
       */

Modified: trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java&p2=trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java (original)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java 2009-09-14 15:51:47+0000
@@ -780,7 +780,8 @@
      /**
       * Pastes the content of the clipboard to the write area.
       */
- public void paste(){
+ public void paste()
+ {
          JEditorPane editorPane = this.writeMessagePanel.getEditorPane();

          editorPane.paste();
@@ -1808,11 +1809,18 @@
          ChatTransport currentChatTransport
              = chatSession.getCurrentChatTransport();

- if (currentChatTransport.getProtocolProvider()
- .getOperationSet(OperationSetMultiUserChat.class) != null)
+ ProtocolProviderService protocolProvider
+ = currentChatTransport.getProtocolProvider();
+
+ // We choose between OpSets for multi user chat...
+ if (protocolProvider.getOperationSet(
+ OperationSetMultiUserChat.class) != null
+ || protocolProvider.getOperationSet(
+ OperationSetAdHocMultiUserChat.class) != null)
          {
              return chatSession.getCurrentChatTransport();
          }
+
          else
          {
              Iterator<ChatTransport> chatTransportsIter
@@ -1838,7 +1846,7 @@
                                  Collection<String> chatContacts,
                                  String reason)
      {
- ChatSession conferenceChatSession;
+ ChatSession conferenceChatSession = null;

          if (chatSession instanceof MetaContactChatSession)
          {
@@ -1849,14 +1857,31 @@
              ConferenceChatManager conferenceChatManager
                  = GuiActivator.getUIService().getConferenceChatManager();

- ChatRoomWrapper chatRoomWrapper
- = conferenceChatManager.createChatRoom(newChatName,
- inviteChatTransport.getProtocolProvider());
+ // the chat session is set regarding to which OpSet is used for MUC
+ if(inviteChatTransport.getProtocolProvider().
+ getOperationSet(OperationSetMultiUserChat.class) != null)
+ {
+ ChatRoomWrapper chatRoomWrapper
+ = conferenceChatManager.createChatRoom(newChatName,
+ inviteChatTransport.getProtocolProvider(), chatContacts);

- conferenceChatSession
- = new ConferenceChatSession(this, chatRoomWrapper);
+ conferenceChatSession
+ = new ConferenceChatSession(this, chatRoomWrapper);
+ }
+ else if (inviteChatTransport.getProtocolProvider().
+ getOperationSet(OperationSetAdHocMultiUserChat.class) != null)
+ {
+ AdHocChatRoomWrapper chatRoomWrapper
+ = conferenceChatManager.createAdHocChatRoom(newChatName,
+ inviteChatTransport.getProtocolProvider(),
+ chatContacts);
+
+ conferenceChatSession
+ = new AdHocConferenceChatSession(this, chatRoomWrapper);
+ }

- this.setChatSession(conferenceChatSession);
+ if (conferenceChatSession != null)
+ this.setChatSession(conferenceChatSession);
          }
          // We're already in a conference chat.
          else

Modified: trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindow.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindow.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindow.java&p2=trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindow.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindow.java (original)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindow.java 2009-09-14 15:51:47+0000
@@ -460,7 +460,7 @@
          mainToolBar.changeHistoryButtonsState(chatPanel);

          chatPanel.requestFocusInWriteArea();
-
+
          for (ChatChangeListener l : this.chatChangeListeners)
          {
              l.chatChanged(chatPanel);

Modified: trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindowManager.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindowManager.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindowManager.java&p2=trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindowManager.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindowManager.java (original)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindowManager.java 2009-09-14 15:51:47+0000
@@ -23,6 +23,7 @@
   * Manages chat windows and panels.
   *
   * @author Yana Stamcheva
+ * @author Valentin Martinet
   */
  public class ChatWindowManager
  {
@@ -123,6 +124,27 @@
                  && getChat(chatSession).isShown());
          }
      }
+
+ /**
+ * Returns TRUE if there is an opened<tt>ChatPanel</tt> for the given
+ *<tt>AdHocChatRoom</tt>.
+ * @param chatRoomWrapper the<tt>AdHocChatRoomWrapper</tt>, for which the
+ * ad-hoc chat is about
+ * @return TRUE if there is an opened<tt>ChatPanel</tt> for the given
+ *<tt>AdHocChatRoom</tt>
+ */
+ public boolean isChatOpenedForAdHocChatRoom(
+ AdHocChatRoomWrapper adHocChatRoomWrapper)
+ {
+ synchronized (syncChat)
+ {
+ ChatSession chatSession
+ = findChatSessionForDescriptor(adHocChatRoomWrapper);
+
+ return (chatSession != null
+&& getChat(chatSession).isShown());
+ }
+ }

      /**
       * Returns TRUE if there is an opened<tt>ChatPanel</tt> for the given
@@ -178,6 +200,43 @@
              return false;
          }
      }
+
+ /**
+ * Returns TRUE if there is an opened<tt>ChatPanel</tt> for the given
+ *<tt>AdHocChatRoom</tt>.
+ *
+ * @param adHocChatRoom the<tt>AdHocChatRoom</tt>, for which the ad-hoc
+ * chat is about
+ * @return TRUE if there is an opened<tt>ChatPanel</tt> for the given
+ *<tt>AdHocChatRoom</tt>
+ */
+ public boolean isChatOpenedForAdHocChatRoom(AdHocChatRoom adHocChatRoom)
+ {
+ synchronized (syncChat)
+ {
+ for (ChatPanel chatPanel : chatPanels)
+ {
+ ChatSession chatSession = chatPanel.getChatSession();
+
+ Object descriptor = chatSession.getDescriptor();
+
+ if(descriptor instanceof AdHocChatRoomWrapper)
+ {
+ AdHocChatRoomWrapper chatRoomWrapper
+ = (AdHocChatRoomWrapper) descriptor;
+
+ if(chatRoomWrapper.getAdHocChatRoomID()
+ .equals(adHocChatRoom.getIdentifier())
+&& getChat(chatSession).isShown())
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+ }

      /**
       * Closes the given chat panel.
@@ -252,6 +311,11 @@
                          closeChatPanel(chatPanel);
                      }
                  }
+ else if (chatPanel.getChatSession() instanceof
+ AdHocConferenceChatSession)
+ {
+ // TODO: close the chat room before closing the window!!!
+ }
                  else
                  {
                      closeChatPanel(chatPanel);
@@ -476,7 +540,7 @@
          synchronized (syncChat)
          {
              ChatSession chatSession
- = findChatSessionForDescriptor(chatRoomWrapper);
+ = findChatSessionForDescriptor(chatRoomWrapper);

              if(chatSession != null)
              {
@@ -484,8 +548,42 @@
              }
              else
                  return createChat(chatRoomWrapper);
+ }
+ }
+
+ /**
+ * Returns the chat panel corresponding to the given chat room wrapper.
+ *
+ * @param chatRoomWrapper the ad-hoc chat room wrapper, corresponding to the
+ * ad-hoc chat room for which the chat panel is about
+ * @return the chat panel corresponding to the given chat room
+ */
+ public ChatPanel getAdHocMultiChat(AdHocChatRoomWrapper chatRoomWrapper)
+ {
+ synchronized (syncChat)
+ {
+ ChatSession chatSession
+ = findChatSessionForDescriptor(chatRoomWrapper);
+
+ if(chatSession != null)
+ {
+ return getChat(chatSession);
              }
+ else
+ return createChat(chatRoomWrapper);
          }
+ }
+
+ /**
+ * Returns the chat panel corresponding to the given ad-hoc chat room.
+ *
+ * @param adHocChatRoom the chat room, for which the chat panel is about
+ * @return the chat panel corresponding to the given ad-hoc chat room
+ */
+ public ChatPanel getAdHocMultiChat(AdHocChatRoom adHocChatRoom)
+ {
+ return getAdHocMultiChat(adHocChatRoom, null);
+ }

      /**
       * Returns the chat panel corresponding to the given chat room.
@@ -543,6 +641,51 @@
      }

      /**
+ * Returns the chat panel corresponding to the given ad-hoc chat room.
+ *
+ * @param chatRoom the ad-hoc chat room, for which the chat panel is about
+ * @param escapedMessageID the message ID of the message that should be
+ * excluded from the history when the last one is loaded in the chat
+ * @return the chat panel corresponding to the given ad-hoc chat room
+ */
+ public ChatPanel getAdHocMultiChat( AdHocChatRoom chatRoom,
+ String escapedMessageID)
+ {
+ synchronized (syncChat)
+ {
+ AdHocChatRoomList chatRoomList = GuiActivator.getUIService()
+ .getConferenceChatManager().getAdHocChatRoomList();
+
+ // Search in the chat room's list for a chat room that correspond
+ // to the given one.
+ AdHocChatRoomWrapper chatRoomWrapper
+ = chatRoomList.findChatRoomWrapperFromAdHocChatRoom(chatRoom);
+
+ if (chatRoomWrapper == null)
+ {
+ AdHocChatRoomProviderWrapper parentProvider
+ = chatRoomList.findServerWrapperFromProvider(
+ chatRoom.getParentProvider());
+
+ chatRoomWrapper =
+ new AdHocChatRoomWrapper(parentProvider, chatRoom);
+
+ chatRoomList.addAdHocChatRoom(chatRoomWrapper);
+ }
+
+ ChatSession chatSession
+ = findChatSessionForDescriptor(chatRoomWrapper);
+
+ if (chatSession != null)
+ {
+ return getChat(chatSession);
+ }
+
+ return createChat(chatRoomWrapper, escapedMessageID);
+ }
+ }
+
+ /**
       * Returns all open<code>ChatPanel</code>s.
       *
       * @return A list of<code>ChatPanel</code>s
@@ -710,10 +853,24 @@
       * Creates a<tt>ChatPanel</tt> for the given<tt>ChatRoom</tt> and saves it
       * in the list of created<tt>ChatPanel</tt>s.
       *
- * @param chatRoomWrapper the<tt>ChatRoom</tt>, for which the chat will be created
+ * @param chatRoomWrapper the<tt>ChatRoom</tt>, for which the chat will be
+ * created
+ * @return The<code>ChatPanel</code> newly created.
+ */
+ private ChatPanel createChat(ChatRoomWrapper chatRoomWrapper)
+ {
+ return createChat(chatRoomWrapper, null);
+ }
+
+ /**
+ * Creates a<tt>ChatPanel</tt> for the given<tt>AdHocChatRoom</tt> and
+ * saves it in the list of created<tt>ChatPanel</tt>s.
+ *
+ * @param chatRoomWrapper the<tt>AdHocChatRoom</tt>, for which the chat
+ * will be created
       * @return The<code>ChatPanel</code> newly created.
       */
- private ChatPanel createChat( ChatRoomWrapper chatRoomWrapper)
+ private ChatPanel createChat(AdHocChatRoomWrapper chatRoomWrapper)
      {
          return createChat(chatRoomWrapper, null);
      }
@@ -722,7 +879,8 @@
       * Creates a<tt>ChatPanel</tt> for the given<tt>ChatRoom</tt> and saves it
       * in the list of created<tt>ChatPanel</tt>s.
       *
- * @param chatRoomWrapper the<tt>ChatRoom</tt>, for which the chat will be created
+ * @param chatRoomWrapper the<tt>ChatRoom</tt>, for which the chat will be
+ * created
       * @param escapedMessageID the message ID of the message that should be
       * excluded from the history when the last one is loaded in the chat.
       * @return The<code>ChatPanel</code> newly created.
@@ -780,6 +938,67 @@
      }

      /**
+ * Creates a<tt>ChatPanel</tt> for the given<tt>AdHocChatRoom</tt> and
+ * saves it in the list of created<tt>ChatPanel</tt>s.
+ *
+ * @param chatRoomWrapper the<tt>AdHocChatRoom</tt>, for which the chat
+ * will be created
+ * @param escapedMessageID the message ID of the message that should be
+ * excluded from the history when the last one is loaded in the chat.
+ * @return The<code>ChatPanel</code> newly created.
+ */
+ private ChatPanel createChat( AdHocChatRoomWrapper chatRoomWrapper,
+ String escapedMessageID)
+ {
+ ChatWindow chatWindow;
+
+ if(ConfigurationManager.isMultiChatWindowEnabled())
+ {
+ Iterator<ChatPanel> chatPanelsIter = chatPanels.iterator();
+
+ // If we're in a tabbed window we're looking for the chat window
+ // through one of the already created chats.
+ if(chatPanelsIter.hasNext())
+ {
+ chatWindow = chatPanelsIter.next().getChatWindow();
+ }
+ else
+ {
+ chatWindow = new ChatWindow();
+
+ GuiActivator.getUIService()
+ .registerExportedWindow(chatWindow);
+ }
+ }
+ else
+ {
+ chatWindow = new ChatWindow();
+ }
+
+ ChatPanel chatPanel = new ChatPanel(chatWindow);
+
+ AdHocConferenceChatSession chatSession
+ = new AdHocConferenceChatSession(chatPanel, chatRoomWrapper);
+
+ chatPanel.setChatSession(chatSession);
+
+ synchronized (chatPanels)
+ {
+ this.chatPanels.add(chatPanel);
+ }
+
+ if (ConfigurationManager.isHistoryShown())
+ {
+ if(escapedMessageID != null)
+ chatPanel.loadHistory(escapedMessageID);
+ else
+ chatPanel.loadHistory();
+ }
+
+ return chatPanel;
+ }
+
+ /**
       * Finds the chat session corresponding to the given chat descriptor.
       *
       * @param descriptor The chat descriptor.
@@ -790,7 +1009,6 @@
          for (ChatPanel chatPanel : chatPanels)
          {
              ChatSession chatSession = chatPanel.getChatSession();
-
              if (chatSession.getDescriptor().equals(descriptor))
                  return chatSession;
          }
@@ -817,9 +1035,9 @@
      /**
       * Returns the<tt>ChatPanel</tt> corresponding to the given meta contact.
       *
- * @param chatSession the key, which corresponds to the chat we are looking for. It
- * could be a<tt>MetaContact</tt> in the case of single user chat and
- * a<tt>ChatRoom</tt> in the case of a multi user chat
+ * @param chatSession the key, which corresponds to the chat we are looking
+ * for. It could be a<tt>MetaContact</tt> in the case of single user chat
+ * and a<tt>ChatRoom</tt> in the case of a multi user chat
       * @return the<tt>ChatPanel</tt> corresponding to the given meta contact
       */
      private ChatPanel getChat(ChatSession chatSession)

Added: trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocChatRoomProviderWrapper.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocChatRoomProviderWrapper.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocChatRoomProviderWrapper.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,234 @@
+/*
+ * 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.chat.conference;
+
+import java.util.*;
+
+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.*;
+
+/**
+ * @author Valentin Martinet
+ */
+public class AdHocChatRoomProviderWrapper
+{
+ private static final Logger logger
+ = Logger.getLogger(AdHocChatRoomProviderWrapper.class);
+
+ private final ProtocolProviderService protocolProvider;
+
+ private final List<AdHocChatRoomWrapper> chatRoomsOrderedCopy
+ = new LinkedList<AdHocChatRoomWrapper>();
+
+ /**
+ * Creates an instance of<tt>AdHocChatRoomProviderWrapper</tt> by
+ * specifying the protocol provider, corresponding to the ad-hoc multi user
+ * chat account.
+ *
+ * @param protocolProvider protocol provider, corresponding to the ad-hoc
+ * multi user chat account.
+ */
+ public AdHocChatRoomProviderWrapper(
+ ProtocolProviderService protocolProvider)
+ {
+ this.protocolProvider = protocolProvider;
+ }
+
+ /**
+ * Returns the name of this ad-hoc chat room provider.
+ * @return the name of this ad-hoc chat room provider.
+ */
+ public String getName()
+ {
+ return protocolProvider.getProtocolDisplayName();
+ }
+
+ public byte[] getIcon()
+ {
+ return protocolProvider.getProtocolIcon()
+ .getIcon(ProtocolIcon.ICON_SIZE_64x64);
+ }
+
+ public byte[] getImage()
+ {
+ byte[] logoImage = null;
+ ProtocolIcon protocolIcon = protocolProvider.getProtocolIcon();
+
+ if(protocolIcon.isSizeSupported(ProtocolIcon.ICON_SIZE_64x64))
+ logoImage = protocolIcon.getIcon(ProtocolIcon.ICON_SIZE_64x64);
+ else if(protocolIcon.isSizeSupported(ProtocolIcon.ICON_SIZE_48x48))
+ logoImage = protocolIcon.getIcon(ProtocolIcon.ICON_SIZE_48x48);
+
+ return logoImage;
+ }
+
+ /**
+ * Returns the protocol provider service corresponding to this server
+ * wrapper.
+ *
+ * @return the protocol provider service corresponding to this server
+ * wrapper.
+ */
+ public ProtocolProviderService getProtocolProvider()
+ {
+ return protocolProvider;
+ }
+
+ /**
+ * Adds the given ad-hoc chat room to this chat room provider.
+ *
+ * @param adHocChatRoom the ad-hoc chat room to add.
+ */
+ public void addAdHocChatRoom(AdHocChatRoomWrapper adHocChatRoom)
+ {
+ this.chatRoomsOrderedCopy.add(adHocChatRoom);
+ }
+
+ /**
+ * Removes the given ad-hoc chat room from this provider.
+ *
+ * @param adHocChatRoom the ad-hoc chat room to remove.
+ */
+ public void removeChatRoom(AdHocChatRoomWrapper adHocChatRoom)
+ {
+ this.chatRoomsOrderedCopy.remove(adHocChatRoom);
+ }
+
+ /**
+ * Returns<code>true</code> if the given ad-hoc chat room is contained in
+ * this provider, otherwise - returns<code>false</code>.
+ *
+ * @param adHocChatRoom the ad-hoc chat room to search for.
+ * @return<code>true</code> if the given ad-hoc chat room is contained in
+ * this provider, otherwise - returns<code>false</code>.
+ */
+ public boolean containsAdHocChatRoom(AdHocChatRoomWrapper adHocChatRoom)
+ {
+ synchronized (chatRoomsOrderedCopy)
+ {
+ return chatRoomsOrderedCopy.contains(adHocChatRoom);
+ }
+ }
+
+ /**
+ * Returns the ad-hoc chat room wrapper contained in this provider that
+ * corresponds to the given ad-hoc chat room.
+ *
+ * @param adHocChatRoom the ad-hoc chat room we're looking for.
+ * @return the ad-hoc chat room wrapper contained in this provider that
+ * corresponds to the given ad-hoc chat room.
+ */
+ public AdHocChatRoomWrapper findChatRoomWrapperForAdHocChatRoom(
+ AdHocChatRoom adHocChatRoom)
+ {
+ // compare ids, cause saved ad-hoc chatrooms don't have AdHocChatRoom
+ // object but Id's are the same
+ for (AdHocChatRoomWrapper chatRoomWrapper : chatRoomsOrderedCopy)
+ {
+ if (chatRoomWrapper.getAdHocChatRoomID().equals(
+ adHocChatRoom.getIdentifier()))
+ {
+ return chatRoomWrapper;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the number of ad-hoc chat rooms contained in this provider.
+ *
+ * @return the number of ad-hoc chat rooms contained in this provider.
+ */
+ public int countAdHocChatRooms()
+ {
+ return chatRoomsOrderedCopy.size();
+ }
+
+ public AdHocChatRoomWrapper getAdHocChatRoom(int index)
+ {
+ return chatRoomsOrderedCopy.get(index);
+ }
+
+ /**
+ * Returns the index of the given chat room in this provider.
+ *
+ * @param chatRoomWrapper the chat room to search for.
+ *
+ * @return the index of the given chat room in this provider.
+ */
+ public int indexOf(AdHocChatRoomWrapper chatRoomWrapper)
+ {
+ return chatRoomsOrderedCopy.indexOf(chatRoomWrapper);
+ }
+
+ /**
+ * Goes through the locally stored chat rooms list and for each
+ * {@link ChatRoomWrapper} tries to find the corresponding server stored
+ * {@link ChatRoom} in the specified operation set. Joins automatically all
+ * found chat rooms.
+ *
+ * @param protocolProvider the protocol provider for the account to
+ * synchronize
+ * @param opSet the ad-hoc multi-user chat operation set, which give us
+ * access to chat room server
+ */
+ public void synchronizeProvider()
+ {
+ final OperationSetAdHocMultiUserChat groupChatOpSet
+ = (OperationSetAdHocMultiUserChat) protocolProvider
+ .getOperationSet(OperationSetAdHocMultiUserChat.class);
+
+ for(final AdHocChatRoomWrapper chatRoomWrapper : chatRoomsOrderedCopy)
+ {
+ new Thread()
+ {
+ public void run()
+ {
+ AdHocChatRoom chatRoom = null;
+
+ try
+ {
+ chatRoom = groupChatOpSet.findRoom(
+ chatRoomWrapper.getAdHocChatRoomName());
+ }
+ catch (OperationFailedException e1)
+ {
+ logger.error("Failed to find chat room with name:"
+ + chatRoomWrapper.getAdHocChatRoomName(), e1);
+ }
+ catch (OperationNotSupportedException e1)
+ {
+ logger.error("Failed to find chat room with name:"
+ + chatRoomWrapper.getAdHocChatRoomName(), e1);
+ }
+
+ if(chatRoom != null)
+ {
+ chatRoomWrapper.setAdHocChatRoom(chatRoom);
+
+ String lastChatRoomStatus
+ = ConfigurationManager.getChatRoomStatus(
+ protocolProvider,
+ chatRoomWrapper.getAdHocChatRoomID());
+
+ if(lastChatRoomStatus == null
+ || lastChatRoomStatus.equals(
+ Constants.ONLINE_STATUS))
+ {
+ GuiActivator.getUIService()
+ .getConferenceChatManager()
+ .joinChatRoom(chatRoomWrapper);
+ }
+ }
+ }
+ }.start();
+ }
+ }
+}

Added: trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocChatRoomWrapper.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocChatRoomWrapper.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocChatRoomWrapper.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,132 @@
+/*
+ * 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.chat.conference;
+
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * The<tt>AdHocChatRoomWrapper</tt> is the representation of the
+ *<tt>AdHocChatRoom</tt> in the GUI. It stores the information for the ad-hoc
+ * chat room even when the corresponding protocol provider is not connected.
+ *
+ * @author Valentin Martinet
+ */
+public class AdHocChatRoomWrapper
+{
+ private AdHocChatRoomProviderWrapper parentProvider;
+
+ private AdHocChatRoom adHocChatRoom;
+
+ private String adHocChatRoomName;
+
+ private String adHocChatRoomID;
+
+ /**
+ * Creates a<tt>AdHocChatRoomWrapper</tt> by specifying the protocol
+ * provider, the identifier and the name of the ad-hoc chat room.
+ *
+ * @param parentProvider the protocol provider to which the corresponding
+ * ad-hoc chat room belongs
+ * @param adHocChatRoomID the identifier of the corresponding ad-hoc chat
+ * room
+ * @param adHocChatRoomName the name of the corresponding ad-hoc chat room
+ */
+ public AdHocChatRoomWrapper(AdHocChatRoomProviderWrapper parentProvider,
+ String adHocChatRoomID,
+ String adHocChatRoomName)
+ {
+ this.parentProvider = parentProvider;
+ this.adHocChatRoomID = adHocChatRoomID;
+ this.adHocChatRoomName = adHocChatRoomName;
+ }
+
+ /**
+ * Creates a<tt>ChatRoomWrapper</tt> by specifying the corresponding chat
+ * room.
+ *
+ * @param chatRoom the chat room to which this wrapper corresponds.
+ */
+ public AdHocChatRoomWrapper( AdHocChatRoomProviderWrapper parentProvider,
+ AdHocChatRoom adHocChatRoom)
+ {
+ this( parentProvider,
+ adHocChatRoom.getIdentifier(),
+ adHocChatRoom.getName());
+
+ this.adHocChatRoom = adHocChatRoom;
+ }
+
+ /**
+ * Returns the<tt>AdHocChatRoom</tt> that this wrapper represents.
+ *
+ * @return the<tt>AdHocChatRoom</tt> that this wrapper represents.
+ */
+ public AdHocChatRoom getAdHocChatRoom()
+ {
+ return adHocChatRoom;
+ }
+
+ /**
+ * Sets the<tt>AdHocChatRoom</tt> that this wrapper represents.
+ *
+ * @param adHocChatRoom the ad-hoc chat room
+ */
+ public void setAdHocChatRoom(AdHocChatRoom adHocChatRoom)
+ {
+ this.adHocChatRoom = adHocChatRoom;
+ }
+
+ /**
+ * Returns the ad-hoc chat room name.
+ *
+ * @return the ad-hoc chat room name
+ */
+ public String getAdHocChatRoomName()
+ {
+ return adHocChatRoomName;
+ }
+
+ /**
+ * Sets the ad-hoc chat room name.
+ *
+ * @param adHocChatRoomName the name of the ad-hoc chat room
+ */
+ public void setAdHocChatRoomName(String adHocChatRoomName)
+ {
+ this.adHocChatRoomName = adHocChatRoomName;
+ }
+
+ /**
+ * Returns the identifier of the ad-hoc chat room.
+ *
+ * @return the identifier of the ad-hoc chat room
+ */
+ public String getAdHocChatRoomID()
+ {
+ return adHocChatRoomID;
+ }
+
+ /**
+ * Sets the identifier of the ad-hoc chat room.
+ *
+ * @param adHocChatRoomID the identifier of the ad-hoc chat room
+ */
+ public void setAdHocChatRoomID(String adHocChatRoomID)
+ {
+ this.adHocChatRoomID = adHocChatRoomID;
+ }
+
+ /**
+ * Returns the parent protocol provider.
+ *
+ * @return the parent protocol provider
+ */
+ public AdHocChatRoomProviderWrapper getParentProvider()
+ {
+ return this.parentProvider;
+ }
+}

Added: trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocConferenceChatContact.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocConferenceChatContact.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocConferenceChatContact.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,105 @@
+/*
+ * 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.chat.conference;
+
+import javax.swing.*;
+
+import net.java.sip.communicator.impl.gui.*;
+import net.java.sip.communicator.impl.gui.main.chat.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * The<tt>AdHocConferenceChatContact</tt> represents a<tt>ChatContact</tt> in
+ * an ad-hoc conference chat.
+ *
+ * @author Valentin Martinet
+ */
+public class AdHocConferenceChatContact extends ChatContact
+{
+ /**
+ * The contact associated with this<tt>AdHocConferenceChatContact</tt>.
+ */
+ private Contact participant;
+
+ /**
+ * Creates an instance of<tt>AdHocConferenceChatContact</tt> by passing to
+ * it the<tt>Contact</tt> for which it is created.
+ *
+ * @param participant the<tt>Contact</tt> for which this
+ *<tt>AdHocConferenceChatContact</tt> is created.
+ */
+ public AdHocConferenceChatContact(Contact participant)
+ {
+ OperationSetPersistentPresence opSet =
+ (OperationSetPersistentPresence) participant.getProtocolProvider().
+ getOperationSet(OperationSetPersistentPresence.class);
+ this.participant = opSet.findContactByID(participant.getAddress());
+ }
+
+ /**
+ * Returns the descriptor object corresponding to this chat contact.
+ *
+ * @return the descriptor object corresponding to this chat contact.
+ */
+ public Object getDescriptor()
+ {
+ return participant;
+ }
+
+ /**
+ * Returns the contact name.
+ *
+ * @return the contact name
+ */
+ public String getName()
+ {
+ String name = participant.getDisplayName();
+
+ if (name == null || name.length()< 1)
+ name = GuiActivator.getResources().getI18NString(
+ "service.gui.UNKNOWN");
+
+ return name;
+ }
+
+ /**
+ * Returns the current presence status for single user chat contacts and
+ * null for multi user chat contacts.
+ *
+ * @return the current presence status for single user chat contacts and
+ * null for multi user chat contacts
+ */
+ public ImageIcon getAvatar()
+ {
+ byte[] avatarBytes = participant.getImage();
+
+ if (avatarBytes != null&& avatarBytes.length> 0)
+ {
+ return ImageUtils.getScaledRoundedIcon(avatarBytes,
+ AVATAR_ICON_WIDTH,
+ AVATAR_ICON_HEIGHT
+ );
+ }
+ else
+ return null;
+ }
+
+ /*
+ * Implements ChatContact#getUID(). Delegates to
+ * Contact#getAddress() because it's supposed to be unique.
+ */
+ public String getUID()
+ {
+ return participant.getAddress();
+ }
+
+ @Override
+ protected byte[] getAvatarBytes() {
+ return this.participant.getImage();
+ }
+}

Added: trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocConferenceChatSession.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocConferenceChatSession.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocConferenceChatSession.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,530 @@
+/*
+ * 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.chat.conference;
+
+import java.util.*;
+
+import javax.swing.*;
+
+import net.java.sip.communicator.impl.gui.*;
+import net.java.sip.communicator.impl.gui.main.chat.*;
+import net.java.sip.communicator.impl.gui.utils.*;
+import net.java.sip.communicator.service.metahistory.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.event.*;
+
+/**
+ * An implementation of<tt>ChatSession</tt> for ad-hoc conference chatting.
+ *
+ * @author Valentin Martinet
+ */
+public class AdHocConferenceChatSession
+ implements ChatSession,
+ AdHocChatRoomParticipantPresenceListener
+{
+ private final List<ChatContact> chatParticipants
+ = new ArrayList<ChatContact>();
+
+ private final List<ChatTransport> chatTransports
+ = new ArrayList<ChatTransport>();
+
+ private ChatTransport currentChatTransport;
+
+ private final AdHocChatRoomWrapper chatRoomWrapper;
+
+ private final ChatSessionRenderer sessionRenderer;
+
+ /**
+ * Creates an instance of<tt>AdHocConferenceChatSession</tt>, by specifying
+ * the sessionRenderer to be used for communication with the UI and the
+ * ad-hoc chat room corresponding to this conference session.
+ *
+ * @param sessionRenderer the renderer to be used for communication with the
+ * UI.
+ * @param chatRoomWrapper the ad-hoc chat room corresponding to this
+ * conference session.
+ */
+ public AdHocConferenceChatSession( ChatSessionRenderer sessionRenderer,
+ AdHocChatRoomWrapper chatRoomWrapper)
+ {
+ this.sessionRenderer = sessionRenderer;
+ this.chatRoomWrapper = chatRoomWrapper;
+
+ this.currentChatTransport = new AdHocConferenceChatTransport(
+ this, chatRoomWrapper.getAdHocChatRoom());
+
+ chatTransports.add(currentChatTransport);
+
+ this.initChatParticipants();
+
+ AdHocChatRoom chatRoom = chatRoomWrapper.getAdHocChatRoom();
+ chatRoom.addParticipantPresenceListener(this);
+ }
+
+ /**
+ * Returns the descriptor of this chat session.
+ *
+ * @return the descriptor of this chat session.
+ */
+ public Object getDescriptor()
+ {
+ return chatRoomWrapper;
+ }
+
+ /**
+ * Disposes this chat session.
+ */
+ public void dispose()
+ {
+ AdHocChatRoom chatRoom = chatRoomWrapper.getAdHocChatRoom();
+ chatRoom.removeParticipantPresenceListener(this);
+ }
+
+ /**
+ * Returns the name of the ad-hoc chat room.
+ *
+ * @return the name of the ad-hoc chat room.
+ */
+ public String getChatName()
+ {
+ return chatRoomWrapper.getAdHocChatRoomName();
+ }
+
+ /**
+ * Returns the configuration form corresponding to the chat room.
+ *
+ * @return the configuration form corresponding to the chat room.
+ * @throws OperationFailedException if no configuration form is available
+ * for the chat room.
+ */
+ public ChatRoomConfigurationForm getChatConfigurationForm()
+ throws OperationFailedException
+ {
+ return null;
+ }
+
+ /**
+ * Returns an iterator to the list of all participants contained in this
+ * chat session.
+ *
+ * @return an iterator to the list of all participants contained in this
+ * chat session.
+ */
+ public Iterator<ChatContact> getParticipants()
+ {
+ return chatParticipants.iterator();
+ }
+
+ /**
+ * Returns all available chat transports for this chat session.
+ *
+ * @return all available chat transports for this chat session.
+ */
+ public Iterator<ChatTransport> getChatTransports()
+ {
+ return chatTransports.iterator();
+ }
+
+ /**
+ * Returns the currently used transport for all operation within this chat
+ * session.
+ *
+ * @return the currently used transport for all operation within this chat
+ * session.
+ */
+ public ChatTransport getCurrentChatTransport()
+ {
+ return currentChatTransport;
+ }
+
+ /**
+ * Returns the default mobile number used to send sms-es in this session. In
+ * the case of conference this is for now null.
+ *
+ * @return the default mobile number used to send sms-es in this session.
+ */
+ public String getDefaultSmsNumber()
+ {
+ return null;
+ }
+
+ /**
+ * Returns a collection of the last N number of messages given by count.
+ *
+ * @param count The number of messages from history to return.
+ * @return a collection of the last N number of messages given by count.
+ */
+ public Collection<Object> getHistory(int count)
+ {
+ final MetaHistoryService metaHistory
+ = GuiActivator.getMetaHistoryService();
+
+ // If the MetaHistoryService is not registered we have nothing to do
+ // here. The history could be "disabled" from the user
+ // through one of the configuration forms.
+ if (metaHistory == null)
+ return null;
+
+ return metaHistory.findLast(
+ chatHistoryFilter,
+ chatRoomWrapper.getAdHocChatRoom(),
+ ConfigurationManager.getChatHistorySize());
+ }
+
+ /**
+ * Returns a collection of the last N number of messages given by count.
+ *
+ * @param date The date up to which we're looking for messages.
+ * @param count The number of messages from history to return.
+ * @return a collection of the last N number of messages given by count.
+ */
+ public Collection<Object> getHistoryBeforeDate(Date date, int count)
+ {
+ final MetaHistoryService metaHistory
+ = GuiActivator.getMetaHistoryService();
+
+ // If the MetaHistoryService is not registered we have nothing to do
+ // here. The history could be "disabled" from the user
+ // through one of the configuration forms.
+ if (metaHistory == null)
+ return null;
+
+ return metaHistory.findLastMessagesBefore(
+ chatHistoryFilter,
+ chatRoomWrapper.getAdHocChatRoom(),
+ date,
+ ConfigurationManager.getChatHistorySize());
+ }
+
+ /**
+ * Returns a collection of the last N number of messages given by count.
+ *
+ * @param date The date from which we're looking for messages.
+ * @param count The number of messages from history to return.
+ * @return a collection of the last N number of messages given by count.
+ */
+ public Collection<Object> getHistoryAfterDate(Date date, int count)
+ {
+ final MetaHistoryService metaHistory
+ = GuiActivator.getMetaHistoryService();
+
+ // If the MetaHistoryService is not registered we have nothing to do
+ // here. The history could be "disabled" from the user
+ // through one of the configuration forms.
+ if (metaHistory == null)
+ return null;
+
+ return metaHistory.findFirstMessagesAfter(
+ chatHistoryFilter,
+ chatRoomWrapper.getAdHocChatRoom(),
+ date,
+ ConfigurationManager.getChatHistorySize());
+ }
+
+ /**
+ * Returns the start date of the history of this chat session.
+ *
+ * @return the start date of the history of this chat session.
+ */
+ public long getHistoryStartDate()
+ {
+ MetaHistoryService metaHistory
+ = GuiActivator.getMetaHistoryService();
+
+ // If the MetaHistoryService is not registered we have nothing to do
+ // here. The history could be "disabled" from the user
+ // through one of the configuration forms.
+ if (metaHistory == null)
+ return 0;
+
+ long startHistoryDate = 0;
+
+ Collection<Object> firstMessage = metaHistory
+ .findFirstMessagesAfter(
+ chatHistoryFilter,
+ chatRoomWrapper.getAdHocChatRoom(),
+ new Date(0),
+ 1);
+
+ if(firstMessage.size()> 0)
+ {
+ Iterator<Object> i = firstMessage.iterator();
+
+ Object o = i.next();
+
+ if(o instanceof MessageDeliveredEvent)
+ {
+ MessageDeliveredEvent evt
+ = (MessageDeliveredEvent)o;
+
+ startHistoryDate = evt.getTimestamp();
+ }
+ else if(o instanceof MessageReceivedEvent)
+ {
+ MessageReceivedEvent evt = (MessageReceivedEvent)o;
+
+ startHistoryDate = evt.getTimestamp();
+ }
+ }
+
+ return startHistoryDate;
+ }
+
+ /**
+ * Returns the end date of the history of this chat session.
+ *
+ * @return the end date of the history of this chat session.
+ */
+ public long getHistoryEndDate()
+ {
+ MetaHistoryService metaHistory
+ = GuiActivator.getMetaHistoryService();
+
+ // If the MetaHistoryService is not registered we have nothing to do
+ // here. The history could be "disabled" from the user
+ // through one of the configuration forms.
+ if (metaHistory == null)
+ return 0;
+
+ long endHistoryDate = 0;
+
+ Collection<Object> lastMessage = metaHistory
+ .findLastMessagesBefore(
+ chatHistoryFilter,
+ chatRoomWrapper.getAdHocChatRoom(),
+ new Date(Long.MAX_VALUE), 1);
+
+ if(lastMessage.size()> 0)
+ {
+ Iterator<Object> i1 = lastMessage.iterator();
+
+ Object o1 = i1.next();
+
+ if(o1 instanceof MessageDeliveredEvent)
+ {
+ MessageDeliveredEvent evt
+ = (MessageDeliveredEvent)o1;
+
+ endHistoryDate = evt.getTimestamp();
+ }
+ else if(o1 instanceof MessageReceivedEvent)
+ {
+ MessageReceivedEvent evt = (MessageReceivedEvent)o1;
+
+ endHistoryDate = evt.getTimestamp();
+ }
+ }
+
+ return endHistoryDate;
+ }
+
+ /**
+ * Sets the transport that will be used for all operations within this chat
+ * session.
+ *
+ * @param chatTransport The transport to set as a default transport for this
+ * session.
+ */
+ public void setCurrentChatTransport(ChatTransport chatTransport)
+ {
+ this.currentChatTransport = chatTransport;
+ }
+
+ /**
+ * Sets the default mobile number used to send sms-es in this session.
+ *
+ * @param smsPhoneNumber The default mobile number used to send sms-es in
+ * this session.
+ */
+ public void setDefaultSmsNumber(String smsPhoneNumber)
+ {}
+
+ /**
+ * Returns the<tt>ChatSessionRenderer</tt> that provides the connection
+ * between this chat session and its UI.
+ *
+ * @return The<tt>ChatSessionRenderer</tt>.
+ */
+ public ChatSessionRenderer getChatSessionRenderer()
+ {
+ return sessionRenderer;
+ }
+
+ /**
+ * Returns<code>true</code> if this contact is persistent, otherwise
+ * returns<code>false</code>.
+ * @return<code>true</code> if this contact is persistent, otherwise
+ * returns<code>false</code>.
+ */
+ public boolean isDescriptorPersistent()
+ {
+ return false;
+ }
+
+ public ChatTransport findChatTransportForDescriptor(Object descriptor)
+ {
+ return MetaContactChatSession.findChatTransportForDescriptor(
+ chatTransports,
+ descriptor);
+ }
+
+ /**
+ * Loads the given chat room in the this chat conference panel. Loads all
+ * members and adds all corresponding listeners.
+ *
+ * @param chatRoom the<tt>ChatRoom</tt> to load
+ */
+ public void loadChatRoom(AdHocChatRoom chatRoom)
+ {
+ for (Contact contact : chatRoom.getParticipants())
+ {
+ sessionRenderer.addChatContact(
+ new AdHocConferenceChatContact(contact));
+
+ }
+
+ chatRoom.addParticipantPresenceListener(this);
+
+ }
+
+ /**
+ * Implements the<tt>ChatPanel.getChatStatusIcon</tt> method.
+ *
+ * @return the status icon corresponding to this ad-hoc chat room
+ */
+ public ImageIcon getChatStatusIcon()
+ {
+ String status = Constants.OFFLINE_STATUS;
+
+ if(chatRoomWrapper.getAdHocChatRoom() != null)
+ status = Constants.ONLINE_STATUS;
+
+ return new ImageIcon(Constants.getStatusIcon(status));
+ }
+
+ /**
+ * Returns the avatar icon of this chat session.
+ *
+ * @return the avatar icon of this chat session.
+ */
+ public byte[] getChatAvatar()
+ {
+ return null;
+ }
+
+ /**
+ * Initializes the list of participants.
+ */
+ private void initChatParticipants()
+ {
+ AdHocChatRoom chatRoom = chatRoomWrapper.getAdHocChatRoom();
+
+ if (chatRoom != null)
+ {
+ for (Contact contact : chatRoom.getParticipants())
+ {
+ chatParticipants.add(new AdHocConferenceChatContact(contact));
+ }
+ }
+ }
+
+ /* Implements ChatSession#isContactListSupported(). */
+ public boolean isContactListSupported()
+ {
+ return true;
+ }
+
+ /**
+ * Invoked when<tt>AdHocChatRoomParticipantPresenceChangeEvent</tt> are
+ * received. When a new participant (<tt>Contact</tt>) has joined the chat
+ * adds it to the list of chat participants on the right of the chat window.
+ * When a participant has left or quit it's removed from the chat window.
+ */
+ public void participantPresenceChanged(
+ AdHocChatRoomParticipantPresenceChangeEvent evt) {
+ AdHocChatRoom sourceChatRoom = evt.getAdHocChatRoom();
+
+ if(!sourceChatRoom.equals(chatRoomWrapper.getAdHocChatRoom()))
+ return;
+
+ String eventType = evt.getEventType();
+ Contact participant = evt.getParticipant();
+
+ String statusMessage = null;
+
+ if (eventType.equals(
+ AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_JOINED))
+ {
+ AdHocConferenceChatContact chatContact
+ = new AdHocConferenceChatContact(participant);
+
+ chatParticipants.add(chatContact);
+
+ sessionRenderer.addChatContact(chatContact);
+
+ /*
+ * When the whole list of members of a given chat room is reported,
+ * it doesn't make sense to see "ChatContact has joined #ChatRoom"
+ * for all of them one after the other. Such an event occurs not
+ * because the ChatContact has joined after us but rather she was
+ * there before us.
+ */
+ if (!evt.isReasonUserList())
+ {
+ statusMessage = GuiActivator.getResources().getI18NString(
+ "service.gui.CHAT_ROOM_USER_JOINED",
+ new String[] {sourceChatRoom.getName()});
+
+ sessionRenderer.updateChatContactStatus(
+ chatContact,
+ statusMessage);
+ }
+ }
+ else if (eventType.equals(
+ AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_LEFT)
+ ||
+ eventType.equals(
+ AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_QUIT))
+ {
+ if(eventType.equals(
+ AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_LEFT))
+ {
+ statusMessage = GuiActivator.getResources().getI18NString(
+ "service.gui.CHAT_ROOM_USER_LEFT",
+ new String[] {sourceChatRoom.getName()});
+ }
+ else if(eventType.equals(
+ AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_QUIT))
+ {
+ statusMessage = GuiActivator.getResources().getI18NString(
+ "service.gui.CHAT_ROOM_USER_QUIT",
+ new String[] {sourceChatRoom.getName()});
+ }
+
+ for (ChatContact chatContact : chatParticipants)
+ {
+ if(chatContact.getDescriptor().equals(participant))
+ {
+ sessionRenderer.updateChatContactStatus(
+ chatContact, statusMessage);
+
+ sessionRenderer.removeChatContact(chatContact);
+ break;
+ }
+ }
+ }
+ }
+
+ public void addChatTransportChangeListener(ChatSessionChangeListener l)
+ {
+ }
+
+ public void removeChatTransportChangeListener(ChatSessionChangeListener l)
+ {
+ }
+}

Added: trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocConferenceChatTransport.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocConferenceChatTransport.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocConferenceChatTransport.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,302 @@
+/*
+ * 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.chat.conference;
+
+import java.io.*;
+
+import net.java.sip.communicator.impl.gui.main.chat.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.event.*;
+
+/**
+ * The conference implementation of the<tt>ChatTransport</tt> interface that
+ * provides abstraction to access to protocol providers.
+ *
+ * @author Valentin Martinet
+ */
+public class AdHocConferenceChatTransport
+ implements ChatTransport
+{
+ private ChatSession chatSession;
+
+ private AdHocChatRoom adHocChatRoom;
+
+ /**
+ * Creates an instance of<tt>ConferenceChatTransport</tt> by specifying the
+ * parent chat session and the ad-hoc chat room associated with this
+ * transport.
+ *
+ * @param chatSession the parent chat session.
+ * @param chatRoom the ad-hoc chat room associated with this conference
+ * transport.
+ */
+ public AdHocConferenceChatTransport(ChatSession chatSession,
+ AdHocChatRoom chatRoom)
+ {
+ this.chatSession = chatSession;
+ this.adHocChatRoom = chatRoom;
+ }
+
+ /**
+ * Returns the contact address corresponding to this chat transport.
+ *
+ * @return The contact address corresponding to this chat transport.
+ */
+ public String getName()
+ {
+ return adHocChatRoom.getName();
+ }
+
+ /**
+ * Returns the display name corresponding to this chat transport.
+ *
+ * @return The display name corresponding to this chat transport.
+ */
+ public String getDisplayName()
+ {
+ return adHocChatRoom.getName();
+ }
+
+ /**
+ * Returns the presence status of this transport.
+ *
+ * @return the presence status of this transport.
+ */
+ public PresenceStatus getStatus()
+ {
+ return null;
+ }
+
+ /**
+ * Returns the<tt>ProtocolProviderService</tt>, corresponding to this chat
+ * transport.
+ *
+ * @return the<tt>ProtocolProviderService</tt>, corresponding to this chat
+ * transport.
+ */
+ public ProtocolProviderService getProtocolProvider()
+ {
+ return adHocChatRoom.getParentProvider();
+ }
+
+ /**
+ * Returns<code>true</code> if this chat transport supports instant
+ * messaging, otherwise returns<code>false</code>.
+ *
+ * @return<code>true</code> if this chat transport supports instant
+ * messaging, otherwise returns<code>false</code>.
+ */
+ public boolean allowsInstantMessage()
+ {
+ return true;
+ }
+
+ /**
+ * Returns<code>true</code> if this chat transport supports sms
+ * messaging, otherwise returns<code>false</code>.
+ *
+ * @return<code>true</code> if this chat transport supports sms
+ * messaging, otherwise returns<code>false</code>.
+ */
+ public boolean allowsSmsMessage()
+ {
+ Object smsOpSet = adHocChatRoom.getParentProvider()
+ .getOperationSet(OperationSetSmsMessaging.class);
+
+ if (smsOpSet != null)
+ return true;
+ else
+ return false;
+ }
+
+ /**
+ * Returns<code>true</code> if this chat transport supports typing
+ * notifications, otherwise returns<code>false</code>.
+ *
+ * @return<code>true</code> if this chat transport supports typing
+ * notifications, otherwise returns<code>false</code>.
+ */
+ public boolean allowsTypingNotifications()
+ {
+ Object tnOpSet = adHocChatRoom.getParentProvider()
+ .getOperationSet(OperationSetTypingNotifications.class);
+
+ if (tnOpSet != null)
+ return true;
+ else
+ return false;
+ }
+
+ /**
+ * Sends the given instant message trough this chat transport, by specifying
+ * the mime type (html or plain text).
+ *
+ * @param message The message to send.
+ * @param mimeType The mime type of the message to send: text/html or
+ * text/plain.
+ */
+ public void sendInstantMessage(String messageText, String mimeType)
+ throws Exception
+ {
+ // If this chat transport does not support instant messaging we do
+ // nothing here.
+ if (!allowsInstantMessage())
+ return;
+
+ Message message = adHocChatRoom.createMessage(messageText);
+
+ adHocChatRoom.sendMessage(message);
+ }
+
+ /**
+ * Sending sms messages is not supported by this chat transport
+ * implementation.
+ */
+ public void sendSmsMessage(String phoneNumber, String message)
+ throws Exception
+ {}
+
+ /**
+ * Sending typing notifications is not supported by this chat transport
+ * implementation.
+ */
+ public int sendTypingNotification(int typingState)
+ {
+ return 0;
+ }
+
+ /**
+ * Sending files through a chat room is not yet supported by this chat
+ * transport implementation.
+ */
+ public FileTransfer sendFile(File file)
+ throws Exception
+ {
+ return null;
+ }
+
+ /**
+ * Invites the given contact in this chat conference.
+ *
+ * @param contactAddress the address of the contact to invite
+ * @param reason the reason for the invitation
+ */
+ public void inviteChatContact(String contactAddress, String reason)
+ {
+ if(adHocChatRoom != null)
+ adHocChatRoom.invite(contactAddress, reason);
+ }
+
+ /**
+ * Returns the parent session of this chat transport. A<tt>ChatSession</tt>
+ * could contain more than one transports.
+ *
+ * @return the parent session of this chat transport
+ */
+ public ChatSession getParentChatSession()
+ {
+ return chatSession;
+ }
+
+ /**
+ * Adds an sms message listener to this chat transport.
+ *
+ * @param l The message listener to add.
+ */
+ public void addSmsMessageListener(MessageListener l)
+ {
+ // If this chat transport does not support sms messaging we do
+ // nothing here.
+ if (!allowsSmsMessage())
+ return;
+
+ OperationSetSmsMessaging smsOpSet
+ = (OperationSetSmsMessaging) adHocChatRoom.getParentProvider()
+ .getOperationSet(OperationSetSmsMessaging.class);
+
+ smsOpSet.addMessageListener(l);
+ }
+
+ /**
+ * Adds an instant message listener to this chat transport.
+ *
+ * @param l The message listener to add.
+ */
+ public void addInstantMessageListener(MessageListener l)
+ {
+ // If this chat transport does not support instant messaging we do
+ // nothing here.
+ if (!allowsInstantMessage())
+ return;
+
+ OperationSetBasicInstantMessaging imOpSet
+ = (OperationSetBasicInstantMessaging)
+ adHocChatRoom.getParentProvider()
+ .getOperationSet(OperationSetBasicInstantMessaging.class);
+
+ imOpSet.addMessageListener(l);
+ }
+
+ /**
+ * Removes the given sms message listener from this chat transport.
+ *
+ * @param l The message listener to remove.
+ */
+ public void removeSmsMessageListener(MessageListener l)
+ {
+ // If this chat transport does not support sms messaging we do
+ // nothing here.
+ if (!allowsSmsMessage())
+ return;
+
+ OperationSetSmsMessaging smsOpSet
+ = (OperationSetSmsMessaging) adHocChatRoom.getParentProvider()
+ .getOperationSet(OperationSetSmsMessaging.class);
+
+ smsOpSet.removeMessageListener(l);
+ }
+
+ /**
+ * Removes the instant message listener from this chat transport.
+ *
+ * @param l The message listener to remove.
+ */
+ public void removeInstantMessageListener(MessageListener l)
+ {
+ // If this chat transport does not support instant messaging we do
+ // nothing here.
+ if (!allowsInstantMessage())
+ return;
+
+ OperationSetBasicInstantMessaging imOpSet
+ = (OperationSetBasicInstantMessaging)
+ adHocChatRoom.getParentProvider()
+ .getOperationSet(OperationSetBasicInstantMessaging.class);
+
+ imOpSet.removeMessageListener(l);
+ }
+
+ public void dispose()
+ {}
+
+ /**
+ * Returns the descriptor of this chat transport.
+ *
+ * @return the descriptor of this chat transport
+ */
+ public Object getDescriptor()
+ {
+ return adHocChatRoom;
+ }
+
+ public long getMaximumFileLength()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+}
\ No newline at end of file

Modified: trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatContact.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatContact.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatContact.java&p2=trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatContact.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatContact.java (original)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatContact.java 2009-09-14 15:51:47+0000
@@ -53,12 +53,13 @@
          String name = chatRoomMember.getName();

          if (name == null || name.length()< 1)
- name = GuiActivator.getResources().getI18NString("service.gui.UNKNOWN");
+ name = GuiActivator.getResources()
+ .getI18NString("service.gui.UNKNOWN");

          return name;
      }

- /*
+ /**
       * Implements ChatContact#getAvatarBytes(). Delegates to chatRoomMember.
       */
      public byte[] getAvatarBytes()
@@ -71,7 +72,7 @@
          return chatRoomMember.getRole();
      }

- /*
+ /**
       * Implements ChatContact#getUID(). Delegates to
       * ChatRoomMember#getContactAddress() because it's supposed to be unique.
       */

Modified: trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatManager.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatManager.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatManager.java&p2=trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatManager.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatManager.java (original)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatManager.java 2009-09-14 15:51:47+0000
@@ -29,17 +29,22 @@
  import org.osgi.framework.*;

  /**
- * The<tt>ConferenceChatManager</tt> is the one that manages chat room
- * invitations.
+ * The<tt>ConferenceChatManager</tt> is the one that manages both chat room and
+ * ad-hoc chat rooms invitations.
   *
   * @author Yana Stamcheva
   * @author Lubomir Marinov
+ * @author Valentin Martinet
   */
  public class ConferenceChatManager
      implements ChatRoomMessageListener,
                  ChatRoomInvitationListener,
                  ChatRoomInvitationRejectionListener,
+ AdHocChatRoomMessageListener,
+ AdHocChatRoomInvitationListener,
+ AdHocChatRoomInvitationRejectionListener,
                  LocalUserChatRoomPresenceListener,
+ LocalUserAdHocChatRoomPresenceListener,
                  ServiceListener
  {
      private static final Logger logger
@@ -49,10 +54,15 @@
          new Hashtable<ChatRoomWrapper, HistoryWindow>();

      private final ChatRoomList chatRoomList = new ChatRoomList();
+
+ private final AdHocChatRoomList adHocChatRoomList = new AdHocChatRoomList();

      private final Vector<ChatRoomListChangeListener> listChangeListeners
          = new Vector<ChatRoomListChangeListener>();

+ private final Vector<AdHocChatRoomListChangeListener>
+ adHoclistChangeListeners = new Vector<AdHocChatRoomListChangeListener>();
+
      /**
       * Creates an instance of<tt>ConferenceChatManager</tt>.
       */
@@ -64,6 +74,7 @@
              public void run()
              {
                  chatRoomList.loadList();
+ adHocChatRoomList.loadList();
              }
          }.start();

@@ -80,6 +91,18 @@
      {
          return chatRoomList;
      }
+
+ /**
+ * Returns all chat room providers currently contained in the ad-hoc chat
+ * room list.
+ *
+ * @return all chat room providers currently contained in the ad-hoc chat
+ * room list.
+ */
+ public AdHocChatRoomList getAdHocChatRoomList()
+ {
+ return adHocChatRoomList;
+ }

      /**
       * Handles<tt>ChatRoomInvitationReceivedEvent</tt>-s.
@@ -175,6 +198,9 @@
              break;
          }

+ logger.setLevelInfo();
+ logger.info("MESSAGE RECEIVED from "+sourceMember.getContactAddress());
+
          logger.trace("MESSAGE RECEIVED from contact: "
              + sourceMember.getContactAddress());

@@ -297,30 +323,31 @@
          ChatRoomMember destMember = evt.getDestinationChatRoomMember();

          if (evt.getErrorCode()
- == MessageDeliveryFailedEvent.OFFLINE_MESSAGES_NOT_SUPPORTED) {
-
+ == MessageDeliveryFailedEvent.OFFLINE_MESSAGES_NOT_SUPPORTED)
+ {
              errorMsg = GuiActivator.getResources().getI18NString(
                      "service.gui.MSG_DELIVERY_NOT_SUPPORTED");
          }
          else if (evt.getErrorCode()
- == MessageDeliveryFailedEvent.NETWORK_FAILURE) {
-
+ == MessageDeliveryFailedEvent.NETWORK_FAILURE)
+ {
              errorMsg = GuiActivator.getResources()
                  .getI18NString("service.gui.MSG_NOT_DELIVERED");
          }
          else if (evt.getErrorCode()
- == MessageDeliveryFailedEvent.PROVIDER_NOT_REGISTERED) {
-
+ == MessageDeliveryFailedEvent.PROVIDER_NOT_REGISTERED)
+ {
              errorMsg = GuiActivator.getResources().getI18NString(
                      "service.gui.MSG_SEND_CONNECTION_PROBLEM");
          }
          else if (evt.getErrorCode()
- == MessageDeliveryFailedEvent.INTERNAL_ERROR) {
-
+ == MessageDeliveryFailedEvent.INTERNAL_ERROR)
+ {
              errorMsg = GuiActivator.getResources().getI18NString(
                      "service.gui.MSG_DELIVERY_INTERNAL_ERROR");
          }
- else {
+ else
+ {
              errorMsg = GuiActivator.getResources().getI18NString(
                      "service.gui.MSG_DELIVERY_UNKNOWN_ERROR");
          }
@@ -347,6 +374,94 @@

      /**
       * Implements the
+ *<tt>LocalUserAdHocChatRoomPresenceListener.localUserPresenceChanged</tt>
+ * method
+ *
+ * @param evt
+ */
+ public void localUserAdHocPresenceChanged(
+ LocalUserAdHocChatRoomPresenceChangeEvent evt)
+ {
+ AdHocChatRoom sourceAdHocChatRoom = evt.getAdHocChatRoom();
+
+ AdHocChatRoomWrapper adHocChatRoomWrapper =
+ adHocChatRoomList.findChatRoomWrapperFromAdHocChatRoom(
+ sourceAdHocChatRoom);
+
+ if (evt.getEventType().equals(
+ LocalUserAdHocChatRoomPresenceChangeEvent.LOCAL_USER_JOINED))
+ {
+ if(adHocChatRoomWrapper != null)
+ {
+ this.fireAdHocChatRoomListChangedEvent(
+ adHocChatRoomWrapper,
+ AdHocChatRoomListChangeEvent.AD_HOC_CHAT_ROOM_CHANGED);
+
+ ChatWindowManager chatWindowManager
+ = GuiActivator.getUIService().getChatWindowManager();
+
+ ChatPanel chatPanel
+ = chatWindowManager.getAdHocMultiChat(adHocChatRoomWrapper);
+
+ // Check if we have already opened a chat window for this chat
+ // wrapper and load the real chat room corresponding to the
+ // wrapper.
+ if(chatWindowManager
+ .isChatOpenedForAdHocChatRoom(adHocChatRoomWrapper))
+ {
+ ((AdHocConferenceChatSession) chatPanel.getChatSession())
+ .loadChatRoom(sourceAdHocChatRoom);
+ }
+ else
+ {
+ chatWindowManager.openChat(chatPanel, true);
+ }
+ }
+
+ sourceAdHocChatRoom.addMessageListener(this);
+ }
+ else if (evt.getEventType().equals(
+ LocalUserAdHocChatRoomPresenceChangeEvent.LOCAL_USER_JOIN_FAILED))
+ {
+ new ErrorDialog(
+ GuiActivator.getUIService().getMainFrame(),
+ GuiActivator.getResources().getI18NString("service.gui.ERROR"),
+ GuiActivator.getResources().getI18NString(
+ "service.gui.FAILED_TO_JOIN_CHAT_ROOM",
+ new String[]{sourceAdHocChatRoom.getName()})
+ + evt.getReason())
+ .showDialog();
+ }
+ else if (evt.getEventType().equals(
+ LocalUserAdHocChatRoomPresenceChangeEvent.LOCAL_USER_LEFT))
+ {
+ this.closeAdHocChatRoom(adHocChatRoomWrapper);
+
+ // Need to refresh the chat room's list in order to change
+ // the state of the chat room to offline.
+ fireAdHocChatRoomListChangedEvent(
+ adHocChatRoomWrapper,
+ AdHocChatRoomListChangeEvent.AD_HOC_CHAT_ROOM_CHANGED);
+
+ sourceAdHocChatRoom.removeMessageListener(this);
+ }
+ else if (evt.getEventType().equals(
+ LocalUserAdHocChatRoomPresenceChangeEvent.LOCAL_USER_DROPPED))
+ {
+ this.closeAdHocChatRoom(adHocChatRoomWrapper);
+
+ // Need to refresh the ad-hoc chat room's list in order to change
+ // the state of the ad-hoc chat room to offline.
+ fireAdHocChatRoomListChangedEvent(
+ adHocChatRoomWrapper,
+ AdHocChatRoomListChangeEvent.AD_HOC_CHAT_ROOM_CHANGED);
+
+ sourceAdHocChatRoom.removeMessageListener(this);
+ }
+ }
+
+ /**
+ * Implements the
       *<tt>LocalUserChatRoomPresenceListener.localUserPresenceChanged</tt>
       * method.
       */
@@ -469,6 +584,24 @@
      }

      /**
+ * Called to accept an incoming invitation. Adds the invitation chat room
+ * to the list of chat rooms and joins it.
+ *
+ * @param invitation the invitation to accept.
+ *
+ * @throws OperationFailedException
+ */
+ public void acceptInvitation(
+ AdHocChatRoomInvitation invitation,
+ OperationSetAdHocMultiUserChat multiUserChatOpSet)
+ throws OperationFailedException
+ {
+ AdHocChatRoom chatRoom = invitation.getTargetAdHocChatRoom();
+
+ chatRoom.join();
+ }
+
+ /**
       * Rejects the given invitation with the specified reason.
       *
       * @param multiUserChatOpSet the operation set to use for rejecting the
@@ -476,14 +609,30 @@
       * @param invitation the invitation to reject
       * @param reason the reason for the rejection
       */
- public void rejectInvitation( OperationSetMultiUserChat multiUserChatOpSet,
- ChatRoomInvitation invitation,
- String reason)
+ public void rejectInvitation( OperationSetMultiUserChat multiUserChatOpSet,
+ ChatRoomInvitation invitation,
+ String reason)
      {
          multiUserChatOpSet.rejectInvitation(invitation, reason);
      }

      /**
+ * Rejects the given invitation with the specified reason.
+ *
+ * @param multiUserChatOpSet the operation set to use for rejecting the
+ * invitation
+ * @param invitation the invitation to reject
+ * @param reason the reason for the rejection
+ */
+ public void rejectInvitation(
+ OperationSetAdHocMultiUserChat multiUserChatAdHocOpSet,
+ AdHocChatRoomInvitation invitation,
+ String reason)
+ {
+ multiUserChatAdHocOpSet.rejectInvitation(invitation, reason);
+ }
+
+ /**
       * Joins the given chat room with the given password and manages all the
       * exceptions that could occur during the join process.
       *
@@ -500,9 +649,9 @@
          if(chatRoom == null)
          {
              new ErrorDialog(
- GuiActivator.getUIService().getMainFrame(),
- GuiActivator.getResources().getI18NString("service.gui.WARNING"),
- GuiActivator.getResources().getI18NString(
+ GuiActivator.getUIService().getMainFrame(),
+ GuiActivator.getResources().getI18NString("service.gui.WARNING"),
+ GuiActivator.getResources().getI18NString(
                      "service.gui.CHAT_ROOM_NOT_CONNECTED",
                      new String[]{chatRoomWrapper.getChatRoomName()}))
                      .showDialog();
@@ -514,14 +663,18 @@
      }

      /**
- * Creates a chatroom, by specifying the chat room name and the parent
- * protocol provider.
+ * Creates a chat room, by specifying the chat room name, the parent
+ * protocol provider and eventually, the contacts invited to participate in
+ * this chat room.
+ *
       * @param chatRoomName the name of the chat room to create.
       * @param protocolProvider the parent protocol provider.
+ * @param contacts the contacts invited when creating the chat room.
       */
      public ChatRoomWrapper createChatRoom(
          String chatRoomName,
- ProtocolProviderService protocolProvider)
+ ProtocolProviderService protocolProvider,
+ Collection<String> contacts)
      {
          ChatRoomWrapper chatRoomWrapper = null;

@@ -536,7 +689,18 @@
          ChatRoom chatRoom = null;
          try
          {
- chatRoom = groupChatOpSet.createChatRoom(chatRoomName, null);
+ Map<String, Object> members = new Hashtable<String, Object>();
+ OperationSetPersistentPresence opSet =
+ (OperationSetPersistentPresence)
+ protocolProvider.getOperationSet(
+ OperationSetPersistentPresence.class);
+
+ for(String contact : contacts)
+ {
+ members.put(contact, opSet.findContactByID(contact));
+ }
+
+ chatRoom = groupChatOpSet.createChatRoom(chatRoomName, members);
          }
          catch (OperationFailedException ex)
          {
@@ -582,6 +746,90 @@
      }

      /**
+ * Creates an ad-hoc chat room, by specifying the ad-hoc chat room name, the
+ * parent protocol provider and eventually, the contacts invited to
+ * participate in this ad-hoc chat room.
+ *
+ * @param chatRoomName the name of the chat room to create.
+ * @param protocolProvider the parent protocol provider.
+ * @param contacts the contacts invited when creating the chat room.
+ */
+ public AdHocChatRoomWrapper createAdHocChatRoom(
+ String chatRoomName,
+ ProtocolProviderService protocolProvider,
+ Collection<String> contacts)
+ {
+ AdHocChatRoomWrapper chatRoomWrapper = null;
+
+ OperationSetAdHocMultiUserChat groupChatOpSet
+ = (OperationSetAdHocMultiUserChat) protocolProvider
+ .getOperationSet(OperationSetAdHocMultiUserChat.class);
+
+ // If there's no group chat operation set we have nothing to do here.
+ if (groupChatOpSet == null)
+ return null;
+
+ AdHocChatRoom chatRoom = null;
+
+ try
+ {
+ List<Contact> members = new LinkedList<Contact>();
+ OperationSetPersistentPresence opSet =
+ (OperationSetPersistentPresence)
+ protocolProvider.getOperationSet(
+ OperationSetPersistentPresence.class);
+
+ for(String contact : contacts)
+ {
+ members.add(opSet.findContactByID(contact));
+ }
+
+ chatRoom = groupChatOpSet.createAdHocChatRoom(
+ chatRoomName, members);
+ }
+ catch (OperationFailedException ex)
+ {
+ new ErrorDialog(
+ GuiActivator.getUIService().getMainFrame(),
+ GuiActivator.getResources().getI18NString("service.gui.ERROR"),
+ GuiActivator.getResources().getI18NString(
+ "service.gui.CREATE_CHAT_ROOM_ERROR",
+ new String[]{chatRoomName}),
+ ex)
+ .showDialog();
+ }
+ catch (OperationNotSupportedException ex)
+ {
+ new ErrorDialog(
+ GuiActivator.getUIService().getMainFrame(),
+ GuiActivator.getResources().getI18NString("service.gui.ERROR"),
+ GuiActivator.getResources().getI18NString(
+ "service.gui.CREATE_CHAT_ROOM_ERROR",
+ new String[]{chatRoomName}),
+ ex)
+ .showDialog();
+ }
+
+ if(chatRoom != null)
+ {
+ AdHocChatRoomProviderWrapper parentProvider
+ = adHocChatRoomList.findServerWrapperFromProvider(
+ protocolProvider);
+
+ chatRoomWrapper = new AdHocChatRoomWrapper(
+ parentProvider, chatRoom);
+ parentProvider.addAdHocChatRoom(chatRoomWrapper);
+ adHocChatRoomList.addAdHocChatRoom(chatRoomWrapper);
+
+ fireAdHocChatRoomListChangedEvent(
+ chatRoomWrapper,
+ AdHocChatRoomListChangeEvent.AD_HOC_CHAT_ROOM_ADDED);
+ }
+
+ return chatRoomWrapper;
+ }
+
+ /**
       * Join chat room.
       * @param chatRoomWrapper
       */
@@ -592,9 +840,9 @@
          if(chatRoom == null)
          {
              new ErrorDialog(
- GuiActivator.getUIService().getMainFrame(),
- GuiActivator.getResources().getI18NString("service.gui.WARNING"),
- GuiActivator.getResources().getI18NString(
+ GuiActivator.getUIService().getMainFrame(),
+ GuiActivator.getResources().getI18NString("service.gui.WARNING"),
+ GuiActivator.getResources().getI18NString(
                          "service.gui.CHAT_ROOM_NOT_CONNECTED",
                          new String[]{chatRoomWrapper.getChatRoomName()}))
                      .showDialog();
@@ -606,6 +854,31 @@
      }

      /**
+ * Joins the given ad-hoc chat room
+ *
+ * @param chatRoomWrapper
+ */
+ public void joinChatRoom(AdHocChatRoomWrapper chatRoomWrapper)
+ {
+ AdHocChatRoom chatRoom = chatRoomWrapper.getAdHocChatRoom();
+
+ if(chatRoom == null)
+ {
+ new ErrorDialog(
+ GuiActivator.getUIService().getMainFrame(),
+ GuiActivator.getResources().getI18NString("service.gui.WARNING"),
+ GuiActivator.getResources().getI18NString(
+ "service.gui.CHAT_ROOM_NOT_CONNECTED",
+ new String[]{chatRoomWrapper.getAdHocChatRoomName()}))
+ .showDialog();
+
+ return;
+ }
+
+ new JoinAdHocChatRoomTask(chatRoomWrapper).execute();
+ }
+
+ /**
       * Removes the given chat room from the UI.
       *
       * @param chatRoomWrapper the chat room to remove.
@@ -655,7 +928,41 @@
          chatWindowManager.openChat(
              chatWindowManager.getMultiChat(chatRoomWrapper), true);
      }
+
+ /**
+ * Joins the given chat room and manages all the exceptions that could
+ * occur during the join process.
+ *
+ * @param chatRoom the chat room to join
+ */
+ public void joinChatRoom(AdHocChatRoom chatRoom)
+ {
+ AdHocChatRoomWrapper chatRoomWrapper
+ = adHocChatRoomList.findChatRoomWrapperFromAdHocChatRoom(chatRoom);
+
+ if(chatRoomWrapper == null)
+ {
+ AdHocChatRoomProviderWrapper parentProvider
+ = adHocChatRoomList.findServerWrapperFromProvider(
+ chatRoom.getParentProvider());
+
+ chatRoomWrapper =
+ new AdHocChatRoomWrapper(parentProvider, chatRoom);
+
+ adHocChatRoomList.addAdHocChatRoom(chatRoomWrapper);

+ fireAdHocChatRoomListChangedEvent(
+ chatRoomWrapper,
+ AdHocChatRoomListChangeEvent.AD_HOC_CHAT_ROOM_ADDED);
+ }
+
+ this.joinChatRoom(chatRoomWrapper);
+ ChatWindowManager chatWindowManager
+ = GuiActivator.getUIService().getChatWindowManager();
+ chatWindowManager.openChat(
+ chatWindowManager.getAdHocMultiChat(chatRoomWrapper), true);
+ }
+
      /**
       * Joins the given chat room and manages all the exceptions that could
       * occur during the join process.
@@ -741,11 +1048,11 @@
          if (chatRoom == null)
          {
              new ErrorDialog(
- GuiActivator.getUIService().getMainFrame(),
- GuiActivator.getResources().getI18NString("service.gui.WARNING"),
- GuiActivator.getResources().getI18NString(
- "service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED"))
- .showDialog();
+ GuiActivator.getUIService().getMainFrame(),
+ GuiActivator.getResources().getI18NString("service.gui.WARNING"),
+ GuiActivator.getResources().getI18NString(
+ "service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED"))
+ .showDialog();

              return;
          }
@@ -869,10 +1176,39 @@
      }

      /**
+ * Adds the given<tt>AdHocChatRoomListChangeListener</tt> that will listen
+ * for all changes of the chat room list data model.
+ *
+ * @param l the listener to add.
+ */
+ public void addAdHocChatRoomListChangeListener(
+ AdHocChatRoomListChangeListener l)
+ {
+ synchronized (adHoclistChangeListeners)
+ {
+ adHoclistChangeListeners.add(l);
+ }
+ }
+
+ /**
+ * Removes the given<tt>AdHocChatRoomListChangeListener</tt>.
+ *
+ * @param l the listener to remove.
+ */
+ public void removeAdHocChatRoomListChangeListener(
+ AdHocChatRoomListChangeListener l)
+ {
+ synchronized (adHoclistChangeListeners)
+ {
+ adHoclistChangeListeners.remove(l);
+ }
+ }
+
+ /**
       * Notifies all interested listeners that a change in the chat room list
       * model has occurred.
       */
- private void fireChatRoomListChangedEvent( ChatRoomWrapper chatRoomWrapper,
+ private void fireChatRoomListChangedEvent( ChatRoomWrapper chatRoomWrapper,
                                                  int eventID)
      {
          ChatRoomListChangeEvent evt
@@ -883,6 +1219,23 @@
              l.contentChanged(evt);
          }
      }
+
+ /**
+ * Notifies all interested listeners that a change in the chat room list
+ * model has occurred.
+ */
+ private void fireAdHocChatRoomListChangedEvent(
+ AdHocChatRoomWrapper adHocChatRoomWrapper,
+ int eventID)
+ {
+ AdHocChatRoomListChangeEvent evt
+ = new AdHocChatRoomListChangeEvent(adHocChatRoomWrapper, eventID);
+
+ for (AdHocChatRoomListChangeListener l : adHoclistChangeListeners)
+ {
+ l.contentChanged(evt);
+ }
+ }

      /**
       * Closes the chat corresponding to the given chat room wrapper, if such
@@ -913,6 +1266,34 @@
      }

      /**
+ * Closes the chat corresponding to the given ad-hoc chat room wrapper, if
+ * such exists.
+ *
+ * @param chatRoomWrapper the ad-hoc chat room wrapper for which we search a
+ * chat to close.
+ */
+ private void closeAdHocChatRoom(AdHocChatRoomWrapper chatRoomWrapper)
+ {
+ final ChatWindowManager chatWindowManager
+ = GuiActivator.getUIService().getChatWindowManager();
+
+ if(chatWindowManager.isChatOpenedForAdHocChatRoom(chatRoomWrapper))
+ {
+ final ChatPanel chatPanel
+ = chatWindowManager.getAdHocMultiChat(chatRoomWrapper);
+
+ // We have to be sure that we close the chat in the swing thread
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ public void run()
+ {
+ chatWindowManager.closeChat(chatPanel);
+ }
+ });
+ }
+ }
+
+ /**
       * Handles<tt>ServiceEvent</tt>s triggered by adding or removing a
       * ProtocolProviderService. Updates the list of available chat rooms and
       * chat room servers.
@@ -944,21 +1325,39 @@
          Object multiUserChatOpSet
              = protocolProvider
                  .getOperationSet(OperationSetMultiUserChat.class);
+
+ Object multiUserChatAdHocOpSet
+ = protocolProvider
+ .getOperationSet(OperationSetAdHocMultiUserChat.class);

- // We don't care if there's no group chat operation set.
- if (multiUserChatOpSet == null)
- {
- return;
- }
-
- if (event.getType() == ServiceEvent.REGISTERED)
+ if (multiUserChatOpSet == null&& multiUserChatAdHocOpSet != null)
          {
- chatRoomList.addChatProvider(protocolProvider);
+ if (event.getType() == ServiceEvent.REGISTERED)
+ {
+ adHocChatRoomList.addChatProvider(protocolProvider);
+ }
+ else if (event.getType() == ServiceEvent.UNREGISTERING)
+ {
+ adHocChatRoomList.removeChatProvider(protocolProvider);
+ }
+ }
+ else if (multiUserChatAdHocOpSet == null&& multiUserChatOpSet != null)
+ {
+ if (event.getType() == ServiceEvent.REGISTERED)
+ {
+ chatRoomList.addChatProvider(protocolProvider);
+ }
+ else if (event.getType() == ServiceEvent.UNREGISTERING)
+ {
+ chatRoomList.removeChatProvider(protocolProvider);
+ }
          }
- else if (event.getType() == ServiceEvent.UNREGISTERING)
+ else
          {
- chatRoomList.removeChatProvider(protocolProvider);
+ return;
          }
+
      }

      /**
@@ -1103,12 +1502,135 @@
              {
                  new ErrorDialog(
                      GuiActivator.getUIService().getMainFrame(),
- GuiActivator.getResources().getI18NString("service.gui.ERROR"),
- errorMessage).showDialog();
+ GuiActivator.getResources().getI18NString(
+ "service.gui.ERROR"), errorMessage).showDialog();
              }
          }
      }
+
+ /**
+ * Joins an ad-hoc chat room in an asynchronous way.
+ */
+ private static class JoinAdHocChatRoomTask
+ extends SwingWorker<String, Object>
+ {
+ private static final String SUCCESS = "Success";
+
+ private static final String AUTHENTICATION_FAILED
+ = "AuthenticationFailed";
+
+ private static final String REGISTRATION_REQUIRED
+ = "RegistrationRequired";
+
+ private static final String PROVIDER_NOT_REGISTERED
+ = "ProviderNotRegistered";
+
+ private static final String SUBSCRIPTION_ALREADY_EXISTS
+ = "SubscriptionAlreadyExists";
+
+ private static final String UNKNOWN_ERROR
+ = "UnknownError";
+
+ private final AdHocChatRoomWrapper adHocChatRoomWrapper;
+
+ JoinAdHocChatRoomTask(AdHocChatRoomWrapper chatRoomWrapper)
+ {
+ this.adHocChatRoomWrapper = chatRoomWrapper;
+ }
+
+ /**
+ * @override {@link SwingWorker}{@link #doInBackground()} to perform
+ * all asynchronous tasks.
+ */
+ public String doInBackground()
+ {
+ AdHocChatRoom chatRoom = adHocChatRoomWrapper.getAdHocChatRoom();
+
+ try
+ {
+ chatRoom.join();
+
+ return SUCCESS;
+ }
+ catch (OperationFailedException e)
+ {
+ logger.trace("Failed to join ad-hoc chat room: "
+ + chatRoom.getName(), e);
+
+ switch (e.getErrorCode())
+ {
+ case OperationFailedException.AUTHENTICATION_FAILED:
+ return AUTHENTICATION_FAILED;
+ case OperationFailedException.REGISTRATION_REQUIRED:
+ return REGISTRATION_REQUIRED;
+ case OperationFailedException.PROVIDER_NOT_REGISTERED:
+ return PROVIDER_NOT_REGISTERED;
+ case OperationFailedException.SUBSCRIPTION_ALREADY_EXISTS:
+ return SUBSCRIPTION_ALREADY_EXISTS;
+ default:
+ return UNKNOWN_ERROR;
+ }
+ }
+ }
+
+ /**
+ * @override {@link SwingWorker}{@link #done()} to perform UI changes
+ * after the ad-hoc chat room join task has finished.
+ */
+ protected void done()
+ {
+ String returnCode = null;
+ try
+ {
+ returnCode = get();
+ }
+ catch (InterruptedException ignore)
+ {}
+ catch (ExecutionException ignore)
+ {}
+
+ ConfigurationManager.updateChatRoomStatus(
+ adHocChatRoomWrapper.getParentProvider().getProtocolProvider(),
+ adHocChatRoomWrapper.getAdHocChatRoomID(),
+ Constants.ONLINE_STATUS);
+
+ String errorMessage = null;
+ if(PROVIDER_NOT_REGISTERED.equals(returnCode))
+ {
+ errorMessage
+ = GuiActivator.getResources()
+ .getI18NString("service.gui.CHAT_ROOM_NOT_CONNECTED",
+ new String[]{
+ adHocChatRoomWrapper.getAdHocChatRoomName()});
+ }
+ else if(SUBSCRIPTION_ALREADY_EXISTS.equals(returnCode))
+ {
+ errorMessage
+ = GuiActivator.getResources()
+ .getI18NString("service.gui.CHAT_ROOM_ALREADY_JOINED",
+ new String[]{
+ adHocChatRoomWrapper.getAdHocChatRoomName()});
+ }
+ else
+ {
+ errorMessage
+ = GuiActivator.getResources()
+ .getI18NString("service.gui.FAILED_TO_JOIN_CHAT_ROOM",
+ new String[]{
+ adHocChatRoomWrapper.getAdHocChatRoomName()});
+ }

+ if (!SUCCESS.equals(returnCode)
+&& !AUTHENTICATION_FAILED.equals(returnCode))
+ {
+ new ErrorDialog(
+ GuiActivator.getUIService().getMainFrame(),
+ GuiActivator.getResources().getI18NString(
+ "service.gui.ERROR"), errorMessage).showDialog();
+ }
+ }
+ }
+
      /**
       * Finds a chat room in asynchronous way.
       */
@@ -1199,4 +1721,218 @@
              return null;
          }
      }
+
+ public void invitationReceived(AdHocChatRoomInvitationReceivedEvent evt) {
+ logger.setLevelInfo();
+ logger.info("Invitation received: "+evt.toString());
+ OperationSetAdHocMultiUserChat multiUserChatOpSet
+ = evt.getSourceOperationSet();
+
+ InvitationReceivedDialog dialog = new InvitationReceivedDialog(
+ this, multiUserChatOpSet, evt.getInvitation());
+
+ dialog.setVisible(true);
+ }
+
+ /**
+ * Implements the<tt>AdHocChatRoomMessageListener.messageDelivered</tt>
+ * method.
+ *<br>
+ * Shows the message in the conversation area and clears the write message
+ * area.
+ */
+ public void messageDelivered(AdHocChatRoomMessageDeliveredEvent evt) {
+ AdHocChatRoom sourceChatRoom = (AdHocChatRoom) evt.getSource();
+
+ logger.setLevelInfo();
+ logger.info("MESSAGE DELIVERED to ad-hoc chat room: "
+ + sourceChatRoom.getName());
+
+ Message msg = evt.getMessage();
+
+ ChatPanel chatPanel = null;
+
+ ChatWindowManager chatWindowManager
+ = GuiActivator.getUIService().getChatWindowManager();
+
+ if(chatWindowManager.isChatOpenedForAdHocChatRoom(sourceChatRoom))
+ {
+ chatPanel = chatWindowManager.getAdHocMultiChat(sourceChatRoom);
+ }
+
+ String messageType = null;
+
+ if (evt.getEventType() ==
+ AdHocChatRoomMessageDeliveredEvent.CONVERSATION_MESSAGE_DELIVERED)
+ {
+ messageType = Chat.OUTGOING_MESSAGE;
+ }
+ else if (evt.getEventType()
+ == AdHocChatRoomMessageDeliveredEvent.ACTION_MESSAGE_DELIVERED)
+ {
+ messageType = Chat.ACTION_MESSAGE;
+ }
+
+ if(chatPanel != null)
+ {
+ chatPanel.addMessage(sourceChatRoom.getParentProvider()
+ .getAccountID().getUserID(),
+ evt.getTimestamp(),
+ messageType,
+ msg.getContent(),
+ msg.getContentType());
+ }
+ else
+ {
+ logger.setLevelError();
+ logger.error("chat panel is null, message NOT DELIVERED !");
+ }
+ }
+
+ /**
+ * Implements<tt>AdHocChatRoomMessageListener.messageDeliveryFailed</tt>
+ * method.
+ *<br>
+ * In the conversation area shows an error message, explaining the problem.
+ */
+ public void messageDeliveryFailed(
+ AdHocChatRoomMessageDeliveryFailedEvent evt) {
+ AdHocChatRoom sourceChatRoom = (AdHocChatRoom) evt.getSource();
+
+ String errorMsg = null;
+
+ Message sourceMessage = (Message) evt.getSource();
+
+ Contact destParticipant = evt.getDestinationParticipant();
+
+ if (evt.getErrorCode()
+ == MessageDeliveryFailedEvent.OFFLINE_MESSAGES_NOT_SUPPORTED)
+ {
+ errorMsg = GuiActivator.getResources().getI18NString(
+ "service.gui.MSG_DELIVERY_NOT_SUPPORTED");
+ }
+ else if (evt.getErrorCode()
+ == MessageDeliveryFailedEvent.NETWORK_FAILURE)
+ {
+ errorMsg = GuiActivator.getResources()
+ .getI18NString("service.gui.MSG_NOT_DELIVERED");
+ }
+ else if (evt.getErrorCode()
+ == MessageDeliveryFailedEvent.PROVIDER_NOT_REGISTERED)
+ {
+ errorMsg = GuiActivator.getResources().getI18NString(
+ "service.gui.MSG_SEND_CONNECTION_PROBLEM");
+ }
+ else if (evt.getErrorCode()
+ == MessageDeliveryFailedEvent.INTERNAL_ERROR)
+ {
+ errorMsg = GuiActivator.getResources().getI18NString(
+ "service.gui.MSG_DELIVERY_INTERNAL_ERROR");
+ }
+ else
+ {
+ errorMsg = GuiActivator.getResources().getI18NString(
+ "service.gui.MSG_DELIVERY_UNKNOWN_ERROR");
+ }
+
+ ChatWindowManager chatWindowManager
+ = GuiActivator.getUIService().getChatWindowManager();
+
+ ChatPanel chatPanel
+ = chatWindowManager.getAdHocMultiChat(sourceChatRoom);
+
+ chatPanel.addMessage(
+ destParticipant.getDisplayName(),
+ System.currentTimeMillis(),
+ Chat.OUTGOING_MESSAGE,
+ sourceMessage.getContent(),
+ sourceMessage.getContentType());
+
+ chatPanel.addErrorMessage(
+ destParticipant.getDisplayName(),
+ errorMsg);
+
+ chatWindowManager.openChat(chatPanel, false);
+ }
+
+ /**
+ * Implements the<tt>AdHocChatRoomMessageListener.messageReceived</tt>
+ * method.
+ *<br>
+ * Obtains the corresponding<tt>ChatPanel</tt> and process the message
+ * there.
+ */
+ public void messageReceived(AdHocChatRoomMessageReceivedEvent evt)
+ {
+ AdHocChatRoom sourceChatRoom = (AdHocChatRoom) evt.getSource();
+ Contact sourceParticipant = evt.getSourceChatRoomParticipant();
+
+ String messageType = null;
+
+ switch (evt.getEventType())
+ {
+ case AdHocChatRoomMessageReceivedEvent.CONVERSATION_MESSAGE_RECEIVED:
+ messageType = Chat.INCOMING_MESSAGE;
+ break;
+ case AdHocChatRoomMessageReceivedEvent.SYSTEM_MESSAGE_RECEIVED:
+ messageType = Chat.SYSTEM_MESSAGE;
+ break;
+ case AdHocChatRoomMessageReceivedEvent.ACTION_MESSAGE_RECEIVED:
+ messageType = Chat.ACTION_MESSAGE;
+ break;
+ }
+
+ logger.info("MESSAGE RECEIVED from contact: "
+ + sourceParticipant.getAddress());
+
+ Message message = evt.getMessage();
+
+ ChatPanel chatPanel = null;
+
+ ChatWindowManager chatWindowManager
+ = GuiActivator.getUIService().getChatWindowManager();
+
+ chatPanel = chatWindowManager
+ .getAdHocMultiChat(sourceChatRoom, message.getMessageUID());
+
+ String messageContent = message.getContent();
+
+ chatPanel.addMessage(
+ sourceParticipant.getDisplayName(),
+ evt.getTimestamp(),
+ messageType,
+ messageContent,
+ message.getContentType());
+
+ chatWindowManager.openChat(chatPanel, false);
+
+ // Fire notification
+ boolean fireChatNotification;
+
+ String nickname = sourceChatRoom.getName();
+
+ fireChatNotification =
+ (nickname == null)
+ || messageContent.toLowerCase().contains(
+ nickname.toLowerCase());
+
+ if (fireChatNotification)
+ {
+ String title
+ = GuiActivator.getResources().getI18NString(
+ "service.gui.MSG_RECEIVED",
+ new String[] { sourceParticipant.getDisplayName() });
+
+ NotificationManager.fireChatNotification(
+ sourceChatRoom,
+ NotificationManager.INCOMING_MESSAGE,
+ title,
+ messageContent);
+ }
+
+ }
+
+ public void invitationRejected(AdHocChatRoomInvitationRejectedEvent evt)
+ {
+ }
  }

Modified: trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/InvitationReceivedDialog.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/InvitationReceivedDialog.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/InvitationReceivedDialog.java&p2=trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/InvitationReceivedDialog.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/InvitationReceivedDialog.java (original)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/InvitationReceivedDialog.java 2009-09-14 15:51:47+0000
@@ -20,62 +20,76 @@
   * The dialog that pops up when a chat room invitation is received.
   *
   * @author Yana Stamcheva
+ * @author Valentin Martinet
   */
  public class InvitationReceivedDialog
      extends SIPCommDialog
      implements ActionListener
-{
+{
      private final JTextArea infoTextArea = new JTextArea();
-
+
      private final JTextArea invitationReasonTextArea = new JTextArea();
-
+
      private final JPanel reasonPanel = new JPanel(new BorderLayout());
-
+
      private final JLabel reasonLabel = new JLabel(
          GuiActivator.getResources().getI18NString("service.gui.REASON") + ": ");
-
+
      private final JTextField reasonField = new JTextField();

      private final JPanel dataPanel = new JPanel(new BorderLayout(10, 10));
-
- private final JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
-
+
+ private final JPanel buttonsPanel
+ = new JPanel(new FlowLayout(FlowLayout.RIGHT));
+
      private final JButton acceptButton = new JButton(
          GuiActivator.getResources().getI18NString("service.gui.ACCEPT"));
-
+
      private final JButton rejectButton = new JButton(
          GuiActivator.getResources().getI18NString("service.gui.REJECT"));
-
+
      private final JButton ignoreButton = new JButton(
          GuiActivator.getResources().getI18NString("service.gui.IGNORE"));
-
+
      private final JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
-
+
      private final JPanel northPanel = new JPanel(new BorderLayout(10, 10));
-
+
      private final JLabel iconLabel = new JLabel(new ImageIcon(
              ImageLoader.getImage(ImageLoader.INVITE_DIALOG_ICON)));
-
+
      private final String title = GuiActivator.getResources()
          .getI18NString("service.gui.INVITATION_RECEIVED");
-
+
      /**
       * The<tt>ChatRoomInvitation</tt> for which this dialog is.
       */
- private final ChatRoomInvitation invitation;
-
+ private ChatRoomInvitation invitation = null;;
+
+ /**
+ * The<tt>AdHocChatRoomInvitation</tt> for which this dialog is, in case of
+ * an<tt>AdHocChatRoom</tt>.
+ */
+ private AdHocChatRoomInvitation invitationAdHoc = null;
+
      /**
       * The<tt>MultiUserChatManager</tt> is the one that deals with invitation
       * events.
       */
      private final ConferenceChatManager multiUserChatManager;
-
+
      /**
       * The operation set that would handle the rejection if the user choose to
       * reject the invitation.
       */
- private final OperationSetMultiUserChat multiUserChatOpSet;
-
+ private OperationSetMultiUserChat multiUserChatOpSet = null;;
+
+ /**
+ * The operation set that would handle the rejection if the user choose to
+ * reject the invitation, in case of an<tt>AdHocChatRoom</tt>.
+ */
+ private OperationSetAdHocMultiUserChat multiUserChatAdHocOpSet = null;;
+
      /**
       * Constructs the<tt>ChatInviteDialog</tt>.
       *
@@ -122,32 +136,92 @@
              this.dataPanel.add(invitationReasonTextArea, BorderLayout.CENTER);
          }

+ this.initGUI();
+ }
+
+ /**
+ * Constructs the<tt>ChatInviteDialog</tt>, in case of an
+ *<tt>AdHocChatRoom</tt>.
+ *
+ * @param multiUserChatManager the<tt>MultiUserChatManager</tt> is the one
+ * that deals with invitation events
+ * @param multiUserChatAdHocOpSet the operation set that would handle the
+ * rejection if the user choose to reject the invitation
+ * @param invitationAdHoc the invitation that this dialog represents
+ */
+ public InvitationReceivedDialog (ConferenceChatManager multiUserChatManager,
+ OperationSetAdHocMultiUserChat multiUserChatAdHocOpSet,
+ AdHocChatRoomInvitation invitationAdHoc)
+ {
+ super(GuiActivator.getUIService().getMainFrame());
+
+ this.multiUserChatManager = multiUserChatManager;
+
+ this.multiUserChatAdHocOpSet = multiUserChatAdHocOpSet;
+
+ this.invitationAdHoc = invitationAdHoc;
+
+ this.setModal(false);
+
+ this.setTitle(title);
+
+ this.mainPanel.setPreferredSize(new Dimension(400, 230));
+
+// this.mainPanel.setOpaque(false);
+
+ infoTextArea.setText(
+ GuiActivator.getResources().getI18NString(
+ "service.gui.INVITATION_RECEIVED_MSG",
+ new String[] {
+ invitationAdHoc.getInviter(),
+ invitationAdHoc.getTargetAdHocChatRoom().getName()}));
+
+ if(invitationAdHoc.getReason() != null
+&& !invitationAdHoc.getReason().equals(""))
+ {
+ invitationReasonTextArea.setText(invitationAdHoc.getReason());
+ invitationReasonTextArea.setBorder(
+ BorderFactory.createTitledBorder(
+ GuiActivator.getResources()
+ .getI18NString("service.gui.INVITATION")));
+
+ this.dataPanel.add(invitationReasonTextArea, BorderLayout.CENTER);
+ }
+
+ this.initGUI();
+ }
+
+ /**
+ * Initializes and builds the GUI.
+ */
+ public void initGUI()
+ {
          this.infoTextArea.setFont(infoTextArea.getFont().deriveFont(Font.BOLD));
          this.infoTextArea.setLineWrap(true);
          this.infoTextArea.setOpaque(false);
          this.infoTextArea.setWrapStyleWord(true);
          this.infoTextArea.setEditable(false);
-
+
          this.northPanel.add(iconLabel, BorderLayout.WEST);
          this.northPanel.add(infoTextArea, BorderLayout.CENTER);
          this.northPanel.setOpaque(false);
-
+
          this.reasonPanel.add(reasonLabel, BorderLayout.WEST);
          this.reasonPanel.add(reasonField, BorderLayout.CENTER);
          this.reasonPanel.setOpaque(false);

          this.dataPanel.add(reasonPanel, BorderLayout.SOUTH);
          this.dataPanel.setOpaque(false);
-
+
          this.acceptButton.addActionListener(this);
          this.rejectButton.addActionListener(this);
          this.ignoreButton.addActionListener(this);
-
+
          this.buttonsPanel.add(acceptButton);
          this.buttonsPanel.add(rejectButton);
          this.buttonsPanel.add(ignoreButton);
          this.buttonsPanel.setOpaque(false);
-
+
          this.getRootPane().setDefaultButton(acceptButton);
          this.acceptButton.setMnemonic(
              GuiActivator.getResources().getI18nMnemonic("service.gui.ACCEPT"));
@@ -155,18 +229,18 @@
              GuiActivator.getResources().getI18nMnemonic("service.gui.REJECT"));
          this.ignoreButton.setMnemonic(
              GuiActivator.getResources().getI18nMnemonic("service.gui.IGNORE"));
-
+
          this.mainPanel.setBorder(
              BorderFactory.createEmptyBorder(15, 15, 15, 15));
-
+
          this.mainPanel.add(northPanel, BorderLayout.NORTH);
          this.mainPanel.add(dataPanel, BorderLayout.CENTER);
          this.mainPanel.add(buttonsPanel, BorderLayout.SOUTH);
          this.mainPanel.setOpaque(false);
-
+
          this.getContentPane().add(mainPanel);
      }
-
+
      /**
       * Handles the<tt>ActionEvent</tt> triggered when one user clicks
       * on one of the buttons.
@@ -174,17 +248,31 @@
      public void actionPerformed(ActionEvent e)
      {
          JButton button = (JButton)e.getSource();
-
+
          if (button.equals(acceptButton))
          {
- multiUserChatManager.acceptInvitation(invitation);
+ if(invitationAdHoc == null)
+ multiUserChatManager.acceptInvitation(invitation);
+ else
+ try
+ {
+ multiUserChatManager.acceptInvitation(
+ invitationAdHoc, multiUserChatAdHocOpSet);
+ } catch (OperationFailedException e1)
+ {
+ e1.printStackTrace();
+ }
          }
          else if (button.equals(rejectButton))
          {
- multiUserChatManager.rejectInvitation(multiUserChatOpSet,
- invitation, reasonField.getText());
+ if(multiUserChatAdHocOpSet == null&& invitationAdHoc == null)
+ multiUserChatManager.rejectInvitation(multiUserChatOpSet,
+ invitation, reasonField.getText());
+ else
+ multiUserChatManager.rejectInvitation(multiUserChatAdHocOpSet,
+ invitationAdHoc, reasonField.getText());
          }
-
+
          this.dispose();
      }

Added: trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/AdHocChatRoomList.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/AdHocChatRoomList.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/AdHocChatRoomList.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,308 @@
+/*
+ * 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.chatroomslist;
+
+import java.util.*;
+
+import net.java.sip.communicator.impl.gui.*;
+import net.java.sip.communicator.impl.gui.main.chat.conference.*;
+import net.java.sip.communicator.service.configuration.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.util.*;
+
+import org.osgi.framework.*;
+
+/**
+ * The<tt>AdHocChatRoomsList</tt> is the list containing all ad-hoc chat rooms.
+ *
+ * @author Valentin Martinet
+ */
+public class AdHocChatRoomList
+{
+ private static final Logger logger
+ = Logger.getLogger(AdHocChatRoomList.class);
+
+ /**
+ * The list containing all chat servers and ad-hoc rooms.
+ */
+ private final List<AdHocChatRoomProviderWrapper> providersList
+ = new Vector<AdHocChatRoomProviderWrapper>();
+
+ /**
+ * Initializes the list of ad-hoc chat rooms.
+ */
+ public void loadList()
+ {
+ try
+ {
+ ServiceReference[] serRefs
+ = GuiActivator.bundleContext.getServiceReferences(
+ ProtocolProviderService.class.getName(),
+ null);
+
+ // If we don't have providers at this stage we just return.
+ if (serRefs == null)
+ return;
+ logger.setLevelDebug();
+ for (ServiceReference serRef : serRefs)
+ {
+ ProtocolProviderService protocolProvider
+ = (ProtocolProviderService)
+ GuiActivator.bundleContext.getService(serRef);
+
+ Object adHocMultiUserChatOpSet
+ = protocolProvider
+ .getOperationSet(OperationSetAdHocMultiUserChat.class);
+
+ if (adHocMultiUserChatOpSet != null)
+ {
+ this.addChatProvider(protocolProvider);
+ }
+ }
+ }
+ catch (InvalidSyntaxException e)
+ {
+ logger.error("Failed to obtain service references.", e);
+ }
+ }
+
+ /**
+ * Adds a chat server and all its existing ad-hoc chat rooms.
+ *
+ * @param pps the<tt>ProtocolProviderService</tt> corresponding to the chat
+ * server
+ * @param adHocMultiUserChatOperationSet the
+ *<tt>OperationSetAdHocMultiUserChat</tt> from which we manage ad-hoc chat
+ * rooms
+ */
+ public void addChatProvider(ProtocolProviderService pps)
+ {
+ AdHocChatRoomProviderWrapper chatRoomProvider
+ = new AdHocChatRoomProviderWrapper(pps);
+
+ providersList.add(chatRoomProvider);
+
+ ConfigurationService configService
+ = GuiActivator.getConfigurationService();
+
+ String prefix = "net.java.sip.communicator.impl.gui.accounts";
+
+ List<String> accounts =
+ configService.getPropertyNamesByPrefix(prefix, true);
+
+ for (String accountRootPropName : accounts) {
+ String accountUID
+ = configService.getString(accountRootPropName);
+
+ if(accountUID.equals(pps
+ .getAccountID().getAccountUniqueID()))
+ {
+ List<String> chatRooms = configService
+ .getPropertyNamesByPrefix(
+ accountRootPropName + ".chatRooms", true);
+
+ for (String chatRoomPropName : chatRooms)
+ {
+ String chatRoomID
+ = configService.getString(chatRoomPropName);
+
+ String chatRoomName = configService.getString(
+ chatRoomPropName + ".chatRoomName");
+
+ AdHocChatRoomWrapper chatRoomWrapper
+ = new AdHocChatRoomWrapper( chatRoomProvider,
+ chatRoomID,
+ chatRoomName);
+
+ chatRoomProvider.addAdHocChatRoom(chatRoomWrapper);
+ }
+ }
+ }
+ }
+
+ /**
+ * Removes the corresponding server and all related ad-hoc chat rooms from
+ * this list.
+ *
+ * @param pps the<tt>ProtocolProviderService</tt> corresponding to the
+ * server to remove
+ */
+ public void removeChatProvider(ProtocolProviderService pps)
+ {
+ AdHocChatRoomProviderWrapper wrapper =
+ findServerWrapperFromProvider(pps);
+
+ if (wrapper != null)
+ removeChatProvider(wrapper);
+ }
+
+ /**
+ * Removes the corresponding server and all related ad-hoc chat rooms from
+ * this list.
+ *
+ * @param adHocChatRoomProvider the<tt>AdHocChatRoomProviderWrapper</tt>
+ * corresponding to the server to remove
+ */
+ private void removeChatProvider(
+ AdHocChatRoomProviderWrapper adHocChatRoomProvider)
+ {
+ providersList.remove(adHocChatRoomProvider);
+
+ ConfigurationService configService
+ = GuiActivator.getConfigurationService();
+ String prefix = "net.java.sip.communicator.impl.gui.accounts";
+ String providerAccountUID
+ = adHocChatRoomProvider
+ .getProtocolProvider().getAccountID().getAccountUniqueID();
+
+ for (String accountRootPropName
+ : configService.getPropertyNamesByPrefix(prefix, true))
+ {
+ String accountUID
+ = configService.getString(accountRootPropName);
+
+ if(accountUID.equals(providerAccountUID))
+ {
+ List<String> chatRooms
+ = configService.getPropertyNamesByPrefix(
+ accountRootPropName + ".chatRooms",
+ true);
+
+ for (String chatRoomPropName : chatRooms)
+ {
+ configService.setProperty(
+ chatRoomPropName + ".chatRoomName",
+ null);
+ }
+
+ configService.setProperty(accountRootPropName, null);
+ }
+ }
+ }
+
+ /**
+ * Adds a chat room to this list.
+ *
+ * @param adHocChatRoomWrapper the<tt>AdHocChatRoom</tt> to add
+ */
+ public void addAdHocChatRoom(AdHocChatRoomWrapper adHocChatRoomWrapper)
+ {
+ AdHocChatRoomProviderWrapper adHocChatRoomProvider
+ = adHocChatRoomWrapper.getParentProvider();
+
+ if (!adHocChatRoomProvider.containsAdHocChatRoom(adHocChatRoomWrapper))
+ adHocChatRoomProvider.addAdHocChatRoom(adHocChatRoomWrapper);
+ }
+
+ /**
+ * Removes the given<tt>AdHocChatRoom</tt> from the list of all ad-hoc
+ * chat rooms.
+ *
+ * @param adHocChatRoomWrapper the<tt>AdHocChatRoomWrapper</tt> to remove
+ */
+ public void removeChatRoom(AdHocChatRoomWrapper adHocChatRoomWrapper)
+ {
+ AdHocChatRoomProviderWrapper adHocChatRoomProvider
+ = adHocChatRoomWrapper.getParentProvider();
+
+ if (providersList.contains(adHocChatRoomProvider))
+ {
+ adHocChatRoomProvider.removeChatRoom(adHocChatRoomWrapper);
+ }
+ }
+
+ /**
+ * Returns the<tt>AdHocChatRoomWrapper</tt> that correspond to the given
+ *<tt>AdHocChatRoom</tt>. If the list of ad-hoc chat rooms doesn't contain
+ * a corresponding wrapper - returns null.
+ *
+ * @param adHocChatRoom the<tt>ChatRoom</tt> that we're looking for
+ * @return the<tt>ChatRoomWrapper</tt> object corresponding to the given
+ *<tt>ChatRoom</tt>
+ */
+ public AdHocChatRoomWrapper findChatRoomWrapperFromAdHocChatRoom(
+ AdHocChatRoom adHocChatRoom)
+ {
+ for (AdHocChatRoomProviderWrapper provider : providersList)
+ {
+ AdHocChatRoomWrapper chatRoomWrapper
+ = provider.findChatRoomWrapperForAdHocChatRoom(
+ adHocChatRoom);
+
+ if (chatRoomWrapper != null)
+ {
+ // stored chatrooms has no chatroom, but their
+ // id is the same as the chatroom we are searching wrapper
+ // for
+ if(chatRoomWrapper.getAdHocChatRoom() == null)
+ {
+ chatRoomWrapper.setAdHocChatRoom(adHocChatRoom);
+ }
+
+ return chatRoomWrapper;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the<tt>AdHocChatRoomProviderWrapper</tt> that correspond to the
+ * given<tt>ProtocolProviderService</tt>. If the list doesn't contain a
+ * corresponding wrapper - returns null.
+ *
+ * @param protocolProvider the protocol provider that we're looking for
+ * @return the<tt>AdHocChatRoomProvider</tt> object corresponding to
+ * the given<tt>ProtocolProviderService</tt>
+ */
+ public AdHocChatRoomProviderWrapper findServerWrapperFromProvider(
+ ProtocolProviderService protocolProvider)
+ {
+ for(AdHocChatRoomProviderWrapper chatRoomProvider : providersList)
+ {
+ if(chatRoomProvider.getProtocolProvider().equals(protocolProvider))
+ {
+ return chatRoomProvider;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Goes through the locally stored chat rooms list and for each
+ * {@link AdHocChatRoomWrapper} tries to find the corresponding server
+ * stored {@link AdHocChatRoom} in the specified operation set. Joins
+ * automatically all found ad-hoc chat rooms.
+ *
+ * @param protocolProvider the protocol provider for the account to
+ * synchronize
+ * @param opSet the ad-hoc multi user chat operation set, which give us
+ * access to chat room server
+ */
+ public void synchronizeOpSetWithLocalContactList(
+ ProtocolProviderService protocolProvider,
+ final OperationSetAdHocMultiUserChat opSet)
+ {
+ AdHocChatRoomProviderWrapper chatRoomProvider
+ = findServerWrapperFromProvider(protocolProvider);
+
+ if (chatRoomProvider != null)
+ {
+ chatRoomProvider.synchronizeProvider();
+ }
+ }
+
+ /**
+ * Returns an iterator to the list of ad-hoc chat room providers.
+ *
+ * @return an iterator to the list of ad-hoc chat room providers.
+ */
+ public Iterator<AdHocChatRoomProviderWrapper> getAdHocChatRoomProviders()
+ {
+ return providersList.iterator();
+ }
+}

Added: trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/AdHocChatRoomListChangeEvent.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/AdHocChatRoomListChangeEvent.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/AdHocChatRoomListChangeEvent.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,92 @@
+/*
+ * 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.chatroomslist;
+
+import java.util.*;
+
+import net.java.sip.communicator.impl.gui.main.chat.conference.*;
+
+/**
+ * Parent class for gui ad-hoc chat room events indicating addition and removal
+ * of ad-hoc chat rooms in the gui ad-hoc chat rooms list.
+ *
+ * @author Valentin Martinet
+ */
+public class AdHocChatRoomListChangeEvent
+ extends EventObject
+{
+ private int eventID = -1;
+
+ /**
+ * Indicates that the AdHocChatRoomListChangeEvent instance was triggered by
+ * adding a AdHocChatRoom in the gui.
+ */
+ public static final int AD_HOC_CHAT_ROOM_ADDED = 1;
+
+ /**
+ * Indicates that the AdHocChatRoomListChangeEvent instance was triggered by
+ * removing a AdHocChatRoom from the gui.
+ */
+ public static final int AD_HOC_CHAT_ROOM_REMOVED = 2;
+
+ /**
+ * Indicates that the AdHocChatRoomListChangeEvent instance was triggered by
+ * changing a AdHocChatRoom in the gui (like changing its status, etc.).
+ */
+ public static final int AD_HOC_CHAT_ROOM_CHANGED = 3;
+
+ /**
+ * Creates a new<tt>AdHocChatRoom</tt> event according to the specified
+ * parameters.
+ *
+ * @param source the<tt>AdHocChatRoom</tt> instance that is added to the
+ * AdHocChatRoomsList
+ * @param eventID one of the AD_HOC_CHAT_ROOM_XXX static fields indicating
+ * the nature of the event.
+ */
+ public AdHocChatRoomListChangeEvent(AdHocChatRoomWrapper source,
+ int eventID)
+ {
+ super(source);
+ this.eventID = eventID;
+ }
+
+ /**
+ * Returns the source<tt>AdHocChatRoom</tt>.
+ * @return the source<tt>AdHocChatRoom</tt>.
+ */
+ public AdHocChatRoomWrapper getSourceAdHocChatRoom()
+ {
+ return (AdHocChatRoomWrapper) getSource();
+ }
+
+ /**
+ * Returns a String representation of this<tt>GuiAdHocChatRoomEvent</tt>.
+ *
+ * @return A String representation of this<tt>GuiAdHocChatRoomEvent</tt>.
+ */
+ public String toString()
+ {
+ StringBuffer buff
+ = new StringBuffer("GuiAdHocChatRoomEvent-[ AdHocChatRoomID=");
+ buff.append(getSourceAdHocChatRoom().getAdHocChatRoomName());
+ buff.append(", eventID=").append(getEventID());
+ buff.append(", ProtocolProvider=");
+
+ return buff.toString();
+ }
+
+ /**
+ * Returns an event id specifying whether the type of this event (e.g.
+ * CHAT_ROOM_ADDED or CHAT_ROOM_REMOVED)
+ * @return one of the CHAT_ROOM_XXX int fields of this class.
+ */
+ public int getEventID()
+ {
+ return eventID;
+ }
+}

Added: trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/AdHocChatRoomListChangeListener.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/AdHocChatRoomListChangeListener.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/AdHocChatRoomListChangeListener.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,20 @@
+/*
+ * 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.chatroomslist;
+
+/**
+ * Listener that dispatches events coming from the ad-hoc chat room list.
+ *
+ * @author Valentin Martinet
+ */
+public interface AdHocChatRoomListChangeListener
+{
+ /**
+ * Indicates that a change has occurred in the ad-hoc chat room data list.
+ */
+ public void contentChanged(AdHocChatRoomListChangeEvent evt);
+}

Modified: trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomList.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomList.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomList.java&p2=trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomList.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomList.java (original)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomList.java 2009-09-14 15:51:47+0000
@@ -82,7 +82,9 @@
              = new ChatRoomProviderWrapper(pps);

          providersList.add(chatRoomProvider);
-
+
          ConfigurationService configService
              = GuiActivator.getConfigurationService();

Modified: trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomListUI.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomListUI.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomListUI.java&p2=trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomListUI.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomListUI.java (original)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomListUI.java 2009-09-14 15:51:47+0000
@@ -26,7 +26,8 @@
  public class ChatRoomListUI
      extends SCScrollPane
      implements MouseListener,
- ChatRoomListChangeListener
+ ChatRoomListChangeListener,
+ AdHocChatRoomListChangeListener
  {
      private final JList chatRoomList = new JList();

@@ -41,8 +42,11 @@
       */
      public ChatRoomListUI(ChatRoomListDialog parentDialog)
      {
- GuiActivator.getUIService().getConferenceChatManager()
- .addChatRoomListChangeListener(this);
+ ConferenceChatManager confChatManager
+ = GuiActivator.getUIService().getConferenceChatManager();
+
+ confChatManager.addChatRoomListChangeListener(this);
+ confChatManager.addAdHocChatRoomListChangeListener(this);

          this.treePanel.add(chatRoomList, BorderLayout.NORTH);

@@ -249,4 +253,43 @@
              chatRoomsListModel.contentChanged(index, index);
          }
      }
+
+ /**
+ * Updates the chat room list model when notified of a change in the chat
+ * room list.
+ */
+ public void contentChanged(AdHocChatRoomListChangeEvent evt)
+ {
+ AdHocChatRoomWrapper chatRoomWrapper = evt.getSourceAdHocChatRoom();
+
+ if (evt.getEventID()
+ == AdHocChatRoomListChangeEvent.AD_HOC_CHAT_ROOM_ADDED)
+ {
+ int index = chatRoomsListModel.indexOf(chatRoomWrapper);
+
+ if (index != -1)
+ chatRoomsListModel.contentAdded(index, index);
+ }
+ else if (evt.getEventID()
+ == AdHocChatRoomListChangeEvent.AD_HOC_CHAT_ROOM_REMOVED)
+ {
+ int groupIndex = chatRoomsListModel.indexOf(
+ chatRoomWrapper.getParentProvider());
+
+ int listSize = chatRoomsListModel.getSize();
+
+ if (groupIndex != -1&& listSize> 0)
+ {
+ chatRoomsListModel.contentChanged(groupIndex, listSize - 1);
+ chatRoomsListModel.contentRemoved(listSize, listSize);
+ }
+ }
+ else if (evt.getEventID()
+ == AdHocChatRoomListChangeEvent.AD_HOC_CHAT_ROOM_CHANGED)
+ {
+ int index = chatRoomsListModel.indexOf(chatRoomWrapper);
+
+ chatRoomsListModel.contentChanged(index, index);
+ }
+ }
  }

Modified: trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/createforms/CreateChatRoomDialog.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/createforms/CreateChatRoomDialog.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/createforms/CreateChatRoomDialog.java&p2=trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/createforms/CreateChatRoomDialog.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/createforms/CreateChatRoomDialog.java (original)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/createforms/CreateChatRoomDialog.java 2009-09-14 15:51:47+0000
@@ -17,8 +17,8 @@
  import net.java.sip.communicator.util.swing.*;

  /**
- * The<tt>CreateChatRoomDialog</tt> is the dialog containing the form for adding
- * a chat room. It is different from the "Create chat room" wizard. The
+ * The<tt>CreateChatRoomDialog</tt> is the dialog containing the form for
+ * adding a chat room. It is different from the "Create chat room" wizard. The
   *<tt>CreateChatRoomDialog</tt> is used when a new chat room
   * is added to an already existing server in the list.
   *
@@ -44,8 +44,8 @@
      private ChatRoomProviderWrapper chatRoomProvider;

      /**
- * Creates an instance of<tt>CreateChatRoomDialog</tt> that represents a dialog
- * that adds a new chat room to an already existing server.
+ * Creates an instance of<tt>CreateChatRoomDialog</tt> that represents a
+ * dialog that adds a new chat room to an already existing server.
       *
       * @param provider The<tt>ChatRoomProviderWrapper</tt>.
       */
@@ -63,31 +63,31 @@
      {
          this.setTitle(GuiActivator.getResources()
                  .getI18NString("service.gui.CREATE_CHAT_ROOM"));
-
+
          this.setSize(620, 450);
          this.setPreferredSize(new Dimension(620, 450));
-
+
          this.getRootPane().setDefaultButton(addButton);
          this.addButton.setName("create");
          this.cancelButton.setName("cancel");
-
+
          this.addButton.setMnemonic(
              GuiActivator.getResources().getI18nMnemonic("service.gui.CREATE"));
-
+
          this.cancelButton.setMnemonic(
              GuiActivator.getResources().getI18nMnemonic("service.gui.CANCEL"));
-
+
          this.addButton.addActionListener(this);
          this.cancelButton.addActionListener(this);
-
+
          this.buttonsPanel.add(addButton);
          this.buttonsPanel.add(cancelButton);
-
+
          this.mainPanel.setBorder(BorderFactory.createEmptyBorder(5, 10, 0, 10));
-
+
          this.mainPanel.add(chatRoomPanel, BorderLayout.CENTER);
          this.mainPanel.add(buttonsPanel, BorderLayout.SOUTH);
-
+
          this.getContentPane().add(mainPanel);
      }

@@ -105,7 +105,7 @@

              GuiActivator.getUIService().getConferenceChatManager()
                  .createChatRoom(chatRoomName,
- chatRoomProvider.getProtocolProvider());
+ chatRoomProvider.getProtocolProvider(), null);
          }
          this.dispose();
      }

Modified: trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/createforms/CreateChatRoomWizard.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/createforms/CreateChatRoomWizard.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/createforms/CreateChatRoomWizard.java&p2=trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/createforms/CreateChatRoomWizard.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/createforms/CreateChatRoomWizard.java (original)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/createforms/CreateChatRoomWizard.java 2009-09-14 15:51:47+0000
@@ -21,11 +21,11 @@
      implements WizardListener
  {
      private NewChatRoom newChatRoom = new NewChatRoom();
-
+
      private CreateChatRoomWizardPage1 page1;
-
+
      private CreateChatRoomWizardPage2 page2;
-
+
      /**
       * Creates an instance of<tt>CreateChatRoomWizard</tt>.
       *
@@ -64,7 +64,8 @@
          {
              GuiActivator.getUIService().getConferenceChatManager()
                  .createChatRoom(newChatRoom.getChatRoomName(),
- newChatRoom.getProtocolProvider());
+ newChatRoom.getProtocolProvider(),
+ null);
          }
      }
  }

Modified: trunk/src/net/java/sip/communicator/impl/gui/main/login/LoginManager.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/login/LoginManager.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/gui/main/login/LoginManager.java&p2=trunk/src/net/java/sip/communicator/impl/gui/main/login/LoginManager.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/gui/main/login/LoginManager.java (original)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/login/LoginManager.java 2009-09-14 15:51:47+0000
@@ -108,7 +108,8 @@

                  if (status == null
                      >> status.equals(Constants.ONLINE_STATUS)
- || ((status instanceof PresenceStatus)&& (((PresenceStatus) status)
+ || ((status instanceof PresenceStatus)
+&& (((PresenceStatus) status)
                          .getStatus()>= PresenceStatus.ONLINE_THRESHOLD)))
                  {
                      this.login(protocolProvider);
@@ -138,8 +139,9 @@
          {
              OperationSetPresence presence = mainFrame
                  .getProtocolPresenceOpSet(protocolProvider);
- OperationSetMultiUserChat multiUserChat = mainFrame
- .getMultiUserChatOpSet(protocolProvider);
+
+ OperationSetMultiUserChat multiUserChat =
+ mainFrame.getMultiUserChatOpSet(protocolProvider);

              if (presence != null)
              {
@@ -153,6 +155,7 @@
                      .getChatRoomList().synchronizeOpSetWithLocalContactList(
                          protocolProvider, multiUserChat);
              }
+
          }
          else if (newState.equals(RegistrationState.AUTHENTICATION_FAILED))
          {

Modified: trunk/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java&p2=trunk/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java (original)
+++ trunk/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java 2009-09-14 15:51:47+0000
@@ -25,20 +25,24 @@
  import net.java.sip.communicator.util.*;

  /**
- * The Message History Service stores messages exchanged through the various protocols
+ * The Message History Service stores messages exchanged through the various
+ * protocols
   * Logs messages for all protocol providers that support basic instant messaging
   * (i.e. those that implement OperationSetBasicInstantMessaging).
   *
   * @author Alexander Pelov
   * @author Damian Minkov
   * @author Lubomir Marinov
+ * @author Valentin Martinet
   */
  public class MessageHistoryServiceImpl
      implements MessageHistoryService,
                  MessageListener,
                  ChatRoomMessageListener,
+ AdHocChatRoomMessageListener,
                  ServiceListener,
- LocalUserChatRoomPresenceListener
+ LocalUserChatRoomPresenceListener,
+ LocalUserAdHocChatRoomPresenceListener
  {
      /**
       * The logger for this class.
@@ -47,7 +51,8 @@
              .getLogger(MessageHistoryServiceImpl.class);

      private static String[] STRUCTURE_NAMES =
- new String[] { "dir", "msg_CDATA", "msgTyp", "enc", "uid", "sub", "receivedTimestamp" };
+ new String[] { "dir", "msg_CDATA", "msgTyp", "enc", "uid", "sub",
+ "receivedTimestamp" };

      private static HistoryRecordStructure recordStructure =
          new HistoryRecordStructure(STRUCTURE_NAMES);
@@ -89,7 +94,8 @@
       * @return Collection of MessageReceivedEvents or MessageDeliveredEvents
       * @throws RuntimeException
       */
- public Collection<EventObject> findByStartDate(MetaContact contact, Date startDate)
+ public Collection<EventObject> findByStartDate( MetaContact contact,
+ Date startDate)
          throws RuntimeException
      {
          TreeSet<EventObject> result =
@@ -109,7 +115,8 @@
              Iterator<HistoryRecord> recs = reader.findByStartDate(startDate);
              while (recs.hasNext())
              {
- result.add(convertHistoryRecordToMessageEvent(recs.next(), item));
+ result.add(
+ convertHistoryRecordToMessageEvent(recs.next(), item));
              }
          }

@@ -119,7 +126,8 @@
          return result;
      }

- private void removeHistorySearchProgressListeners(Map<?, HistoryReader> readers)
+ private void removeHistorySearchProgressListeners(
+ Map<?, HistoryReader> readers)
      {
          for (HistoryReader item : readers.values())
              removeHistorySearchProgressListeners(item);
@@ -134,10 +142,12 @@
       * @return Collection of MessageReceivedEvents or MessageDeliveredEvents
       * @throws RuntimeException
       */
- public Collection<EventObject> findByEndDate(MetaContact contact, Date endDate)
+ public Collection<EventObject> findByEndDate( MetaContact contact,
+ Date endDate)
          throws RuntimeException
      {
- TreeSet<EventObject> result = new TreeSet<EventObject>(new MessageEventComparator<EventObject>());
+ TreeSet<EventObject> result = new TreeSet<EventObject>(
+ new MessageEventComparator<EventObject>());

          // get the readers for this contact
          Map<Contact, HistoryReader> readers = getHistoryReaders(contact);
@@ -154,7 +164,8 @@
              Iterator<HistoryRecord> recs = reader.findByEndDate(endDate);
              while (recs.hasNext())
              {
- result.add(convertHistoryRecordToMessageEvent(recs.next(), item));
+ result
+ .add(convertHistoryRecordToMessageEvent(recs.next(), item));
              }
          }

@@ -174,10 +185,14 @@
       * @return Collection of MessageReceivedEvents or MessageDeliveredEvents
       * @throws RuntimeException
       */
- public Collection<EventObject> findByPeriod(MetaContact contact, Date startDate, Date endDate)
+ public Collection<EventObject> findByPeriod(MetaContact contact,
+ Date startDate,
+ Date endDate)
          throws RuntimeException
      {
- TreeSet<EventObject> result = new TreeSet<EventObject>(new MessageEventComparator<EventObject>());
+ TreeSet<EventObject> result
+ = new TreeSet<EventObject>(new MessageEventComparator<EventObject>());
+
          // get the readers for this contact
          Map<Contact, HistoryReader> readers = getHistoryReaders(contact);

@@ -191,10 +206,12 @@
              // add the progress listeners
              addHistorySearchProgressListeners(reader, recordsCount);

- Iterator<HistoryRecord> recs = reader.findByPeriod(startDate, endDate);
+ Iterator<HistoryRecord> recs
+ = reader.findByPeriod(startDate, endDate);
              while (recs.hasNext())
              {
- result.add(convertHistoryRecordToMessageEvent(recs.next(), item));
+ result
+ .add(convertHistoryRecordToMessageEvent(recs.next(), item));
              }
          }

@@ -233,7 +250,8 @@
       * @return Collection of MessageReceivedEvents or MessageDeliveredEvents
       * @throws RuntimeException
       */
- public Collection<EventObject> findByKeyword(MetaContact contact, String keyword)
+ public Collection<EventObject> findByKeyword( MetaContact contact,
+ String keyword)
          throws RuntimeException
      {
          return findByKeyword(contact, keyword, false);
@@ -248,15 +266,16 @@
       * @return Collection of MessageReceivedEvents or MessageDeliveredEvents
       * @throws RuntimeException
       */
- public Collection<EventObject> findByKeywords(MetaContact contact, String[] keywords)
+ public Collection<EventObject> findByKeywords( MetaContact contact,
+ String[] keywords)
          throws RuntimeException
      {
          return findByKeywords(contact, keywords, false);
      }

      /**
- * Returns the supplied number of recent messages exchanged by all the contacts
- * in the supplied metacontact
+ * Returns the supplied number of recent messages exchanged by all the
+ * contacts in the supplied metacontact
       *
       * @param contact MetaContact
       * @param count messages count
@@ -266,7 +285,9 @@
      public Collection<EventObject> findLast(MetaContact contact, int count)
          throws RuntimeException
      {
- TreeSet<EventObject> result = new TreeSet<EventObject>(new MessageEventComparator<EventObject>());
+ TreeSet<EventObject> result
+ = new TreeSet<EventObject>(
+ new MessageEventComparator<EventObject>());

          Iterator<Contact> iter = contact.getContacts();
          while (iter.hasNext())
@@ -292,7 +313,8 @@
              }
          }

- LinkedList<EventObject> resultAsList = new LinkedList<EventObject>(result);
+ LinkedList<EventObject> resultAsList
+ = new LinkedList<EventObject>(result);
          int startIndex = resultAsList.size() - count;

          if(startIndex< 0)
@@ -311,10 +333,13 @@
       * @return Collection of MessageReceivedEvents or MessageDeliveredEvents
       * @throws RuntimeException
       */
- public Collection<EventObject> findFirstMessagesAfter(MetaContact contact, Date date,
- int count) throws RuntimeException
+ public Collection<EventObject> findFirstMessagesAfter( MetaContact contact,
+ Date date,
+ int count)
+ throws RuntimeException
      {
- TreeSet<EventObject> result = new TreeSet<EventObject>(new MessageEventComparator<EventObject>());
+ TreeSet<EventObject> result = new TreeSet<EventObject>(
+ new MessageEventComparator<EventObject>());

          Iterator<Contact> iter = contact.getContacts();
          while (iter.hasNext())
@@ -329,10 +354,11 @@
                  // date param of method is the one saved in receivedTimestamp
                  // the method findFirstRecordsAfter compares to the
                  // attribute timestamp. Most of the times there is 1 or 2 mills
- // difference between the two dates. So we will request more records
- // from the reader and than will get the needed count according
- // to the correct field comparsion (receivedTimestamp)
- Iterator<HistoryRecord> recs = reader.findFirstRecordsAfter(date, count + 4);
+ // difference between the two dates. So we will request more
+ // records from the reader and than will get the needed count
+ // according to the correct field comparsion (receivedTimestamp)
+ Iterator<HistoryRecord> recs
+ = reader.findFirstRecordsAfter(date, count + 4);
                  while (recs.hasNext())
                  {
                      result.add(
@@ -356,19 +382,22 @@
              if(object instanceof MessageDeliveredEvent)
              {
                  isRecordOK =
- (((MessageDeliveredEvent)object).getTimestamp()> date.getTime());
+ (((MessageDeliveredEvent)object).getTimestamp()
+> date.getTime());
              }
              else if(object instanceof MessageReceivedEvent)
              {
                  isRecordOK =
- (((MessageReceivedEvent)object).getTimestamp()> date.getTime());
+ (((MessageReceivedEvent)object).getTimestamp()
+> date.getTime());
              }

              if(!isRecordOK)
                  startIx++;
          }

- LinkedList<EventObject> resultAsList = new LinkedList<EventObject>(result);
+ LinkedList<EventObject> resultAsList
+ = new LinkedList<EventObject>(result);

          int toIndex = startIx + count;
          if(toIndex> resultAsList.size())
@@ -387,10 +416,13 @@
       * @return Collection of MessageReceivedEvents or MessageDeliveredEvents
       * @throws RuntimeException
       */
- public Collection<EventObject> findLastMessagesBefore(MetaContact contact, Date date,
- int count) throws RuntimeException
+ public Collection<EventObject> findLastMessagesBefore( MetaContact contact,
+ Date date,
+ int count)
+ throws RuntimeException
      {
- TreeSet<EventObject> result = new TreeSet<EventObject>(new MessageEventComparator<EventObject>());
+ TreeSet<EventObject> result = new TreeSet<EventObject>(
+ new MessageEventComparator<EventObject>());

          Iterator<Contact> iter = contact.getContacts();
          while (iter.hasNext())
@@ -402,7 +434,8 @@
                  History history = this.getHistory(null, item);

                  HistoryReader reader = history.getReader();
- Iterator<HistoryRecord> recs = reader.findLastRecordsBefore(date, count);
+ Iterator<HistoryRecord> recs
+ = reader.findLastRecordsBefore(date, count);
                  while (recs.hasNext())
                  {
                      result.add(
@@ -416,7 +449,8 @@
              }
          }

- LinkedList<EventObject> resultAsList = new LinkedList<EventObject>(result);
+ LinkedList<EventObject> resultAsList
+ = new LinkedList<EventObject>(result);
          int startIndex = resultAsList.size() - count;

          if(startIndex< 0)
@@ -445,7 +479,8 @@

          String account = "unkown";
          if (remoteContact != null)
- account = remoteContact.getProtocolProvider().getAccountID().getAccountUniqueID();
+ account = remoteContact.getProtocolProvider()
+ .getAccountID().getAccountUniqueID();

          HistoryID historyId = HistoryID.createFromRawID(
              new String[] { "messages",
@@ -513,6 +548,28 @@
              account.getService(),
              room.getName());
      }
+
+ /**
+ * Returns the history by specified local contact
+ * (if is null the default is used)
+ * and by the ad-hoc chat room
+ *
+ * @param room The ad-hoc chat room
+ * @return History the history - created if not existing
+ * @throws IOException
+ */
+ private History getHistoryForAdHocMultiChat(
+ AdHocChatRoom room)
+ throws IOException
+ {
+ AccountID account = room.getParentProvider().getAccountID();
+
+ return this.getHistoryForMultiChat(
+ null,
+ account.getAccountUniqueID(),
+ account.getService(),
+ room.getName());
+ }

      /**
       * Returns the history by specified local contact
@@ -557,21 +614,24 @@
      }

      /**
- * Used to convert HistoryRecord in MessageDeliveredEvent or MessageReceivedEvent
- * which are returned by the finder methods
+ * Used to convert HistoryRecord in MessageDeliveredEvent or
+ * MessageReceivedEvent which are returned by the finder methods
       *
       * @param hr HistoryRecord
       * @param contact Contact
       * @return Object
       */
- private EventObject convertHistoryRecordToMessageEvent(HistoryRecord hr, Contact contact)
+ private EventObject convertHistoryRecordToMessageEvent( HistoryRecord hr,
+ Contact contact)
      {
          MessageImpl msg = createMessageFromHistoryRecord(hr);
          long timestamp;

          // if there is value for date of receiving the message
- // this is the event timestamp (this is the date that had came from protocol)
- // the HistoryRecord timestamp is the timestamp when the record was written
+ // this is the event timestamp (this is the date that had came
+ // from protocol)
+ // the HistoryRecord timestamp is the timestamp when the record
+ // was written
          long messageReceivedDate = msg.getMessageReceivedDate();
          long hrTimestamp = hr.getTimeInMillis();
          if (messageReceivedDate != 0)
@@ -614,8 +674,10 @@
          long timestamp;

          // if there is value for date of receiving the message
- // this is the event timestamp (this is the date that had came from protocol)
- // the HistoryRecord timestamp is the timestamp when the record was written
+ // this is the event timestamp (this is the date that had came
+ // from protocol)
+ // the HistoryRecord timestamp is the timestamp when the record
+ // was written
          long messageReceivedDate = msg.getMessageReceivedDate();
          long hrTimestamp = hr.getTimeInMillis();
          if(messageReceivedDate != 0)
@@ -892,6 +954,32 @@
              logger.error("Could not add message to history", e);
          }
      }
+
+ /**
+ * Writes a message to the history.
+ * @param history The history to which will write the message
+ * @param message Message
+ * @param messageTimestamp Date this is the timestamp when was message received
+ * that came from the protocol provider
+ */
+ private void writeMessage(History history, String direction,
+ Contact from,
+ Message message, long messageTimestamp)
+ {
+ try
+ {
+ HistoryWriter historyWriter = history.getWriter();
+ historyWriter.addRecord(new String[] { direction,
+ message.getContent(), message.getContentType(),
+ message.getEncoding(), message.getMessageUID(),
+ from.getAddress(),
+ String.valueOf(messageTimestamp) },
+ new Date()); // this date is when the history record is written
+ } catch (IOException e)
+ {
+ logger.error("Could not add message to history", e);
+ }
+ }

      // //////////////////////////////////////////////////////////////////////////

@@ -1453,11 +1541,12 @@
       * @return Collection of MessageReceivedEvents or MessageDeliveredEvents
       * @throws RuntimeException
       */
- public Collection<EventObject> findByPeriod(ChatRoom room, Date startDate, Date endDate,
- String[] keywords, boolean caseSensitive)
+ public Collection<EventObject> findByPeriod(ChatRoom room, Date startDate,
+ Date endDate, String[] keywords, boolean caseSensitive)
          throws RuntimeException
      {
- TreeSet<EventObject> result = new TreeSet<EventObject>(new ChatRoomMessageEventComparator<EventObject>());
+ TreeSet<EventObject> result = new TreeSet<EventObject>(
+ new ChatRoomMessageEventComparator<EventObject>());
          try
          {
              // get the readers for this room
@@ -1467,8 +1556,9 @@
              // add the progress listeners
              addHistorySearchProgressListeners(reader, 1);

- Iterator<HistoryRecord> recs = reader.findByPeriod(startDate, endDate, keywords,
- SEARCH_FIELD, caseSensitive);
+ Iterator<HistoryRecord> recs
+ = reader.findByPeriod(startDate, endDate, keywords,
+ SEARCH_FIELD, caseSensitive);
              while (recs.hasNext())
              {
                  result.add(convertHistoryRecordToMessageEvent(recs.next(), room));
@@ -1512,7 +1602,8 @@
              boolean caseSensitive)
          throws RuntimeException
      {
- TreeSet<EventObject> result = new TreeSet<EventObject>(new ChatRoomMessageEventComparator<EventObject>());
+ TreeSet<EventObject> result = new TreeSet<EventObject>(
+ new ChatRoomMessageEventComparator<EventObject>());
          try
          {
              // get the readers for this room
@@ -1526,7 +1617,8 @@
                  findByKeyword(keyword, SEARCH_FIELD, caseSensitive);
              while (recs.hasNext())
              {
- result.add(convertHistoryRecordToMessageEvent(recs.next(), room));
+ result
+ .add(convertHistoryRecordToMessageEvent(recs.next(), room));
              }

              removeHistorySearchProgressListeners(reader);
@@ -1547,7 +1639,8 @@
       * @return Collection of MessageReceivedEvents or MessageDeliveredEvents
       * @throws RuntimeException
       */
- public Collection<EventObject> findByKeywords(ChatRoom room, String[] keywords)
+ public Collection<EventObject> findByKeywords( ChatRoom room,
+ String[] keywords)
          throws RuntimeException
      {
          return findByKeywords(room, keywords, false);
@@ -1563,11 +1656,13 @@
       * @return Collection of MessageReceivedEvents or MessageDeliveredEvents
       * @throws RuntimeException
       */
- public Collection<EventObject> findByKeywords(ChatRoom room, String[] keywords,
- boolean caseSensitive)
+ public Collection<EventObject> findByKeywords( ChatRoom room,
+ String[] keywords,
+ boolean caseSensitive)
          throws RuntimeException
      {
- TreeSet<EventObject> result = new TreeSet<EventObject>(new ChatRoomMessageEventComparator<EventObject>());
+ TreeSet<EventObject> result = new TreeSet<EventObject>(
+ new ChatRoomMessageEventComparator<EventObject>());
          try
          {
              // get the readers for this room
@@ -1581,7 +1676,8 @@
                  findByKeywords(keywords, SEARCH_FIELD, caseSensitive);
              while (recs.hasNext())
              {
- result.add(convertHistoryRecordToMessageEvent(recs.next(), room));
+ result
+ .add(convertHistoryRecordToMessageEvent(recs.next(), room));
              }

              removeHistorySearchProgressListeners(reader);
@@ -1605,7 +1701,8 @@
      public Collection<EventObject> findLast(ChatRoom room, int count)
          throws RuntimeException
      {
- TreeSet<EventObject> result = new TreeSet<EventObject>(new ChatRoomMessageEventComparator<EventObject>());
+ TreeSet<EventObject> result = new TreeSet<EventObject>(
+ new ChatRoomMessageEventComparator<EventObject>());

          try
          {
@@ -1625,7 +1722,8 @@
              logger.error("Could not read history", e);
          }

- LinkedList<EventObject> resultAsList = new LinkedList<EventObject>(result);
+ LinkedList<EventObject> resultAsList
+ = new LinkedList<EventObject>(result);
          int startIndex = resultAsList.size() - count;

          if(startIndex< 0)
@@ -1644,16 +1742,20 @@
       * @return Collection of MessageReceivedEvents or MessageDeliveredEvents
       * @throws RuntimeException
       */
- public Collection<EventObject> findFirstMessagesAfter(ChatRoom room, Date date, int count)
+ public Collection<EventObject> findFirstMessagesAfter( ChatRoom room,
+ Date date,
+ int count)
          throws RuntimeException
      {
- TreeSet<EventObject> result = new TreeSet<EventObject>(new ChatRoomMessageEventComparator<EventObject>());
+ TreeSet<EventObject> result = new TreeSet<EventObject>(
+ new ChatRoomMessageEventComparator<EventObject>());

          try
          {
- HistoryReader reader =
- this.getHistoryForMultiChat(room).getReader();
- Iterator<HistoryRecord> recs = reader.findFirstRecordsAfter(date, count);
+ HistoryReader reader
+ = this.getHistoryForMultiChat(room).getReader();
+ Iterator<HistoryRecord> recs
+ = reader.findFirstRecordsAfter(date, count);
              while (recs.hasNext())
              {
                  result.add(
@@ -1666,7 +1768,8 @@
              logger.error("Could not read history", e);
          }

- LinkedList<EventObject> resultAsList = new LinkedList<EventObject>(result);
+ LinkedList<EventObject> resultAsList
+ = new LinkedList<EventObject>(result);

          int toIndex = count;
          if(toIndex> resultAsList.size())
@@ -1685,16 +1788,20 @@
       * @return Collection of MessageReceivedEvents or MessageDeliveredEvents
       * @throws RuntimeException
       */
- public Collection<EventObject> findLastMessagesBefore(ChatRoom room, Date date, int count)
+ public Collection<EventObject> findLastMessagesBefore( ChatRoom room,
+ Date date,
+ int count)
          throws RuntimeException
      {
- TreeSet<EventObject> result = new TreeSet<EventObject>(new ChatRoomMessageEventComparator<EventObject>());
+ TreeSet<EventObject> result = new TreeSet<EventObject>(
+ new ChatRoomMessageEventComparator<EventObject>());

          try
          {
              HistoryReader reader =
                  this.getHistoryForMultiChat(room).getReader();
- Iterator<HistoryRecord> recs = reader.findLastRecordsBefore(date, count);
+ Iterator<HistoryRecord> recs
+ = reader.findLastRecordsBefore(date, count);
              while (recs.hasNext())
              {
                  result.add(
@@ -1707,7 +1814,8 @@
              logger.error("Could not read history", e);
          }

- LinkedList<EventObject> resultAsList = new LinkedList<EventObject>(result);
+ LinkedList<EventObject> resultAsList
+ = new LinkedList<EventObject>(result);
          int startIndex = resultAsList.size() - count;

          if(startIndex< 0)
@@ -1720,7 +1828,8 @@
      {
          if (resourcesService == null)
          {
- ServiceReference serviceReference = MessageHistoryActivator.bundleContext
+ ServiceReference serviceReference
+ = MessageHistoryActivator.bundleContext
                  .getServiceReference(ResourceManagementService.class.getName());

              if(serviceReference == null)
@@ -1757,7 +1866,8 @@
              this.listener = listener;
          }

- private void setCurrentValues(HistoryReader currentReader, int allRecords)
+ private void setCurrentValues( HistoryReader currentReader,
+ int allRecords)
          {
              this.allRecords = allRecords;
              this.reader = currentReader;
@@ -1790,7 +1900,8 @@

              currentProgress += tmpHistoryProgress - lastHistoryProgress;

- if(evt.getProgress() == HistorySearchProgressListener.PROGRESS_MAXIMUM_VALUE)
+ if(evt.getProgress()
+ == HistorySearchProgressListener.PROGRESS_MAXIMUM_VALUE)
              {
                  lastHistoryProgress = 0;

@@ -1798,7 +1909,8 @@
                  // there will be looses in currentProgress due to the devision
                  if((int)accumulatedRatio == raiser)
                      currentProgress = raiser *
- MessageHistorySearchProgressListener.PROGRESS_MAXIMUM_VALUE;
+ MessageHistorySearchProgressListener
+ .PROGRESS_MAXIMUM_VALUE;
              }
              else
                  lastHistoryProgress = tmpHistoryProgress;
@@ -2060,4 +2172,63 @@
              }
          }
      }
+
+ public void messageDelivered(AdHocChatRoomMessageDeliveredEvent evt)
+ {
+ try
+ {
+ History history = this.
+ getHistoryForAdHocMultiChat(
+ evt.getSourceAdHocChatRoom());
+
+ writeMessage(history, "out", evt.getMessage(), evt.getTimestamp());
+ }
+ catch (IOException e)
+ {
+ logger.error("Could not add message to history", e);
+ }
+ }
+
+ public void messageDeliveryFailed(
+ AdHocChatRoomMessageDeliveryFailedEvent evt)
+ {
+ // TODO Auto-generated method stub
+ }
+
+ public void messageReceived(AdHocChatRoomMessageReceivedEvent evt)
+ {
+ try
+ {
+ History history = this.getHistoryForAdHocMultiChat(
+ evt.getSourceChatRoom());
+
+ writeMessage(history, "in", evt.getSourceChatRoomParticipant(),
+ evt.getMessage(), evt.getTimestamp());
+ } catch (IOException e)
+ {
+ logger.error("Could not add message to history", e);
+ }
+ }
+
+ /**
+ * Called to notify interested parties that a change in our presence in
+ * an ad-hoc chat room has occurred. Changes may include us being join,
+ * left.
+ * @param evt the<tt>LocalUserAdHocChatRoomPresenceChangeEvent</tt>
+ * instance containing the ad-hoc chat room and the type, and reason of the
+ * change
+ */
+ public void localUserAdHocPresenceChanged(
+ LocalUserAdHocChatRoomPresenceChangeEvent evt)
+ {
+ if(evt.getEventType()
+ == LocalUserAdHocChatRoomPresenceChangeEvent.LOCAL_USER_JOINED)
+ {
+ evt.getAdHocChatRoom().addMessageListener(this);
+ }
+ else
+ {
+ evt.getAdHocChatRoom().removeMessageListener(this);
+ }
+ }
  }

Modified: trunk/src/net/java/sip/communicator/impl/protocol/facebook/FacebookUser.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/facebook/FacebookUser.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/protocol/facebook/FacebookUser.java&p2=trunk/src/net/java/sip/communicator/impl/protocol/facebook/FacebookUser.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/protocol/facebook/FacebookUser.java (original)
+++ trunk/src/net/java/sip/communicator/impl/protocol/facebook/FacebookUser.java 2009-09-14 15:51:47+0000
@@ -16,48 +16,48 @@
   */
  public class FacebookUser
  {
- /*{"listChanged":true,
- "availableCount":2,
-
- "nowAvailableList":
- {"1355527894":{"i":false},
- "1386786477":{"i":false}},
-
- "wasAvailableIDs":[],
-
- "userInfos":{
- "1355527894":
- {"name":"Dai Zhiwei",
- "firstName":"Dai",
- "thumbSrc":"http:\/\/profile.ak.facebook.com\/v225\/1132\/119\/q1355527894_6497.jpg",
- "status":null,
- "statusTime":0,
- "statusTimeRel":""},
- "1386786477":
- {"name":"\u5341\u4e00",
- "firstName":"\u4e00",
- "thumbSrc":"http:\/\/static.ak.fbcdn.net\/pics\/q_silhouette.gif",
- "status":null,
- "statusTime":0,
- "statusTimeRel":""},
- "1190346972":
- {"name":"David Willer",
- "firstName":"David",
- "thumbSrc":"http:\/\/profile.ak.facebook.com\/profile5\/54\/96\/q1190346972_3586.jpg",
- "status":null,
- "statusTime":0,
- "statusTimeRel":""}},
-
- "forcedRender":true,
- "flMode":false,
- "flData":{}}*/
+ /*{"listChanged":true,
+ "availableCount":2,
+
+ "nowAvailableList":
+ {"1355527894":{"i":false},
+ "1386786477":{"i":false}},
+
+ "wasAvailableIDs":[],
+
+ "userInfos":{
+ "1355527894":
+ {"name":"Dai Zhiwei",
+ "firstName":"Dai",
+ "thumbSrc":"http:\/\/profile.ak.facebook.com\/v225\/1132\/119\/q1355527894_6497.jpg",
+ "status":null,
+ "statusTime":0,
+ "statusTimeRel":""},
+ "1386786477":
+ {"name":"\u5341\u4e00",
+ "firstName":"\u4e00",
+ "thumbSrc":"http:\/\/static.ak.fbcdn.net\/pics\/q_silhouette.gif",
+ "status":null,
+ "statusTime":0,
+ "statusTimeRel":""},
+ "1190346972":
+ {"name":"David Willer",
+ "firstName":"David",
+ "thumbSrc":"http:\/\/profile.ak.facebook.com\/profile5\/54\/96\/q1190346972_3586.jpg",
+ "status":null,
+ "statusTime":0,
+ "statusTimeRel":""}},
+
+ "forcedRender":true,
+ "flMode":false,
+ "flData":{}}*/
      public static String defaultThumbSrc = "http://static.ak.fbcdn.net/pics/q_silhouette.gif";

      public static String defaultAvatarSrc = "http://static.ak.fbcdn.net/pics/d_silhouette.gif";

- public String uid;
-
- public boolean isIdle;
+ public String uid;
+
+ public boolean isIdle;

      public String name;

@@ -91,9 +91,9 @@
          thumbSrc = (String) user.get("thumbSrc");
          Object temp = user.get("status");
          if(!temp.equals(org.json.JSONObject.NULL))
- status = (String)temp;
- else
- status = "";
+ status = (String)temp;
+ else
+ status = "";
          statusTime = (Number) user.get("statusTime");
          statusTimeRel = (String) user.get("statusTimeRel");

Added: trunk/src/net/java/sip/communicator/impl/protocol/icq/AdHocChatRoomIcqImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/icq/AdHocChatRoomIcqImpl.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/protocol/icq/AdHocChatRoomIcqImpl.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,735 @@
+/*
+ * 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.icq;
+
+import java.util.*;
+import java.util.Map.*;
+
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.event.*;
+import net.java.sip.communicator.util.*;
+import net.kano.joustsim.*;
+import net.kano.joustsim.oscar.oscar.service.chatrooms.*;
+
+/**
+ * Represents an ad-hoc chat room, where multiple chat users could communicate
+ * in a many-to-many fashion.
+ *
+ * @author Valentin Martinet
+ */
+public class AdHocChatRoomIcqImpl implements AdHocChatRoom
+{
+ private static final Logger logger = Logger
+ .getLogger(AdHocChatRoomIcqImpl.class);
+
+ /**
+ * Listeners that will be notified of changes in member status in the
+ * room such as member joined, left or being kicked or dropped.
+ */
+ private Vector<AdHocChatRoomParticipantPresenceListener> memberListeners
+ = new Vector<AdHocChatRoomParticipantPresenceListener>();
+
+ /**
+ * Listeners that will be notified every time
+ * a new message is received on this chat room.
+ */
+ private Vector<AdHocChatRoomMessageListener> messageListeners
+ = new Vector<AdHocChatRoomMessageListener>();
+
+ /**
+ * Chat room invitation from the icq provider, needed for joining a
+ * chat room.
+ */
+ private ChatInvitation chatInvitation = null;
+
+ /**
+ * Chat room session from the icq provider, we get this after joining a
+ * chat room.
+ * Provides most of the function we need for multi user chatting.
+ */
+ private ChatRoomSession chatRoomSession = null;
+
+ /**
+ * The list of participants of this ad-hoc chat room.
+ */
+ private Hashtable<String, Contact> participants
+ = new Hashtable<String, Contact>();
+
+ /**
+ * The operation set that created us.
+ */
+ private OperationSetAdHocMultiUserChatIcqImpl opSetMuc = null;
+
+ /**
+ * The protocol provider that created us
+ */
+ private ProtocolProviderServiceIcqImpl provider = null;
+
+ /**
+ * List with invitations.
+ */
+ private Hashtable<String, String> inviteUserList
+ = new Hashtable<String, String>();
+
+ /**
+ * HTML mime type
+ */
+ private static final String HTML_MIME_TYPE = "text/html";
+
+ private final String defaultHtmlStartTag = "<HTML>";
+
+ private final String defaultHtmlEndTag = "</HTML>";
+
+ /**
+ * Chat room name.
+ */
+
+ private String chatRoomName = "";
+
+ /**
+ * The nick name of the user.
+ */
+ private String nickName = "";
+
+ /**
+ * Chat room subject. Note: ICQ does not support chat room subjects.
+ */
+ private String chatSubject = "";
+
+ /**
+ * Constructor for chat room instances, with a given chat room invitation.
+ * If this constructor is used the user was invited to a chat room.
+ * @param chatInvitation Chat room invitation that the user received from
+ * the ICQ network
+ * @param icqProvider The ICQ provider
+ */
+ public AdHocChatRoomIcqImpl(ChatInvitation chatInvitation,
+ ProtocolProviderServiceIcqImpl icqProvider)
+ {
+
+ chatRoomName = chatInvitation.getRoomName();
+ this.chatInvitation = chatInvitation;
+ this.provider = icqProvider;
+
+ this.opSetMuc = (OperationSetAdHocMultiUserChatIcqImpl) provider
+ .getOperationSet(OperationSetAdHocMultiUserChat.class);
+ }
+
+ /**
+ * Constructor for chat room instances.
+ * @param roomName The name of the chat room.
+ * @param chatRoomSession Chat room session from the icq network
+ * @param icqProvider The icq provider
+ */
+
+ public AdHocChatRoomIcqImpl(String roomName, ChatRoomSession chatRoomSession,
+ ProtocolProviderServiceIcqImpl icqProvider)
+ {
+ this.chatRoomSession = chatRoomSession;
+ chatRoomName = roomName;
+ this.provider = icqProvider;
+
+ this.opSetMuc = (OperationSetAdHocMultiUserChatIcqImpl) provider
+ .getOperationSet(OperationSetAdHocMultiUserChat.class);
+
+ this.chatRoomSession.addListener(
+ new AdHocChatRoomSessionListenerImpl(this));
+
+ }
+
+ /**
+ * Adds a listener that will be notified of changes in our status in the
+ * room such as us being kicked, banned, or granted admin permissions.
+ *
+ * @param listener a participant status listener.
+ */
+ public void addParticipantPresenceListener(
+ AdHocChatRoomParticipantPresenceListener listener)
+ {
+ synchronized (memberListeners)
+ {
+ if (!memberListeners.contains(listener))
+ memberListeners.add(listener);
+ }
+ }
+
+ /**
+ * Registers<tt>listener</tt> so that it would receive events every time
+ * a new message is received on this chat room.
+ *
+ * @param listener a<tt>MessageListener</tt> that would be notified
+ * every time a new message is received on this chat room.
+ */
+ public void addMessageListener(AdHocChatRoomMessageListener listener)
+ {
+ synchronized (messageListeners)
+ {
+ if (!messageListeners.contains(listener))
+ messageListeners.add(listener);
+ }
+ }
+
+ /**
+ * Create a Message instance for sending arbitrary MIME-encoding content.
+ *
+ * @param content content value
+ * @param contentType the MIME-type for<tt>content</tt>
+ * @param contentEncoding encoding used for<tt>content</tt>
+ * @param subject a<tt>String</tt> subject or<tt>null</tt> for now
+ * subject.
+ * @return the newly created message.
+ */
+ public Message createMessage(byte[] content, String contentType,
+ String contentEncoding, String subject)
+ {
+ return new MessageIcqImpl(new String(content), contentType,
+ contentEncoding, subject);
+ }
+
+ /**
+ * Create a Message instance for sending a simple text messages with
+ * default (text/plain) content type and encoding.
+ *
+ * @param messageText the string content of the message.
+ * @return Message the newly created message
+ */
+ public Message createMessage(String messageText)
+ {
+ Message msg = new MessageIcqImpl(messageText,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_ENCODING, null);
+
+ return msg;
+ }
+
+ /**
+ * Returns the identifier of this<tt>AdHocChatRoom</tt>.
+ *
+ * @return a<tt>String</tt> containing the identifier of this
+ *<tt>AdHocChatRoom</tt>.
+ */
+ public String getIdentifier()
+ {
+ return chatRoomName;
+ }
+
+ /**
+ * Returns a<tt>List</tt> of<tt>Contact</tt>s corresponding
+ * to all participants currently participating in this room.
+ *
+ * @return a<tt>List</tt> of<tt>Contact</tt> corresponding to all room
+ * participants.
+ */
+ public List<Contact> getParticipants()
+ {
+ return new LinkedList<Contact>(participants.values());
+ }
+
+ /**
+ * Returns the number of participants that are currently in this chat room.
+ *
+ * @return the number of<tt>Contact</tt>s, currently participating in
+ * this room.
+ */
+ public int getParticipantsCount()
+ {
+ return participants.size();
+ }
+
+ /**
+ * Returns the name of this<tt>AdHocChatRoom</tt>.
+ *
+ * @return a<tt>String</tt> containing the name of this<tt>ChatRoom</tt>.
+ */
+ public String getName()
+ {
+ return chatRoomName;
+ }
+
+ /**
+ * Returns the protocol provider service that created us.
+ *
+ * @return the protocol provider service that created us.
+ */
+ public ProtocolProviderService getParentProvider()
+ {
+ return provider;
+ }
+
+ /**
+ * Returns the last known room subject/theme or<tt>null</tt> if the user
+ * hasn't joined the room or the room does not have a subject yet.<p> To be
+ * notified every time the room's subject change you should add a
+ *<tt>ChatRoomPropertyChangelistener</tt> to this room.<p>
+ *
+ * To change the room's subject use {@link #setSubject(String)}. Note: Not
+ * possible inside the msn protocol!
+ *
+ * @return the room subject or<tt>null</tt> if the user hasn't joined the
+ * room or the room does not have a subject yet.
+ */
+ public String getSubject()
+ {
+ return chatSubject;
+ }
+
+ /**
+ * Returns the local user's nickname in the context of this chat room or
+ *<tt>null</tt> if not currently joined.
+ *
+ * @return the nickname currently being used by the local user in the
+ * context of the local chat room.
+ */
+ public String getUserNickname()
+ {
+ if (nickName == null)
+ nickName = provider.getInfoRetreiver().getNickName(
+ provider.getAccountID().getUserID());
+
+ return nickName;
+ }
+
+ /**
+ * Invites another user to this room. If we're not joined nothing will
+ * happen.
+ *
+ * @param userAddress the address of the user (email address) to invite to
+ * the room.(one may also invite users not on their contact list).
+ * @param reason You cannot specify a Reason inside the msn protocol
+ */
+ public void invite(String userAddress, String reason)
+ {
+ assertConnected();
+
+ if (logger.isInfoEnabled())
+ logger.info("Inviting " + userAddress + " for reason: " + reason);
+
+ if (chatRoomSession.getState().equals(ChatSessionState.INROOM))
+ chatRoomSession.invite(new Screenname(userAddress), reason);
+ else
+ inviteUserList.put(userAddress, reason);
+ }
+
+ /**
+ * Joins this chat room with the nickname of the local user so that the
+ * user would start receiving events and messages for it.
+ *
+ * @throws OperationFailedException with the corresponding code if an
+ * error occurs while joining the room.
+ */
+ public void join() throws OperationFailedException
+ {
+ if (chatRoomSession == null&& chatInvitation == null)
+ { // the session is not set and we don't have a chatInvitatoin
+ // so we try to join the chatRoom again
+ ChatRoomManager chatRoomManager = provider.getAimConnection()
+ .getChatRoomManager();
+ chatRoomSession = chatRoomManager.joinRoom(this.getName());
+ chatRoomSession.addListener(
+ new AdHocChatRoomSessionListenerImpl(this));
+ }
+ else if (chatInvitation != null)
+ {
+ chatRoomSession = chatInvitation.accept();
+ chatRoomSession.addListener(
+ new AdHocChatRoomSessionListenerImpl(this));
+ }
+
+ // We don't specify a reason.
+ opSetMuc.fireLocalUserPresenceEvent(this,
+ LocalUserAdHocChatRoomPresenceChangeEvent.LOCAL_USER_JOINED, null);
+ }
+
+ /**
+ * Leave this chat room. Once this method is called, the user won't be
+ * listed as a member of the chat room any more and no further chat events
+ * will be delivered. Depending on the underlying protocol and
+ * implementation leave() might cause the room to be destroyed if it has
+ * been created by the local user.
+ */
+ public void leave()
+ {
+ if (chatRoomSession != null)
+ { // manually close the chat room session
+ // and set the chat room session to null.
+ chatRoomSession.close();
+ chatRoomSession = null;
+ }
+
+ Iterator<Entry<String, Contact>> membersSet
+ = participants.entrySet().iterator();
+
+ while (membersSet.hasNext())
+ {
+ Map.Entry<String, Contact> memberEntry = membersSet.next();
+
+ Contact participant = (Contact) memberEntry.getValue();
+
+ fireParticipantPresenceEvent(participant,
+ AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_LEFT,
+ "Local user has left the chat room.");
+ }
+
+ // Delete the list of members
+ participants.clear();
+ }
+
+ /**
+ * Removes a listener that was being notified of changes in the status of
+ * other ad-hoc chat room participants.
+ *
+ * @param listener a participant status listener.
+ */
+ public void removeParticipantPresenceListener(
+ AdHocChatRoomParticipantPresenceListener listener)
+ {
+ synchronized (memberListeners)
+ {
+ memberListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Removes<tt>listener</tt> so that it won't receive any further message
+ * events from this room.
+ *
+ * @param listener the<tt>MessageListener</tt> to remove from this room
+ */
+ public void removeMessageListener(AdHocChatRoomMessageListener listener)
+ {
+ synchronized (messageListeners)
+ {
+ messageListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Sends the<tt>message</tt> to the destination indicated by the
+ *<tt>to</tt> contact.
+ *
+ * @param message The<tt>Message</tt> to send.
+ * @throws OperationFailedException if the underlying stack is not
+ * registered or initialized or if the chat room is not joined.
+ */
+ public void sendMessage(Message message) throws OperationFailedException
+ {
+ assertConnected();
+ try
+ {
+ chatRoomSession.sendMessage(message.getContent());
+
+ //we don't need to fire a message delivered event, because
+ // we will receive this message again.
+ AdHocChatRoomMessageDeliveredEvent msgDeliveredEvt
+ = new AdHocChatRoomMessageDeliveredEvent(
+ this,
+ System.currentTimeMillis(),
+ message,
+ AdHocChatRoomMessageDeliveredEvent
+ .CONVERSATION_MESSAGE_DELIVERED);
+
+ fireMessageEvent(msgDeliveredEvt);
+ }
+ catch (Exception e)
+ {
+ logger.debug("Failed to send a conference message.");
+ throw new OperationFailedException(
+ "Failed to send a conference message.",
+ OperationFailedException.GENERAL_ERROR);
+ }
+ }
+
+ /**
+ * Notifies all interested listeners that a
+ *<tt>ChatRoomMessageDeliveredEvent</tt>,
+ *<tt>ChatRoomMessageReceivedEvent</tt> or a
+ *<tt>ChatRoomMessageDeliveryFailedEvent</tt> has been fired.
+ * @param evt The specific event
+ */
+ public void fireMessageEvent(EventObject evt)
+ {
+ Iterator<AdHocChatRoomMessageListener> listeners = null;
+ synchronized (messageListeners)
+ {
+ listeners = new ArrayList<AdHocChatRoomMessageListener>
+ (messageListeners).iterator();
+ }
+
+ while (listeners.hasNext())
+ {
+ AdHocChatRoomMessageListener listener
+ = listeners.next();
+
+ if (evt instanceof AdHocChatRoomMessageDeliveredEvent)
+ {
+ listener.messageDelivered(
+ (AdHocChatRoomMessageDeliveredEvent) evt);
+ }
+ else if (evt instanceof AdHocChatRoomMessageReceivedEvent)
+ {
+ listener.messageReceived(
+ (AdHocChatRoomMessageReceivedEvent) evt);
+ }
+ else if (evt instanceof AdHocChatRoomMessageDeliveryFailedEvent)
+ {
+ listener.messageDeliveryFailed(
+ (AdHocChatRoomMessageDeliveryFailedEvent) evt);
+ }
+ }
+ }
+
+ /**
+ * Creates the corresponding AdHocChatRoomParticipantPresenceChangeEvent and
+ * notifies all<tt>AdHocChatRoomParticipantPresenceListener</tt>s
+ * that a Contact has joined or left this<tt>AdHocChatRoom</tt>.
+ *
+ * @param member the<tt>Contact</tt> that this
+ * @param eventID the identifier of the event
+ * @param eventReason the reason of the event
+ */
+ private void fireParticipantPresenceEvent(Contact member, String eventID,
+ String eventReason)
+ {
+ AdHocChatRoomParticipantPresenceChangeEvent evt
+ = new AdHocChatRoomParticipantPresenceChangeEvent(this,
+ member,
+ eventID,
+ eventReason);
+
+ logger.trace("Will dispatch the following ChatRoom event: " + evt);
+
+ Iterator<AdHocChatRoomParticipantPresenceListener> listeners = null;
+ synchronized (memberListeners)
+ {
+ listeners = new ArrayList<AdHocChatRoomParticipantPresenceListener>
+ (memberListeners).iterator();
+ }
+
+ while (listeners.hasNext())
+ {
+ AdHocChatRoomParticipantPresenceListener listener
+ = listeners.next();
+
+ listener.participantPresenceChanged(evt);
+ }
+ }
+
+ /**
+ * Our listener for all events for this chat room, e.g. incoming messages or
+ * users that leave or join the chat room.
+ *
+ */
+
+ private class AdHocChatRoomSessionListenerImpl implements
+ ChatRoomSessionListener
+ {
+ /**
+ * The chat room this listener is for.
+ */
+ private AdHocChatRoomIcqImpl chatRoom = null;
+
+ /**
+ * Constructor for this listener, needed to set the chatRoom.
+ * @param room The containing chat room.
+ */
+ public AdHocChatRoomSessionListenerImpl(AdHocChatRoomIcqImpl room)
+ {
+ chatRoom = room;
+ }
+
+ /**
+ * Handles incoming messages for the specified chat room.
+ * @param chatRoomSession Specific chat room session
+ * @param chatRoomUser The User who sends the message
+ * @param chatMessage The message
+ */
+
+ public void handleIncomingMessage(ChatRoomSession chatRoomSession,
+ ChatRoomUser chatRoomUser, ChatMessage chatMessage)
+ {
+ logger.debug("Incoming multi user chat message received: "
+ + chatMessage.getMessage());
+
+ String msgBody = chatMessage.getMessage();
+
+ String msgContent;
+ if (msgBody.startsWith(defaultHtmlStartTag))
+ {
+ msgContent = msgBody.substring(
+ msgBody.indexOf(defaultHtmlStartTag)
+ + defaultHtmlStartTag.length(),
+ msgBody.indexOf(defaultHtmlEndTag));
+ }
+ else
+ msgContent = msgBody;
+
+ Message newMessage = createMessage(
+ msgContent.getBytes(),
+ HTML_MIME_TYPE,
+ OperationSetBasicInstantMessagingIcqImpl
+ .DEFAULT_MIME_ENCODING,
+ null);
+
+ String participantUID = chatRoomUser.getScreenname().getFormatted();
+
+ if(participantUID.equals(nickName))
+ return;
+
+ AdHocChatRoomMessageReceivedEvent msgReceivedEvent
+ = new AdHocChatRoomMessageReceivedEvent(
+ chatRoom,
+ participants.get(participantUID),
+ System.currentTimeMillis(),
+ newMessage,
+ AdHocChatRoomMessageReceivedEvent
+ .CONVERSATION_MESSAGE_RECEIVED);
+
+ fireMessageEvent(msgReceivedEvent);
+ }
+
+ public void handleStateChange(ChatRoomSession chatRoomSession,
+ ChatSessionState oldChatSessionState,
+ ChatSessionState newChatSessionState)
+ {
+ logger.debug("ChatRoomSessionState changed to: "
+ + newChatSessionState);
+
+ if (chatInvitation == null
+&& newChatSessionState.equals(ChatSessionState.INROOM))
+ {
+ try
+ {
+ chatRoom.join();
+ }
+ catch (Exception e)
+ {
+ logger.debug("Failed to join the chat room: " + e);
+ }
+ }
+
+ if(inviteUserList != null
+&& newChatSessionState.equals(ChatSessionState.INROOM) )
+ {
+ Iterator<Map.Entry<String, String>> invitesIter
+ = inviteUserList.entrySet().iterator();
+
+ while (invitesIter.hasNext())
+ {
+ Map.Entry<String, String> entry = invitesIter.next();
+
+ chatRoom.invite(entry.getKey(),
+ entry.getValue());
+ }
+ }
+
+ if (newChatSessionState.equals(ChatSessionState.CLOSED)
+ || newChatSessionState.equals(ChatSessionState.FAILED))
+ {
+ // the chatRoom is closed or we failed to join, so we remove all
+ // chat room user from the chat room member list
+ updateMemberList(chatRoomSession.getUsers(), true);
+ }
+ }
+
+ public void handleUsersJoined(ChatRoomSession chatRoomSession,
+ Set<ChatRoomUser> chatRoomUserSet)
+ {
+ // add the new members to the member list
+ updateMemberList(chatRoomUserSet, false);
+ }
+
+ public void handleUsersLeft(ChatRoomSession chatRoomSession,
+ Set<ChatRoomUser> chatRoomUserSet)
+ {
+ // remove the given members from the member list
+ updateMemberList(chatRoomUserSet, true);
+ }
+ }
+
+ /**
+ * Updates the member list, if the given boolean is true given members will
+ * be added, if it is false the given members will be removed.
+ *
+ * @param chatRoomUserSet New members or members to remove
+ * @param removeMember True if members should be removed, False if members
+ * should be added.
+ */
+ private void updateMemberList( Set<ChatRoomUser> chatRoomUserSet,
+ boolean removeMember)
+ {
+ Iterator<ChatRoomUser> it = chatRoomUserSet.iterator();
+
+ while (it.hasNext())
+ {
+ ChatRoomUser user = it.next();
+ String uid = user.getScreenname().getFormatted();
+
+ //we want to add a member and he/she is not in our member list
+ if (!removeMember
+&& !participants.containsKey(uid)
+&& !uid.equals(provider.getAccountID().getUserID()))
+ {
+ OperationSetPersistentPresenceIcqImpl presenceOpSet
+ = (OperationSetPersistentPresenceIcqImpl) getParentProvider()
+ .getOperationSet(OperationSetPersistentPresence.class);
+
+ Contact participant= presenceOpSet.getServerStoredContactList()
+ .findContactByScreenName(uid);
+
+ participants.put(uid, participant);
+
+ fireParticipantPresenceEvent(
+ participant,
+ AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_JOINED,
+ null);
+ }
+ //we want to remove a member and found him/her in our member list
+ if (removeMember&& participants.containsKey(uid))
+ {
+ Contact participant = participants
+ .get(uid);
+
+ participants.remove(uid);
+
+ fireParticipantPresenceEvent(
+ participant,
+ AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_LEFT,
+ null);
+ }
+ }
+ }
+
+ /**
+ * Utility method throwing an exception if the stack is not properly
+ * initialized.
+ * @throws java.lang.IllegalStateException if the underlying stack is
+ * not registered and initialized.
+ */
+ private void assertConnected() throws IllegalStateException
+ {
+ if (provider == null)
+ throw new IllegalStateException(
+ "The provider must be non-null and signed on the "
+ + "service before being able to communicate.");
+ if (!provider.isRegistered())
+ throw new IllegalStateException(
+ "The provider must be signed on the service before "
+ + "being able to communicate.");
+ }
+
+ /**
+ * Finds the member of this chat room corresponding to the given nick name.
+ *
+ * @param nickName the nick name to search for.
+ * @return the member of this chat room corresponding to the given nick name.
+ */
+ public Contact findParticipantForNickName(String nickName)
+ {
+ return participants.get(nickName);
+ }
+}

Added: trunk/src/net/java/sip/communicator/impl/protocol/icq/AdHocChatRoomInvitationIcqImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/icq/AdHocChatRoomInvitationIcqImpl.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/protocol/icq/AdHocChatRoomInvitationIcqImpl.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,96 @@
+/*
+ * 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.icq;
+
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * The ICQ implementation of the<tt>ChatRoomInvitation</tt> interface for
+ * ad-hoc chat rooms.
+ *
+ * @author Valentin Martinet
+ */
+public class AdHocChatRoomInvitationIcqImpl
+ implements AdHocChatRoomInvitation
+{
+ /**
+ * Corresponding ad-hoc chat room instance.
+ */
+ private AdHocChatRoom chatRoom;
+
+ /**
+ * The name of the inviter
+ */
+ private String inviter;
+
+ /**
+ * The invitation reason.
+ */
+ private String reason;
+
+ /**
+ * The password.
+ */
+ private byte[] password;
+
+ /**
+ * Creates an instance of the<tt>AdHocChatRoomInvitationIcqImpl</tt> by
+ * specifying the targetChatRoom, the inviter, the reason and the password.
+ *
+ * @param targetChatRoom The<tt>AdHocChatRoom</tt> for which the invitation
+ * is
+ * @param inviter The<tt>Contact</tt>, which sent the invitation
+ * @param reason The Reason for the invitation
+ * @param password The password
+ */
+ public AdHocChatRoomInvitationIcqImpl(AdHocChatRoom targetChatRoom,
+ String inviter,
+ String reason,
+ byte[] password)
+ {
+ this.chatRoom = targetChatRoom;
+ this.inviter = inviter;
+ this.reason = reason;
+ this.password = password;
+ }
+
+ /**
+ * Returns the corresponding ad-hoc chat room.
+ * @return The ad-hoc chat room
+ */
+ public AdHocChatRoom getTargetAdHocChatRoom()
+ {
+ return chatRoom;
+ }
+
+ /**
+ * Returns the corresponding inviter.
+ * @return The name of the inviter
+ */
+ public String getInviter()
+ {
+ return inviter;
+ }
+
+ /**
+ * Returns the invitation reason.
+ * @return the invitation reason
+ */
+ public String getReason()
+ {
+ return reason;
+ }
+
+ /**
+ * Returns the password of the chat room.
+ * @return The password
+ */
+ public byte[] getAdHocChatRoomPassword()
+ {
+ return password;
+ }
+}

Removed: trunk/src/net/java/sip/communicator/impl/protocol/icq/ChatRoomIcqImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/icq/ChatRoomIcqImpl.java?view=auto&rev=5963

Removed: trunk/src/net/java/sip/communicator/impl/protocol/icq/ChatRoomInvitationIcqImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/icq/ChatRoomInvitationIcqImpl.java?view=auto&rev=5963

Removed: trunk/src/net/java/sip/communicator/impl/protocol/icq/ChatRoomMemberIcqImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/icq/ChatRoomMemberIcqImpl.java?view=auto&rev=5963

Added: trunk/src/net/java/sip/communicator/impl/protocol/icq/OperationSetAdHocMultiUserChatIcqImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/icq/OperationSetAdHocMultiUserChatIcqImpl.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/protocol/icq/OperationSetAdHocMultiUserChatIcqImpl.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,513 @@
+/*
+ * 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.icq;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.event.*;
+import net.java.sip.communicator.util.Logger;
+import net.kano.joscar.*;
+import net.kano.joustsim.oscar.oscar.service.chatrooms.*;
+
+/**
+ * A ICQ implementation of the ad-hoc multi user chat operation set.
+ *
+ * @author Valentin Martinet
+ */
+public class OperationSetAdHocMultiUserChatIcqImpl
+ implements OperationSetAdHocMultiUserChat
+{
+ private static final Logger logger = Logger
+ .getLogger(OperationSetAdHocMultiUserChatIcqImpl.class);
+
+ /**
+ * The currently valid ICQ protocol provider service implementation.
+ */
+ private ProtocolProviderServiceIcqImpl icqProvider = null;
+
+ /**
+ * A list of listeners subscribed for invitations multi user chat events.
+ */
+ private Vector<AdHocChatRoomInvitationListener> invitationListeners
+ = new Vector<AdHocChatRoomInvitationListener>();
+
+ /**
+ * A list of listeners subscribed for events indicating rejection of a
+ * multi user chat invitation sent by us.
+ */
+ private Vector<AdHocChatRoomInvitationRejectionListener>
+ invitationRejectionListeners
+ = new Vector<AdHocChatRoomInvitationRejectionListener>();
+
+ /**
+ * Listeners that will be notified of changes in our status in the
+ * room such as us being kicked, banned, or granted admin permissions.
+ */
+ private Vector<LocalUserAdHocChatRoomPresenceListener> presenceListeners
+ = new Vector<LocalUserAdHocChatRoomPresenceListener>();
+
+ /**
+ * A list of the rooms that are currently open by this account. Note that
+ * we have not necessarily joined these rooms, we might have simply been
+ * searching through them.
+ */
+ private Hashtable<String, AdHocChatRoom> chatRoomCache
+ = new Hashtable<String, AdHocChatRoom>();
+
+ /**
+ * The registration listener that would get notified when the underlying
+ * ICQ provider gets registered.
+ */
+ private RegistrationStateListener providerRegListener
+ = new RegistrationStateListener();
+
+ /**
+ * A reference to the persistent presence operation set that we use
+ * to match incoming messages to<tt>Contact</tt>s and vice versa.
+ */
+ protected OperationSetPersistentPresenceIcqImpl opSetPersPresence = null;
+
+ /**
+ * Hash table that contains all invitations, this is needed if the user wants
+ * to reject an invitation.
+ */
+ private Hashtable<AdHocChatRoom, ChatInvitation> invitations
+ = new Hashtable<AdHocChatRoom, ChatInvitation>();
+
+ /**
+ * Instantiates the user operation set with a currently valid instance of
+ * the Icq protocol provider.
+ * @param icqProvider a currently valid instance of
+ * ProtocolProviderServiceIcqImpl.
+ */
+ OperationSetAdHocMultiUserChatIcqImpl(
+ ProtocolProviderServiceIcqImpl icqProvider)
+ {
+ this.icqProvider = icqProvider;
+ icqProvider.addRegistrationStateChangeListener(providerRegListener);
+ }
+
+ /**
+ * Adds a listener to invitation notifications.
+ *
+ * @param listener an invitation listener.
+ */
+ public void addInvitationListener(AdHocChatRoomInvitationListener listener)
+ {
+ synchronized (invitationListeners)
+ {
+ if (!invitationListeners.contains(listener))
+ invitationListeners.add(listener);
+ }
+ }
+
+ /**
+ * Subscribes<tt>listener</tt> so that it would receive events indicating
+ * rejection of a multi user chat invitation that we've sent earlier.
+ *
+ * @param listener the listener that we'll subscribe for invitation
+ * rejection events.
+ */
+ public void addInvitationRejectionListener(
+ AdHocChatRoomInvitationRejectionListener listener)
+ {
+ synchronized (invitationRejectionListeners)
+ {
+ if (!invitationRejectionListeners.contains(listener))
+ invitationRejectionListeners.add(listener);
+ }
+ }
+
+ /**
+ * Adds a listener that will be notified of changes in our status in a chat
+ * room such as us being kicked, banned or dropped.
+ *
+ * @param listener the<tt>LocalUserAdHocChatRoomPresenceListener</tt>.
+ */
+ public void addPresenceListener(
+ LocalUserAdHocChatRoomPresenceListener listener)
+ {
+ synchronized (presenceListeners)
+ {
+ if (!presenceListeners.contains(listener))
+ presenceListeners.add(listener);
+ }
+ }
+
+ /**
+ * Returns a reference to a chatRoom by an given chat invitation. This method
+ * is called, when the user received a chat invitation. The chat room will be
+ * created and the chatInvitation will be saved in the created chat room. This
+ * ensures to get the chat room session for each chat room.
+ *
+ * @param chatInvitation The Chat invitation the user received
+ * @return A chat room based on the chat invitation
+ * @throws OperationFailedException if an error occurs while trying to
+ * discover the room on the server.
+ * @throws OperationNotSupportedException if the server does not support
+ * multi user chat
+ */
+ public AdHocChatRoom findRoom(ChatInvitation chatInvitation)
+ throws OperationFailedException, OperationNotSupportedException
+ {
+ AdHocChatRoom chatRoom = (AdHocChatRoom) chatRoomCache.get(chatInvitation
+ .getRoomName());
+
+ if (chatRoom == null)
+ {
+ chatRoom = createLocalChatRoomInstance(chatInvitation);
+ }
+
+ return chatRoom;
+ }
+
+ /**
+ * Creates an<tt>AdHocChatRoom</tt> from the specified smack
+ *<tt>MultiUserChat</tt>.
+ *
+ * @param chatInvitation The chat invitation we received from the
+ * chatRoomManager
+ *
+ * @return ChatRoom the chat room that we've just created.
+ */
+
+ private AdHocChatRoom createLocalChatRoomInstance(
+ ChatInvitation chatInvitation)
+ {
+ synchronized (chatRoomCache)
+ {
+ AdHocChatRoom newChatRoom = new AdHocChatRoomIcqImpl(chatInvitation,
+ icqProvider);
+
+ chatRoomCache.put(chatInvitation.getRoomName(), newChatRoom);
+ return newChatRoom;
+ }
+ }
+
+ /**
+ * Creates a room with the named<tt>roomName</tt> and according to the
+ * specified<tt>roomProperties</tt> on the server that this protocol
+ * provider is currently connected to.
+ *
+ * @param roomName the name of the<tt>AdHocChatRoom</tt> to create.
+ * @param roomProperties properties specifying how the room should be
+ * created. Contains list of invitees and the invitation message.
+ *
+ * @throws OperationFailedException if the room couldn't be created for
+ * some reason (e.g. room already exists; user already joined to an
+ * existent room or user has no permissions to create an ad-hoc chat room).
+ * @throws OperationNotSupportedException if ad-hoc chat room creation is not
+ * supported by this server
+ *
+ * @return AdHocChatRoom the ad-hoc chat room that we've just created.
+ */
+ public AdHocChatRoom createAdHocChatRoom( String roomName,
+ Map<String, Object> roomProperties)
+ throws OperationFailedException,
+ OperationNotSupportedException
+ {
+ AdHocChatRoom chatRoom = null;
+
+ ChatRoomManager chatRoomManager = icqProvider.getAimConnection()
+ .getChatRoomManager();
+
+ ChatRoomSession chatRoomSession = chatRoomManager.joinRoom(roomName);
+
+ if(chatRoomSession != null)
+ {
+ chatRoom = new AdHocChatRoomIcqImpl( roomName,
+ chatRoomSession,
+ icqProvider);
+ }
+
+ return chatRoom;
+ }
+
+ /**
+ * Creates an ad-hoc room with the named<tt>adHocRoomName</tt> and in
+ * including to the specified<tt>contacts</tt>. When the method
+ * returns the ad-hoc room the local user will not have joined it and thus
+ * will not receive messages on it until the<tt>AdHocChatRoom.join()</tt>
+ * method is called.
+ *
+ * NOTE: this method was done for the Yahoo! implementation. But since both
+ * Yahoo! and ICQ are implementing the ad-hoc multi-user-chat operation set,
+ * we have to define this method here.
+ *
+ * @param adHocRoomName the name of the ad-hoc room
+ * @param contacts the list of contacts
+ *
+ * @throws OperationFailedException
+ * @throws OperationNotSupportedException
+ */
+ public AdHocChatRoom createAdHocChatRoom(String adHocRoomName,
+ List<Contact> contacts)
+ throws OperationFailedException,
+ OperationNotSupportedException
+ {
+ AdHocChatRoom chatRoom = null;
+
+ ChatRoomManager chatRoomManager = icqProvider.getAimConnection()
+ .getChatRoomManager();
+
+ ChatRoomSession chatRoomSession = chatRoomManager.joinRoom(adHocRoomName);
+
+ if(chatRoomSession != null)
+ {
+ chatRoom = new AdHocChatRoomIcqImpl( adHocRoomName,
+ chatRoomSession,
+ icqProvider);
+ }
+
+ return chatRoom;
+ }
+
+ /**
+ * Returns a reference to a chatRoom named<tt>roomName</tt> or null if
+ * no such room exists.
+ *
+ * @param roomName the name of the<tt>AdHocChatRoom</tt> that we're looking
+ * for.
+ * @return the<tt>AdHocChatRoom</tt> named<tt>roomName</tt> or null if no
+ * such room exists on the server that this provider is currently
+ * connected to.
+ * @throws OperationFailedException if an error occurs while trying to
+ * discover the room on the server.
+ * @throws OperationNotSupportedException if the server does not support
+ * multi user chat
+ */
+
+ public AdHocChatRoom findRoom(String roomName)
+ throws OperationFailedException, OperationNotSupportedException
+ {
+ AdHocChatRoom room = (AdHocChatRoom) chatRoomCache.get(roomName);
+
+ return room;
+ }
+
+ /**
+ * Returns true if<tt>contact</tt> supports multi user chat sessions.
+ *
+ * @param contact reference to the contact whose support for chat rooms
+ * we are currently querying.
+ * @return a boolean indicating whether<tt>contact</tt> supports
+ * chat rooms.
+ */
+ public boolean isMultiChatSupportedByContact(Contact contact)
+ {
+ if (contact.getProtocolProvider().getOperationSet(
+ OperationSetAdHocMultiUserChat.class) != null)
+ return true;
+
+ return false;
+ }
+
+ /**
+ * Informs the sender of an invitation that we decline their invitation.
+ *
+ * @param invitation the connection to use for sending the rejection.
+ * @param rejectReason the reason to reject the given invitation
+ */
+ public void rejectInvitation(AdHocChatRoomInvitation invitation,
+ String rejectReason)
+ {
+ ChatInvitation inv = (ChatInvitation) invitations.get(invitation
+ .getTargetAdHocChatRoom());
+
+ if (inv != null)
+ { //send the rejection
+ inv.reject();
+ }
+ //remove the invitation
+ invitations.remove(invitation.getTargetAdHocChatRoom());
+ }
+
+ /**
+ * Removes<tt>listener</tt> from the list of invitation listeners
+ * registered to receive invitation events.
+ *
+ * @param listener the invitation listener to remove.
+ */
+ public void removeInvitationListener(
+ AdHocChatRoomInvitationListener listener)
+ {
+ synchronized (invitationListeners)
+ {
+ invitationListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Removes<tt>listener</tt> from the list of invitation listeners
+ * registered to receive invitation rejection events.
+ *
+ * @param listener the invitation listener to remove.
+ */
+ public void removeInvitationRejectionListener(
+ AdHocChatRoomInvitationRejectionListener listener)
+ {
+ synchronized (invitationRejectionListeners)
+ {
+ invitationRejectionListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Removes a listener that was being notified of changes in our status in
+ * a room such as us being joined or dropped.
+ *
+ * @param listener the<tt>LocalUserAdHocChatRoomPresenceListener</tt>.
+ */
+ public void removePresenceListener(
+ LocalUserAdHocChatRoomPresenceListener listener)
+ {
+ synchronized (presenceListeners)
+ {
+ presenceListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Delivers a<tt>AdHocChatRoomInvitationReceivedEvent</tt> to all
+ * registered<tt>AdHocChatRoomInvitationListener</tt>s.
+ *
+ * @param targetChatRoom the ad-hoc 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, byte[] password)
+ {
+ AdHocChatRoomInvitationIcqImpl invitation =
+ new AdHocChatRoomInvitationIcqImpl(
+ targetChatRoom, inviter, reason, password);
+
+ AdHocChatRoomInvitationReceivedEvent evt
+ = new AdHocChatRoomInvitationReceivedEvent(
+ this, invitation, new Date(System.currentTimeMillis()));
+
+ Iterator<AdHocChatRoomInvitationListener> listeners = null;
+ synchronized (invitationListeners)
+ {
+ listeners = new ArrayList<AdHocChatRoomInvitationListener>
+ (invitationListeners).iterator();
+ }
+
+ while (listeners.hasNext())
+ {
+ AdHocChatRoomInvitationListener listener
+ = (AdHocChatRoomInvitationListener) listeners.next();
+
+ listener.invitationReceived(evt);
+ }
+ }
+
+ /**
+ * Delivers a<tt>LocalUserAdHocChatRoomPresenceChangeEvent</tt> to all
+ * registered<tt>LocalUserAdHocChatRoomPresenceListener</tt>s.
+ *
+ * @param chatRoom the<tt>AdHocChatRoom</tt> which has been joined, left,
+ * etc.
+ * @param eventType the type of this event; one of LOCAL_USER_JOINED,
+ * LOCAL_USER_LEFT, etc.
+ * @param reason the reason
+ */
+ public void fireLocalUserPresenceEvent( AdHocChatRoom chatRoom,
+ String eventType,
+ String reason)
+ {
+ LocalUserAdHocChatRoomPresenceChangeEvent evt =
+ new LocalUserAdHocChatRoomPresenceChangeEvent(
+ this, chatRoom, eventType, reason);
+
+ Iterator<LocalUserAdHocChatRoomPresenceListener> listeners = null;
+ synchronized (presenceListeners)
+ {
+ listeners = new ArrayList<LocalUserAdHocChatRoomPresenceListener>
+ (presenceListeners).iterator();
+ }
+
+ while (listeners.hasNext())
+ {
+ LocalUserAdHocChatRoomPresenceListener listener
+ = (LocalUserAdHocChatRoomPresenceListener) listeners.next();
+
+ listener.localUserAdHocPresenceChanged(evt);
+ }
+ }
+
+ /**
+ * Our listener that will tell us when we're registered to icq and joust
+ * sim is ready to accept us as a listener.
+ */
+ private class RegistrationStateListener implements
+ RegistrationStateChangeListener
+ {
+ /**
+ * The method is called by a ProtocolProvider implementation whenever
+ * a change in the registration state of the corresponding provider had
+ * occurred.
+ * @param evt ProviderStatusChangeEvent the event describing the status
+ * change.
+ */
+ public void registrationStateChanged(RegistrationStateChangeEvent evt)
+ {
+ logger.debug("The ICQ provider changed state from: "
+ + evt.getOldState() + " to: " + evt.getNewState());
+ if (evt.getNewState() == RegistrationState.REGISTERED)
+ {
+ String customMessageEncoding = null;
+ if ((customMessageEncoding = System
+ .getProperty("icq.custom.message.charset")) != null)
+ OscarTools.setDefaultCharset(customMessageEncoding);
+
+ opSetPersPresence =
+ (OperationSetPersistentPresenceIcqImpl) icqProvider
+ .getOperationSet(OperationSetPersistentPresence.class);
+
+ //add ChatRoomMangagerListener
+ icqProvider.getAimConnection().getChatRoomManager()
+ .addListener(new ChatRoomManagerListenerImpl());
+ }
+ }
+ }
+
+ /**
+ * Our listener for chat room invitations.
+ *
+ */
+ private class ChatRoomManagerListenerImpl
+ implements ChatRoomManagerListener
+ {
+ public void handleInvitation(ChatRoomManager chatRoomManager,
+ ChatInvitation chatInvitation)
+ {
+ logger
+ .debug("Invitation received: "
+ + chatInvitation.getRoomName());
+ try
+ {
+ AdHocChatRoom chatRoom = findRoom(chatInvitation);
+ // save chatInvitation, for a possible rejection
+ invitations.put(chatRoom, chatInvitation);
+
+ fireInvitationEvent(chatRoom, chatInvitation.getScreenname()
+ .toString(), chatInvitation.getMessage(), null);
+ }
+ catch (OperationNotSupportedException onse)
+ {
+ logger.debug("Failed to handle ChatInvitation: " + onse);
+ }
+ catch (OperationFailedException ofe)
+ {
+ logger.debug("Failed to handle ChatInvitation: " + ofe);
+ }
+ }
+ }
+}

Removed: trunk/src/net/java/sip/communicator/impl/protocol/icq/OperationSetMultiUserChatIcqImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/icq/OperationSetMultiUserChatIcqImpl.java?view=auto&rev=5963

Modified: trunk/src/net/java/sip/communicator/impl/protocol/icq/ProtocolProviderServiceIcqImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/icq/ProtocolProviderServiceIcqImpl.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/protocol/icq/ProtocolProviderServiceIcqImpl.java&p2=trunk/src/net/java/sip/communicator/impl/protocol/icq/ProtocolProviderServiceIcqImpl.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/protocol/icq/ProtocolProviderServiceIcqImpl.java (original)
+++ trunk/src/net/java/sip/communicator/impl/protocol/icq/ProtocolProviderServiceIcqImpl.java 2009-09-14 15:51:47+0000
@@ -26,6 +26,7 @@
   *
   * @author Emil Ivov
   * @author Damian Minkov
+ * @author Valentin Martinet
   */
  public class ProtocolProviderServiceIcqImpl
      extends AbstractProtocolProviderService
@@ -455,9 +456,10 @@
              if(IcqAccountID.isAIM(accountID.getAccountProperties()))
                      USING_ICQ = false;

- supportedOperationSets.put(OperationSetInstantMessageTransform.class.getName(),
+ supportedOperationSets.put(
+ OperationSetInstantMessageTransform.class.getName(),
                  new OperationSetInstantMessageTransformImpl());
-
+
              //initialize the presence operationset
              OperationSetPersistentPresence persistentPresence =
                  new OperationSetPersistentPresenceIcqImpl(this, screenname);
@@ -477,13 +479,13 @@
              supportedOperationSets.put(
                  OperationSetBasicInstantMessaging.class.getName(),
                  basicInstantMessaging);
-
- //initialize the multi chat operation set
- OperationSetMultiUserChatIcqImpl multiUserOpSet
- = new OperationSetMultiUserChatIcqImpl(this);
+
+ //initialize the multi chat operation set
+ OperationSetAdHocMultiUserChatIcqImpl multiUserOpSet
+ = new OperationSetAdHocMultiUserChatIcqImpl(this);

              supportedOperationSets.put(
- OperationSetMultiUserChat.class.getName(),
+ OperationSetAdHocMultiUserChat.class.getName(),
                  multiUserOpSet);

              //initialize the typing notifications operation set

Copied: trunk/src/net/java/sip/communicator/impl/protocol/msn/AdHocChatRoomInvitationMsnImpl.java (from r5898, /trunk/src/net/java/sip/communicator/impl/protocol/msn/ChatRoomInvitationMsnImpl.java)
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/msn/AdHocChatRoomInvitationMsnImpl.java?view=diff&rev=5964&p1=/trunk/src/net/java/sip/communicator/impl/protocol/msn/ChatRoomInvitationMsnImpl.java&p2=trunk/src/net/java/sip/communicator/impl/protocol/msn/AdHocChatRoomInvitationMsnImpl.java&r1=5898&r2=5964

--- /trunk/src/net/java/sip/communicator/impl/protocol/msn/ChatRoomInvitationMsnImpl.java (original)
+++ trunk/src/net/java/sip/communicator/impl/protocol/msn/AdHocChatRoomInvitationMsnImpl.java 2009-09-14 15:51:47+0000
@@ -9,54 +9,43 @@
  import net.java.sip.communicator.service.protocol.*;

  /**
- * The MSN implementation of the<tt>ChatRoomInvitation</tt> interface.
+ * The MSN implementation of the<tt>AdHocChatRoomInvitation</tt> interface.
+ *
   * @author Rupert Burchardi
+ * @author Yana Stamcheva
   */
-public class ChatRoomInvitationMsnImpl implements ChatRoomInvitation
+public class AdHocChatRoomInvitationMsnImpl
+ implements AdHocChatRoomInvitation
  {
     /**
      * Corresponding chat room instance.
      */
- private ChatRoom chatRoom;
+ private AdHocChatRoom chatRoom;
     /**
- * The name of the inviter
+ * The name of the inviter.
      */
     private String inviter;
- /**
- * The invitation reason. Note: Not supported in the msn protocol.
- */
- private String reason;
-
- /**
- * The password. Note: Not supported in the msn protocol.
- */
- private byte[] password;

     /**
- * Creates an instance of the<tt>ChatRoomInvitationMsnImpl</tt> by
+ * Creates an instance of the<tt>AdHocChatRoomInvitationMsnImpl</tt> by
      * specifying the targetChatRoom, the inviter, the reason and the password.
      *
- * @param targetChatRoom The<tt>ChatRoom</tt> for which the invitation is
- * @param inviter The<tt>ChatRoomMember</tt>, which sent the invitation
- * @param reason The Reason for the invitation
- * @param password The password
- */
- public ChatRoomInvitationMsnImpl(ChatRoom targetChatRoom,
- String inviter,
- String reason,
- byte[] password)
+ * @param targetChatRoom the<tt>AdHocChatRoom</tt> for which the invitation
+ * is
+ * @param inviter the contact, which sent the invitation
+ */
+ public AdHocChatRoomInvitationMsnImpl(AdHocChatRoom targetChatRoom,
+ String inviter)
     {
         this.chatRoom = targetChatRoom;
         this.inviter = inviter;
- this.reason = reason;
- this.password = password;
     }

     /**
      * Returns the corresponding chat room.
      * @return The chat room
      */
- public ChatRoom getTargetChatRoom()
+ public AdHocChatRoom getTargetAdHocChatRoom()
     {
         return chatRoom;
     }
@@ -76,14 +65,7 @@
      */
     public String getReason()
     {
- return reason;
- }
- /**
- * Returns the password of the chat room.
- * @return The password
- */
- public byte[] getChatRoomPassword()
- {
- return password;
+ //Not supported in the Msn protocol.
+ return null;
     }
  }

Added: trunk/src/net/java/sip/communicator/impl/protocol/msn/AdHocChatRoomMsnImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/msn/AdHocChatRoomMsnImpl.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/protocol/msn/AdHocChatRoomMsnImpl.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,557 @@
+/*
+ * 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.msn;
+
+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 net.sf.jml.*;
+
+/**
+ * Implements ad-hoc chat rooms for MSN.
+ *
+ * @author Rupert Burchardi
+ * @author Valentin Martinet
+ */
+public class AdHocChatRoomMsnImpl
+ implements AdHocChatRoom
+{
+ private static final Logger logger
+ = Logger.getLogger(AdHocChatRoomMsnImpl.class);
+
+ /**
+ * The protocol provider that created us
+ */
+ private final ProtocolProviderServiceMsnImpl provider;
+
+ /**
+ * The OperationSet for MSN multi user chats.
+ */
+ private OperationSetAdHocMultiUserChatMsnImpl opSetAdHocMuc = null;
+
+ /**
+ * The corresponding switchboard for the chat room. Each chat room has its
+ * own switchboard and if it is closed the user cannot reconnect to it, see
+ * MSN documentation for further infos.
+ */
+ private MsnSwitchboard switchboard = null;
+
+ /**
+ * Listeners that will be notified of changes in participants status in the
+ * ad-hoc room, such as participant joined, left, etc.
+ */
+ private Vector<AdHocChatRoomParticipantPresenceListener>
+ participantsPresenceListeners =
+ new Vector<AdHocChatRoomParticipantPresenceListener>();
+
+ /**
+ * Listeners that will be notified every time a new message is received on
+ * this ad-hoc chat room.
+ */
+ private Vector<AdHocChatRoomMessageListener> messageListeners
+ = new Vector<AdHocChatRoomMessageListener>();
+
+ /**
+ * A Message buffer, will keep all messages until the MSN ad-hoc chat room
+ * is ready.
+ */
+ public Vector<EventObject> messageBuffer = new Vector<EventObject>();
+
+ /**
+ * The name of this ad-hoc chat room
+ */
+ private String name;
+
+ /**
+ * The list of participants of this ad-hoc chat room.
+ */
+ private final Hashtable<String, Contact> participants =
+ new Hashtable<String, Contact>();
+
+ /**
+ * List of unresolved member names.
+ */
+ private ArrayList<String> pendingInvitations = new ArrayList<String>();
+
+ /**
+ * Creates a new ad-hoc chat room for MSN named<tt>name</tt>, using the
+ * protocol provider<tt>provider</tt>.
+ *
+ * @param name
+ * @param provider
+ */
+ public AdHocChatRoomMsnImpl(String name,
+ ProtocolProviderServiceMsnImpl provider)
+ {
+ this.name = name;
+ this.provider = provider;
+ this.opSetAdHocMuc =
+ (OperationSetAdHocMultiUserChatMsnImpl)
+ this.provider.getOperationSet(OperationSetAdHocMultiUserChat.class);
+ }
+
+ /**
+ * Creates a new ad-hoc chat room for MSN named<tt>name</tt>, using the
+ * protocol provider<tt>provider</tt> and the msn switchboard
+ *<tt>switchboard</tt>.
+ *
+ * @param name
+ * @param provider
+ * @param switchboard
+ */
+ public AdHocChatRoomMsnImpl(String name,
+ ProtocolProviderServiceMsnImpl provider,
+ MsnSwitchboard switchboard)
+ {
+ this.name = name;
+ this.provider = provider;
+ this.opSetAdHocMuc =
+ (OperationSetAdHocMultiUserChatMsnImpl)
+ this.provider.getOperationSet(OperationSetAdHocMultiUserChat.class);
+ this.switchboard = switchboard;
+ }
+
+ /**
+ * Adds a listener that will be notified of changes in our status in the
+ * room.
+ *
+ * @param listener a participant status listener.
+ */
+ public void addParticipantPresenceListener(
+ AdHocChatRoomParticipantPresenceListener listener)
+ {
+ synchronized(this.participantsPresenceListeners)
+ {
+ if (!this.participantsPresenceListeners.contains(listener))
+ this.participantsPresenceListeners.add(listener);
+ }
+ }
+
+ /**
+ * Registers<tt>listener</tt> so that it would receive events every time a
+ * new message is received on this chat room.
+ *
+ * @param listener a<tt>MessageListener</tt> that would be notified every
+ * time a new message is received on this chat room.
+ */
+ public void addMessageListener(AdHocChatRoomMessageListener listener)
+ {
+ synchronized(this.messageListeners)
+ {
+ if (!this.messageListeners.contains(listener))
+ this.messageListeners.add(listener);
+ }
+ }
+
+ /**
+ * Removes<tt>listener</tt> so that it won't receive any further message
+ * events from this room.
+ *
+ * @param listener the<tt>MessageListener</tt> to remove from this room
+ */
+ public void removeMessageListener(ChatRoomMessageListener listener)
+ {
+ synchronized (messageListeners)
+ {
+ if (messageListeners.contains(listener))
+ messageListeners.remove(messageListeners.indexOf(listener));
+ }
+ }
+
+ /**
+ * Finds the participant of this ad-hoc chat room corresponding to the
+ * given address.
+ *
+ * @param address the address to search for.
+ * @return the participant of this chat room corresponding to the given
+ * nick name.
+ */
+ public Contact findParticipantForAddress(String address)
+ {
+ Iterator<Contact> participantsIter
+ = this.participants.values().iterator();
+
+ while (participantsIter.hasNext())
+ {
+ Contact contact = participantsIter.next();
+
+ if (contact.getAddress().equals(address))
+ {
+ return contact;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Creates a<tt>Message</tt> for this ad-hoc chat room containing
+ *<tt>text</tt>.
+ *
+ * @param text
+ * @return Message the newly created<tt>Message</tt>
+ */
+ public Message createMessage(String text)
+ {
+ Message msg =
+ new MessageMsnImpl(text,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_ENCODING, null);
+
+ return msg;
+ }
+
+ /**
+ * Returns the name of this ad-hoc chatroom
+ *
+ * @return String
+ */
+ public String getName()
+ {
+ return this.name;
+ }
+
+ /**
+ * Returns the parent provider
+ *
+ * @return ProtocolProviderService
+ */
+ public ProtocolProviderService getParentProvider()
+ {
+ return this.provider;
+ }
+
+ /**
+ * Returns a list containing all the<tt>Contact</tt>s who participate in
+ * this ad-hoc chat room.
+ *
+ * @return List<Contact>
+ */
+ public List<Contact> getParticipants()
+ {
+ return new LinkedList<Contact>(this.participants.values());
+ }
+
+ /**
+ * Returns the participant of this ad-hoc chat room which corresponds to
+ * the given _id.
+ *
+ * @param _id
+ * @return Contact the corresponding Contact
+ */
+ public Contact getAdHocChatRoomParticipant(String id)
+ {
+ return this.participants.get(id);
+ }
+
+ /**
+ * Adds a participant to the participants list.
+ *
+ * @param participant The participant (<tt>Contact</tt>) to add.
+ */
+ public void addAdHocChatRoomParticipant(String id, Contact participant)
+ {
+ this.participants.put(id, participant);
+
+ fireParticipantPresenceEvent(participant,
+ AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_JOINED, null);
+ }
+
+ /**
+ * Removes the participant of this ad-hoc chat room which corresponds to
+ * the given _id.
+ *
+ * @param _id
+ */
+ public void removeParticipant(String id)
+ {
+ Contact contact= this.participants.get(id);
+ this.participants.remove(id);
+
+ fireParticipantPresenceEvent(contact,
+ AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_LEFT, null);
+ }
+
+ /**
+ * Returns the number of<tt>Contact</tt>s who participate in this ad-hoc
+ * chat room.
+ */
+ public int getParticipantsCount()
+ {
+ return this.participants.size();
+ }
+
+ public String getSubject()
+ {
+ return null;
+ }
+
+ /**
+ * Invites another user to this room. If we're not joined nothing will
+ * happen.
+ *
+ * @param userAddress the address of the user (email address) to invite to
+ * the room.(one may also invite users not on their contact
+ * list).
+ * @param reason You cannot specify a Reason inside the msn protocol
+ */
+ public void invite(String userAddress, String reason)
+ {
+ // msn requires lower case email addresses
+ userAddress = userAddress.toLowerCase();
+
+ if (switchboard == null)
+ {
+ pendingInvitations.add(userAddress);
+ }
+ else
+ {
+ switchboard.inviteContact(Email.parseStr(userAddress));
+ }
+ }
+
+ public void join()
+ {
+ // We don't specify a reason.
+ this.opSetAdHocMuc.fireLocalUserPresenceEvent(this,
+ LocalUserAdHocChatRoomPresenceChangeEvent.LOCAL_USER_JOINED, null);
+
+ // We buffered the messages before the user has joined the chat, now the
+ // user has joined so we fire them again
+ for (EventObject evt : this.messageBuffer)
+ {
+ this.fireMessageEvent(evt);
+ }
+ }
+
+ /**
+ * Leave this chat room. Once this method is called, the user won't be
+ * listed as a member of the chat room any more and no further chat events
+ * will be delivered. Depending on the underlying protocol and
+ * implementation leave() might cause the room to be destroyed if it has
+ * been created by the local user.
+ */
+ public void leave()
+ {
+ if (switchboard != null)
+ {
+ switchboard.close();
+ switchboard = null;
+ }
+
+ Iterator<Contact> participantsIter
+ = participants.values().iterator();
+
+ while (participantsIter.hasNext())
+ {
+ Contact participant = (Contact) participantsIter.next();
+
+ fireParticipantPresenceEvent(participant,
+ AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_LEFT,
+ "Local user has left the chat room.");
+ }
+
+ // Delete the list of members
+ participants.clear();
+ }
+
+ public boolean isSystem()
+ {
+ return false;
+ }
+
+ /**
+ * Sends the given message through the participants of this ad-hoc chat
+ * room.
+ *
+ * @param message the message to delivered
+ *
+ * @throws OperationFailedException if send fails
+ */
+ public void sendMessage(Message message) throws OperationFailedException
+ {
+ logger.setLevelInfo();
+ logger.info("switchboard="+this.switchboard);
+ this.switchboard.sendText(message.getContent());
+
+ AdHocChatRoomMessageDeliveredEvent msgDeliveredEvt
+ = new AdHocChatRoomMessageDeliveredEvent(
+ this,
+ System.currentTimeMillis(),
+ message,
+ AdHocChatRoomMessageDeliveredEvent.CONVERSATION_MESSAGE_DELIVERED);
+
+ this.fireMessageEvent(msgDeliveredEvt);
+ }
+
+ /**
+ * Sets the corresponding switchboard.
+ *
+ * @param switchboard Corresponding switchboard.
+ */
+ public void setSwitchboard(MsnSwitchboard switchboard)
+ {
+ this.switchboard = switchboard;
+ }
+
+ /**
+ * Creates the corresponding AdHocChatRoomParticipantPresenceChangeEvent and
+ * notifies all<tt>AdHocChatRoomParticipantPresenceListener</tt>s that a
+ * participant has joined or left this<tt>AdHocChatRoom</tt>.
+ *
+ * @param participant the<tt>Contact</tt>
+ * @param eventID the identifier of the event
+ * @param eventReason the reason of the event
+ */
+ private void fireParticipantPresenceEvent( Contact participant,
+ String eventID,
+ String eventReason)
+ {
+ AdHocChatRoomParticipantPresenceChangeEvent evt =
+ new AdHocChatRoomParticipantPresenceChangeEvent(
+ this, participant, eventID, eventReason);
+
+ logger.trace("Will dispatch the following AdHocChatRoom event: " + evt);
+
+ Iterator<AdHocChatRoomParticipantPresenceListener> listeners = null;
+ synchronized (this.participantsPresenceListeners)
+ {
+ listeners = new ArrayList<AdHocChatRoomParticipantPresenceListener>(
+ this.participantsPresenceListeners).iterator();
+ }
+
+ while (listeners.hasNext())
+ {
+ listeners.next().participantPresenceChanged(evt);
+ }
+ }
+
+ /**
+ * Notifies all interested listeners that a
+ *<tt>AdHocChatRoomMessageDeliveredEvent</tt>,
+ *<tt>AdHocChatRoomMessageReceivedEvent</tt> or a
+ *<tt>AdHocChatRoomMessageDeliveryFailedEvent</tt> has been fired.
+ *
+ * @param evt The specific event
+ */
+ public void fireMessageEvent(EventObject evt)
+ {
+ Iterator<AdHocChatRoomMessageListener> listeners = null;
+ synchronized (messageListeners)
+ {
+ listeners = new ArrayList<AdHocChatRoomMessageListener>(
+ messageListeners).iterator();
+ }
+
+ if (!listeners.hasNext())
+ {
+ messageBuffer.add(evt);
+ }
+
+ while (listeners.hasNext())
+ {
+ AdHocChatRoomMessageListener listener =
+ (AdHocChatRoomMessageListener) listeners.next();
+
+ if (evt instanceof AdHocChatRoomMessageDeliveredEvent)
+ {
+ listener.messageDelivered(
+ (AdHocChatRoomMessageDeliveredEvent) evt);
+ }
+ else if (evt instanceof AdHocChatRoomMessageReceivedEvent)
+ {
+ listener.messageReceived(
+ (AdHocChatRoomMessageReceivedEvent) evt);
+ }
+ else if (evt instanceof AdHocChatRoomMessageDeliveryFailedEvent)
+ {
+ listener.messageDeliveryFailed(
+ (AdHocChatRoomMessageDeliveryFailedEvent) evt);
+ }
+ }
+ }
+
+ /**
+ * Fills the participants list with all participants inside the switchboard
+ * (ad-hoc chat room).
+ *
+ * @param switchboard The corresponding switchboard
+ */
+ public void updateParticipantsList(MsnSwitchboard switchboard)
+ {
+ MsnContact[] contacts = switchboard.getAllContacts();
+
+ for (MsnContact msnContact : contacts)
+ {
+ if (!this.participants.containsKey(msnContact.getId()))
+ {
+// // if the member is not inside the members list, create a
+// // contact instance,
+// // add it to the list and fire a member presence event
+// Contact participant =
+// new ContactMsnImpl(msnContact,
+// msnContact.getDisplayName(),
+// msnContact.getEmail().getEmailAddress(),
+// ChatRoomMemberRole.MEMBER);
+
+ this.participants.put(msnContact.getId(), (Contact) msnContact);
+
+ fireParticipantPresenceEvent(
+ (Contact) msnContact,
+ AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_JOINED,
+ null);
+ }
+ }
+
+ for (String contactAddress: this.pendingInvitations)
+ {
+ this.invite(contactAddress, "");
+ }
+ }
+
+ /**
+ * Returns the identifier of this ad-hoc chat room.
+ *
+ * @return a<tt>String</tt> containing the identifier of this ad-hoc room
+ */
+ public String getIdentifier()
+ {
+ return this.getName();
+ }
+
+ /**
+ * Removes the given participant presence listener.
+ *
+ * @param listener the listener to remove
+ */
+ public void removeParticipantPresenceListener(
+ AdHocChatRoomParticipantPresenceListener listener)
+ {
+ synchronized (this.participantsPresenceListeners)
+ {
+ if (this.participantsPresenceListeners.contains(listener))
+ this.participantsPresenceListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Removes the given message listener.
+ *
+ * @param listener the listener to remove
+ */
+ public void removeMessageListener(AdHocChatRoomMessageListener listener)
+ {
+ synchronized(this.messageListeners)
+ {
+ if(this.messageListeners.contains(listener))
+ {
+ this.messageListeners.remove(listener);
+ }
+ }
+ }
+}

Removed: trunk/src/net/java/sip/communicator/impl/protocol/msn/ChatRoomInvitationMsnImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/msn/ChatRoomInvitationMsnImpl.java?view=auto&rev=5963

Removed: trunk/src/net/java/sip/communicator/impl/protocol/msn/ChatRoomMemberMsnImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/msn/ChatRoomMemberMsnImpl.java?view=auto&rev=5963

Removed: trunk/src/net/java/sip/communicator/impl/protocol/msn/ChatRoomMsnImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/msn/ChatRoomMsnImpl.java?view=auto&rev=5963

Added: trunk/src/net/java/sip/communicator/impl/protocol/msn/OperationSetAdHocMultiUserChatMsnImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/msn/OperationSetAdHocMultiUserChatMsnImpl.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/protocol/msn/OperationSetAdHocMultiUserChatMsnImpl.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,734 @@
+/*
+ * 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.msn;
+
+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 net.sf.jml.*;
+import net.sf.jml.event.*;
+import net.sf.jml.message.*;
+
+/**
+ * A MSN implementation of the ad-hoc multi user chat operation set.
+ *
+ * @author Valentin Martinet
+ */
+public class OperationSetAdHocMultiUserChatMsnImpl
+ implements OperationSetAdHocMultiUserChat
+{
+ private static final Logger logger
+ = Logger.getLogger(OperationSetAdHocMultiUserChatMsnImpl.class);
+
+ /**
+ * Listeners that will be notified of changes in our status in the room.
+ */
+ private Vector<LocalUserAdHocChatRoomPresenceListener> presenceListeners
+ = new Vector<LocalUserAdHocChatRoomPresenceListener>();
+
+ /**
+ * The currently valid MSN protocol provider service implementation.
+ */
+ private ProtocolProviderServiceMsnImpl provider = null;
+
+ /**
+ * The ad-hoc rooms we currently are in.
+ */
+ private Hashtable<String, AdHocChatRoomMsnImpl> adHocChatRoomCache
+ = new Hashtable<String, AdHocChatRoomMsnImpl>();
+
+ /**
+ * A list of listeners subscribed for invitations multi user chat events.
+ */
+ private Vector<AdHocChatRoomInvitationListener> invitationListeners
+ = new Vector<AdHocChatRoomInvitationListener>();
+
+ /**
+ * A list of listeners subscribed for events indicating rejection of a multi
+ * user chat invitation sent by us.
+ */
+ private Vector<AdHocChatRoomInvitationRejectionListener>
+ invitationRejectionListeners
+ = new Vector<AdHocChatRoomInvitationRejectionListener>();
+
+ /**
+ * A list of the ad-hoc rooms that are currently open and created by this
+ * account.
+ */
+ private Hashtable<Object, AdHocChatRoom> userCreatedAdHocChatRoomList
+ = new Hashtable<Object, AdHocChatRoom>();
+
+ /**
+ * Creates an<tt>OperationSetAdHocMultiUserChatMsnImpl</tt> by specifying
+ * the parent provider.
+ */
+ public OperationSetAdHocMultiUserChatMsnImpl(
+ ProtocolProviderServiceMsnImpl provider)
+ {
+ this.provider = provider;
+ this.provider.addRegistrationStateChangeListener(
+ new RegistrationStateListener());
+ }
+
+ /**
+ * Adds the given presence listener to existing presence listeners list.
+ *
+ * @param listener the listener to add
+ */
+ public void addPresenceListener(
+ LocalUserAdHocChatRoomPresenceListener listener)
+ {
+ synchronized(presenceListeners)
+ {
+ if(!presenceListeners.contains(listener))
+ presenceListeners.add(listener);
+ }
+ }
+
+ /**
+ * Adds a listener to invitation notifications.
+ *
+ * @param listener an invitation listener.
+ */
+ public void addInvitationListener(AdHocChatRoomInvitationListener listener)
+ {
+ synchronized (invitationListeners)
+ {
+ if (!invitationListeners.contains(listener))
+ invitationListeners.add(listener);
+ }
+ }
+
+ /**
+ * Removes<tt>listener</tt> from the list of invitation listeners
+ * registered to receive invitation events.
+ *
+ * @param listener the invitation listener to remove.
+ */
+ public void removeInvitationListener(
+ AdHocChatRoomInvitationListener listener)
+ {
+ synchronized (invitationListeners)
+ {
+ invitationListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Adds a listener to invitation notifications.
+ *
+ * @param listener an invitation listener.
+ */
+ public void addInvitationRejectionListener(
+ AdHocChatRoomInvitationRejectionListener listener)
+ {
+ synchronized (invitationRejectionListeners)
+ {
+ if (!invitationRejectionListeners.contains(listener))
+ invitationRejectionListeners.add(listener);
+ }
+ }
+
+ /**
+ * Removes<tt>listener</tt> from the list of invitation listeners
+ * registered to receive invitation events.
+ *
+ * @param listener the invitation listener to remove.
+ */
+ public void removeInvitationRejectionListener(
+ AdHocChatRoomInvitationRejectionListener listener)
+ {
+ synchronized (invitationRejectionListeners)
+ {
+ invitationRejectionListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Creates an<tt>AdHocChatRoom</tt> from the specified _adHocChatRoomName
+ * and the corresponding _switchboard.
+ *
+ * @param adHocChatRoomName the specific chat room name.
+ * @param switchboard The corresponding switchboard.
+ *
+ * @return AdHocChatRoomMsnImpl the chat room that we've just created.
+ */
+ private AdHocChatRoomMsnImpl createAdHocChatRoom(String adHocChatRoomName,
+ MsnSwitchboard switchboard)
+ {
+ synchronized (this.adHocChatRoomCache)
+ {
+ AdHocChatRoomMsnImpl adHocChatRoom = new AdHocChatRoomMsnImpl(
+ adHocChatRoomName, this.provider, switchboard);
+
+ this.adHocChatRoomCache.put(adHocChatRoom.getName(), adHocChatRoom);
+ adHocChatRoom.join();
+ return adHocChatRoom;
+ }
+
+ }
+
+ /**
+ * Creates a message by a given message text.
+ *
+ * @param messageText The message text.
+ * @return the newly created message.
+ */
+ public Message createMessage(String messageText)
+ {
+ return new MessageMsnImpl(messageText,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_ENCODING, null);
+ }
+
+ /**
+ * Creates an ad-hoc room with the named<tt>adHocRoomName</tt> and in
+ * including to the specified<tt>contacts</tt>. When the method
+ * returns the ad-hoc room the local user will not have joined it and thus
+ * will not receive messages on it until the<tt>AdHocChatRoom.join()</tt>
+ * method is called.
+ *
+ * NOTE: this method was done for the Yahoo! implementation. But since both
+ * Yahoo! and MSN are implementing the ad-hoc multi-user-chat operation set,
+ * we have to define this method here.
+ *
+ * @param adHocRoomName the name of the ad-hoc room
+ * @param contacts the list of contacts
+ *
+ * @throws OperationFailedException
+ * @throws OperationNotSupportedException
+ */
+ public AdHocChatRoom createAdHocChatRoom(String adHocRoomName,
+ List<Contact> contacts)
+ throws OperationFailedException, OperationNotSupportedException
+ {
+ AdHocChatRoom adHocRoom = null;
+ adHocRoom = findRoom(adHocRoomName);
+ if (adHocRoom == null)
+ {
+ // when the room hasn't been created, we create it.
+ adHocRoom = createLocalAdHocChatRoomInstance(adHocRoomName);
+
+ // we create an identifier object and create a new switchboard
+ // we need to track this object to identify this chatRoom
+ Object id = new Object();
+ this.provider.getMessenger().newSwitchboard(id);
+ // we put it into a hash table
+ this.userCreatedAdHocChatRoomList.put(id, adHocRoom);
+ }
+ adHocRoom.join();
+ return adHocRoom;
+ }
+
+ /**
+ * Creates an<tt>AdHocChatRoom</tt> whose name is _adHocRoomName with the
+ * properties contained in _adHocRoomProperties
+ *
+ * @param adHocRoomName the name of the ad-hoc room
+ * @param adHocRoomProperties the ad-hoc room's properties
+ *
+ * @throws OperationFailedException
+ * @throws OperationNotSupportedException
+ */
+ public AdHocChatRoom createAdHocChatRoom(String adHocRoomName,
+ Map<String, Object> adHocRoomProperties)
+ throws OperationFailedException, OperationNotSupportedException {
+ AdHocChatRoom adHocRoom = null;
+ adHocRoom = findRoom(adHocRoomName);
+ if (adHocRoom == null)
+ {
+ // when the room hasn't been created, we create it.
+ adHocRoom = createLocalAdHocChatRoomInstance(adHocRoomName);
+
+ // we create an identifier object and create a new switchboard
+ // we need to track this object to identify this chatRoom
+ Object id = new Object();
+ this.provider.getMessenger().newSwitchboard(id);
+ // we put it into a hash table
+ this.userCreatedAdHocChatRoomList.put(id, adHocRoom);
+ }
+ adHocRoom.join();
+ return adHocRoom;
+ }
+
+ /**
+ * Creates a<tt>ChatRoom</tt> from the specified chatRoomName.
+ *
+ * @param adHocChatRoomName the specific ad-hoc chat room name.
+ *
+ * @return AdHocChatRoom the ad-hoc chat room that we've just created.
+ */
+ private AdHocChatRoom createLocalAdHocChatRoomInstance(
+ String adHocChatRoomName)
+ {
+ synchronized (this.adHocChatRoomCache)
+ {
+ AdHocChatRoomMsnImpl adHocChatRoom =
+ new AdHocChatRoomMsnImpl(adHocChatRoomName, this.provider);
+
+ this.adHocChatRoomCache.put(adHocChatRoom.getName(), adHocChatRoom);
+ return adHocChatRoom;
+ }
+ }
+
+ /**
+ * Returns a reference to a chatRoom named<tt>_adHocRoomName</tt> or null.
+ * Note: Only called by user.
+ *
+ * @param adHocRoomName the name of the<tt>AdHocChatRoom</tt> that we're
+ * looking for.
+ * @return the<tt>AdHocChatRoom</tt> named<tt>_adHocRoomName</tt> or null
+ * if no such ad-hoc room exists on the server that this provider is
+ * currently connected to.
+ *
+ * @throws OperationFailedException if an error occurs while trying to
+ * discover the ad-hoc room on the server.
+ * @throws OperationNotSupportedException if the server does not support
+ * multi user chat
+ */
+ public AdHocChatRoom findRoom(String adHocRoomName)
+ throws OperationFailedException, OperationNotSupportedException
+ {
+ assertConnected();
+
+ AdHocChatRoom adHocRoom =
+ (AdHocChatRoom) this.adHocChatRoomCache.get(adHocRoomName);
+
+ return adHocRoom;
+ }
+
+ /**
+ * Returns a reference to an chatRoom named<tt>roomName</tt>. If the chat
+ * room doesn't exist, a new chat room is created for the given
+ * MsnSwitchboard.
+ *
+ * @param switchboard The specific switchboard for the chat room.
+ *
+ * @return the corresponding chat room
+ *
+ * @throws OperationFailedException if an error occurs while trying to
+ * discover the room on the server.
+ * @throws OperationNotSupportedException if the server does not support
+ * multi user chat
+ */
+
+ public AdHocChatRoom findRoom(MsnSwitchboard switchboard)
+ throws OperationFailedException,
+ OperationNotSupportedException
+ {
+ this.assertConnected();
+
+ AdHocChatRoomMsnImpl adHocRoom = (AdHocChatRoomMsnImpl)
+ this.adHocChatRoomCache.get(String.valueOf(switchboard.hashCode()));
+
+ if (adHocRoom == null)
+ {
+ String name = String.valueOf(switchboard.hashCode());
+ adHocRoom = this.createAdHocChatRoom(name, switchboard);
+ adHocRoom.setSwitchboard(switchboard);
+ adHocRoom.updateParticipantsList(switchboard);
+
+ this.adHocChatRoomCache.put(name, adHocRoom);
+
+ // fireInvitationEvent(room,
+ // switchboard.getMessenger().getOwner().getDisplayName(),
+ // "You have been invited to a group chat", null);
+ adHocRoom.join();
+ }
+
+ return adHocRoom;
+ }
+
+ /**
+ * Delivers a<tt>LocalUserAdHocChatRoomPresenceChangeEvent</tt> to all
+ * registered<tt>LocalUserAdHocChatRoomPresenceListener</tt>s.
+ *
+ * @param adHocChatRoom the<tt>AdHocChatRoom</tt> which has been joined,
+ * left, etc.
+ * @param eventType the type of this event; one of LOCAL_USER_JOINED,
+ * LOCAL_USER_LEFT, etc.
+ * @param reason the reason
+ */
+ public void fireLocalUserPresenceEvent( AdHocChatRoom adHocChatRoom,
+ String eventType,
+ String reason)
+ {
+ LocalUserAdHocChatRoomPresenceChangeEvent evt =
+ new LocalUserAdHocChatRoomPresenceChangeEvent(
+ this,
+ adHocChatRoom,
+ eventType,
+ reason);
+
+ Iterator<LocalUserAdHocChatRoomPresenceListener> listeners = null;
+ synchronized(this.presenceListeners)
+ {
+ listeners = new ArrayList<LocalUserAdHocChatRoomPresenceListener>
+ (this.presenceListeners).iterator();
+ }
+
+ while (listeners.hasNext())
+ {
+ LocalUserAdHocChatRoomPresenceListener listener = listeners.next();
+
+ listener.localUserAdHocPresenceChanged(evt);
+ }
+ }
+
+ /**
+ * Checks if an incoming message is a multi user chat message. This is done
+ * by the switchboard, if it is not created by the user, its an active file
+ * transfer switchboard or the user count is too low then this method return
+ * false.
+ *
+ * @param switchboard The corresponding MSNswitchboard.
+ * @return true if it is a group chat message or false in the other case.
+ */
+ public boolean isGroupChatMessage(MsnSwitchboard switchboard)
+ {
+ // //fileTransfer??
+ // if (switchboard.getActiveFileTransfers() != null)
+ // return false;
+
+ Object attachment = switchboard.getAttachment();
+ if (attachment == null)
+ { // the user did not created the chat room by him/her self,
+ // the only way to figure out if this is a group chat message
+ // is to check the user count
+ return (switchboard.getAllContacts().length> 1);
+
+ }
+
+ return this.userCreatedAdHocChatRoomList.containsKey(attachment);
+ }
+
+ public boolean isMultiChatSupportedByContact(Contact contact)
+ {
+ return false;
+ }
+
+ /**
+ * Removes the given listener from presence listeners' list.
+ *
+ * @param listener the listener to remove
+ */
+ public void removePresenceListener(
+ LocalUserAdHocChatRoomPresenceListener listener)
+ {
+ synchronized (this.presenceListeners)
+ {
+ if(this.presenceListeners.contains(listener))
+ {
+ this.presenceListeners.remove(listener);
+ }
+ }
+ }
+
+ /**
+ * Makes sure that we are properly connected.
+ *
+ * @throws OperationFailedException if the provider is not connected.
+ * @throws OperationNotSupportedException if the service is not supported by
+ * the server.
+ */
+ private void assertConnected()
+ throws OperationFailedException,
+ OperationNotSupportedException
+ {
+ if (this.provider == null)
+ throw new IllegalStateException(
+ "The provider must be non-null and signed on the "
+ + "service before being able to communicate.");
+ if (!this.provider.isRegistered())
+ throw new IllegalStateException(
+ "The provider must be signed on the service before "
+ + "being able to communicate.");
+ }
+
+ /**
+ * Our listener that will tell us when we're registered to msn.
+ */
+ private class RegistrationStateListener
+ implements RegistrationStateChangeListener
+ {
+ /**
+ * The method is called by a ProtocolProvider implementation whenever a
+ * change in the registration state of the corresponding provider had
+ * occurred.
+ *
+ * @param evt ProviderStatusChangeEvent the event describing the status
+ * change.
+ */
+ public void registrationStateChanged(RegistrationStateChangeEvent evt)
+ {
+ if (evt.getNewState() == RegistrationState.REGISTERED)
+ {
+ provider.getMessenger().addSwitchboardListener(
+ new MsnSwitchboardListener());
+ provider.getMessenger().addMessageListener(
+ new MsnMessageListener());
+ }
+ }
+
+ }
+
+ /**
+ * Our group chat message listener, it extends the MsnMessageAdapter from
+ * the the jml library.
+ */
+ private class MsnMessageListener
+ extends MsnMessageAdapter
+ implements MsnEmailListener
+ {
+ public void instantMessageReceived( MsnSwitchboard switchboard,
+ MsnInstantMessage message,
+ MsnContact contact)
+ {
+ if (!isGroupChatMessage(switchboard))
+ return;
+
+ Message newMessage = createMessage(message.getContent());
+
+ logger.debug("Group chat message received.");
+ Object attachment = switchboard.getAttachment();
+ try
+ {
+ AdHocChatRoomMsnImpl chatRoom = null;
+
+ if (attachment == null) // chat room session NOT created by
+ // yourself
+ {
+ chatRoom = (AdHocChatRoomMsnImpl) findRoom(switchboard);
+ }
+
+ // user created chat room session?
+ if (attachment != null
+&& userCreatedAdHocChatRoomList.containsKey(attachment))
+ { chatRoom =
+ (AdHocChatRoomMsnImpl) userCreatedAdHocChatRoomList
+ .get(attachment);
+ }
+
+ if (chatRoom == null)
+ {
+ return;
+ }
+
+ Contact participant =
+ chatRoom.getAdHocChatRoomParticipant(contact.getId());
+
+ AdHocChatRoomMessageReceivedEvent msgReceivedEvent =
+ new AdHocChatRoomMessageReceivedEvent(
+ chatRoom,
+ participant,
+ System.currentTimeMillis(),
+ newMessage,
+ AdHocChatRoomMessageReceivedEvent
+ .CONVERSATION_MESSAGE_RECEIVED);
+
+ chatRoom.fireMessageEvent(msgReceivedEvent);
+
+ }
+ catch (OperationFailedException e)
+ {
+ logger.error("Failed to find room with name: ", e);
+ }
+ catch (OperationNotSupportedException e)
+ {
+ logger.error("Failed to find room with name: ", e);
+ }
+
+ }
+
+ public void initialEmailNotificationReceived(
+ MsnSwitchboard switchboard, MsnEmailInitMessage message,
+ MsnContact contact)
+ {
+ }
+
+ public void initialEmailDataReceived(MsnSwitchboard switchboard,
+ MsnEmailInitEmailData message, MsnContact contact)
+ {
+ }
+
+ public void newEmailNotificationReceived(MsnSwitchboard switchboard,
+ MsnEmailNotifyMessage message, MsnContact contact)
+ {
+
+ }
+
+ public void activityEmailNotificationReceived(
+ MsnSwitchboard switchboard, MsnEmailActivityMessage message,
+ MsnContact contact)
+ {
+ }
+ }
+
+ /**
+ * The Switchboard Listener, listens to all four switchboard events:
+ * Switchboard started/closed and User joins/left.
+ *
+ */
+ private class MsnSwitchboardListener
+ extends MsnSwitchboardAdapter
+ {
+ public void contactJoinSwitchboard(MsnSwitchboard switchboard,
+ MsnContact contact)
+ {
+ if (!isGroupChatMessage(switchboard))
+ return;
+
+ Object attachment = switchboard.getAttachment();
+ try
+ {
+ AdHocChatRoomMsnImpl chatRoom = null;
+ if (attachment == null) // chat room session NOT created by
+ // yourself
+ chatRoom = (AdHocChatRoomMsnImpl) findRoom(switchboard);
+
+ // user created chat room session?
+ if (attachment != null
+&& userCreatedAdHocChatRoomList.containsKey(attachment))
+ chatRoom =
+ (AdHocChatRoomMsnImpl) userCreatedAdHocChatRoomList
+ .get(attachment);
+
+ if (chatRoom == null)
+ return;
+
+ Contact msnContact = new ContactMsnImpl(
+ contact, new ServerStoredContactListMsnImpl(
+ new OperationSetPersistentPresenceMsnImpl(provider),
+ provider), true, true);
+ chatRoom.addAdHocChatRoomParticipant( contact.getId(),
+ msnContact);
+ }
+ catch (Exception e)
+ {
+ logger.error("Failed to join switchboard.", e);
+ }
+
+ }
+
+ public void contactLeaveSwitchboard(MsnSwitchboard switchboard,
+ MsnContact contact)
+ {
+ logger
+ .debug(contact.getDisplayName() + " has left the Switchboard");
+
+ Object attachment = switchboard.getAttachment();
+
+ try
+ {
+ AdHocChatRoomMsnImpl adHocChatRoom = null;
+ if (attachment == null)// chat room session NOT created by
+ // yourself
+ adHocChatRoom = (AdHocChatRoomMsnImpl)findRoom(switchboard);
+
+ // user created chat room session?
+ if (attachment != null
+&& userCreatedAdHocChatRoomList.containsKey(attachment))
+ adHocChatRoom =
+ (AdHocChatRoomMsnImpl) userCreatedAdHocChatRoomList
+ .get(attachment);
+
+ if (adHocChatRoom == null)
+ return;
+
+ String participantId = contact.getId();
+
+ Contact participant =
+ adHocChatRoom.getAdHocChatRoomParticipant(participantId);
+
+ if (participant != null)
+ {
+ adHocChatRoom.removeParticipant(participantId);
+ }
+ }
+ catch (OperationFailedException e)
+ {
+ logger.debug( "Could not find a chat room corresponding" +
+ "to the given switchboard.", e);
+ }
+ catch (OperationNotSupportedException e)
+ {
+ logger.debug( "Could not find a chat room corresponding" +
+ "to the given switchboard.", e);
+ }
+ }
+
+ public void switchboardClosed(MsnSwitchboard switchboard)
+ {
+ Object attachment = switchboard.getAttachment();
+ try
+ {
+ AdHocChatRoomMsnImpl adHocChatRoom = null;
+ if (attachment == null)// chat room session NOT created by
+ // yourself
+ adHocChatRoom = (AdHocChatRoomMsnImpl) findRoom(switchboard);
+ // user created chat room session?
+ if (attachment != null
+&& userCreatedAdHocChatRoomList.containsKey(attachment))
+ adHocChatRoom =
+ (AdHocChatRoomMsnImpl) userCreatedAdHocChatRoomList
+ .get(attachment);
+
+ if (adHocChatRoom == null)
+ return;
+
+ adHocChatRoom.setSwitchboard(null);
+
+ adHocChatRoom.leave();
+ fireLocalUserPresenceEvent(adHocChatRoom,
+ LocalUserChatRoomPresenceChangeEvent.LOCAL_USER_DROPPED ,
+ "Switchboard closed.");
+ }
+ catch (Exception e)
+ {
+ }
+ }
+
+ public void switchboardStarted(MsnSwitchboard switchboard)
+ {
+
+ Object switchboardID = switchboard.getAttachment();
+ AdHocChatRoomMsnImpl adHocChatRoom = null;
+ if (switchboardID != null
+&& userCreatedAdHocChatRoomList.containsKey(switchboardID))
+ {
+ adHocChatRoom =
+ (AdHocChatRoomMsnImpl) userCreatedAdHocChatRoomList
+ .get(switchboardID);
+
+ adHocChatRoom.setSwitchboard(switchboard);
+ adHocChatRoom.updateParticipantsList(switchboard);
+ adHocChatRoom.join();
+ }
+ else
+ {
+ logger.setLevelDebug();
+ logger.debug("Could not join the Ad-hoc chat room.");
+ }
+ }
+ }
+
+ /**
+ * Supposed to reject an invitation for MUC.
+ * Note: Not supported inside the MSN.
+ */
+ public void rejectInvitation(AdHocChatRoomInvitation invitation,
+ String rejectReason)
+ {
+ // there is no way to block invitations, because there arn't any
+ // invitations.
+ // the only way would be to block the Friend and that shouldn't be done
+ // here.
+ return;
+ }
+}

Modified: trunk/src/net/java/sip/communicator/impl/protocol/msn/OperationSetBasicInstantMessagingMsnImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/msn/OperationSetBasicInstantMessagingMsnImpl.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/protocol/msn/OperationSetBasicInstantMessagingMsnImpl.java&p2=trunk/src/net/java/sip/communicator/impl/protocol/msn/OperationSetBasicInstantMessagingMsnImpl.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/protocol/msn/OperationSetBasicInstantMessagingMsnImpl.java (original)
+++ trunk/src/net/java/sip/communicator/impl/protocol/msn/OperationSetBasicInstantMessagingMsnImpl.java 2009-09-14 15:51:47+0000
@@ -25,8 +25,8 @@
  public class OperationSetBasicInstantMessagingMsnImpl
      extends AbstractOperationSetBasicInstantMessaging
  {
- private static final Logger logger =
- Logger.getLogger(OperationSetBasicInstantMessagingMsnImpl.class);
+ private static final Logger logger
+ = Logger.getLogger(OperationSetBasicInstantMessagingMsnImpl.class);

      /**
       * The provider that created us.
@@ -39,7 +39,7 @@
       */
      private OperationSetPersistentPresenceMsnImpl opSetPersPresence = null;

- private OperationSetMultiUserChatMsnImpl opSetMuc = null;
+ private OperationSetAdHocMultiUserChatMsnImpl opSetMuc = null;
      /**
       * Creates an instance of this operation set.
       * @param provider a ref to the<tt>ProtocolProviderServiceImpl</tt>
@@ -50,8 +50,8 @@
          ProtocolProviderServiceMsnImpl provider)
      {
          this.msnProvider = provider;
- opSetMuc = (OperationSetMultiUserChatMsnImpl) msnProvider
- .getOperationSet(OperationSetMultiUserChat.class);
+ opSetMuc = (OperationSetAdHocMultiUserChatMsnImpl) msnProvider
+ .getOperationSet(OperationSetAdHocMultiUserChat.class);
          provider.addRegistrationStateChangeListener(new RegistrationStateListener());
      }

Removed: trunk/src/net/java/sip/communicator/impl/protocol/msn/OperationSetMultiUserChatMsnImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/msn/OperationSetMultiUserChatMsnImpl.java?view=auto&rev=5963

Modified: trunk/src/net/java/sip/communicator/impl/protocol/msn/ProtocolProviderServiceMsnImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/msn/ProtocolProviderServiceMsnImpl.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/protocol/msn/ProtocolProviderServiceMsnImpl.java&p2=trunk/src/net/java/sip/communicator/impl/protocol/msn/ProtocolProviderServiceMsnImpl.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/protocol/msn/ProtocolProviderServiceMsnImpl.java (original)
+++ trunk/src/net/java/sip/communicator/impl/protocol/msn/ProtocolProviderServiceMsnImpl.java 2009-09-14 15:51:47+0000
@@ -261,12 +261,13 @@
          {
              this.accountID = accountID;

- supportedOperationSets.put(OperationSetInstantMessageTransform.class.getName(),
+ supportedOperationSets.put(
+ OperationSetInstantMessageTransform.class.getName(),
                  new OperationSetInstantMessageTransformImpl());
-
+
              //initialize the presence operationset
              persistentPresence = new OperationSetPersistentPresenceMsnImpl(this);
-
+
              supportedOperationSets.put(
                  OperationSetPersistentPresence.class.getName(),
                  persistentPresence);
@@ -275,16 +276,15 @@
              supportedOperationSets.put( OperationSetPresence.class.getName(),
                                          persistentPresence);

- // initialize the multi user chat operation set
- OperationSetMultiUserChat multiUserChat = new OperationSetMultiUserChatMsnImpl(
- this);
+ OperationSetAdHocMultiUserChat adHocMultiUserChat =
+ new OperationSetAdHocMultiUserChatMsnImpl(this);

- supportedOperationSets.put(OperationSetMultiUserChat.class
- .getName(), multiUserChat);
+ supportedOperationSets.put(OperationSetAdHocMultiUserChat.class
+ .getName(), adHocMultiUserChat);

             // initialize the IM operation set
- OperationSetBasicInstantMessagingMsnImpl basicInstantMessaging = new OperationSetBasicInstantMessagingMsnImpl(
- this);
+ OperationSetBasicInstantMessagingMsnImpl basicInstantMessaging
+ = new OperationSetBasicInstantMessagingMsnImpl(this);

             supportedOperationSets.put(OperationSetBasicInstantMessaging.class
                     .getName(), basicInstantMessaging);

Modified: trunk/src/net/java/sip/communicator/impl/protocol/sip/SipLogger.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/sip/SipLogger.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/protocol/sip/SipLogger.java&p2=trunk/src/net/java/sip/communicator/impl/protocol/sip/SipLogger.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/protocol/sip/SipLogger.java (original)
+++ trunk/src/net/java/sip/communicator/impl/protocol/sip/SipLogger.java 2009-09-14 15:51:47+0000
@@ -33,31 +33,31 @@
       * Implementation of StackLogger
       */

- /**
+ /**
       * log a stack trace. This helps to look at the stack frame.
       */
- public void logStackTrace()
+ public void logStackTrace()
      {
          logger.trace("JAIN-SIP stack trace", new Throwable());
      }

- public void logStackTrace(int traceLevel)
+ public void logStackTrace(int traceLevel)
      {
          // FIXE ME: don't ignore the level?
          logger.trace("JAIN-SIP stack trace", new Throwable());
      }

- /**
+ /**
       * Get the line count in the log stream.
       *
       * @return line count
       */
- public int getLineCount()
+ public int getLineCount()
      {
          return 0;
      }

- /**
+ /**
       * Log an exception.
       *
       * @param ex

Added: trunk/src/net/java/sip/communicator/impl/protocol/yahoo/AdHocChatRoomInvitationYahooImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/yahoo/AdHocChatRoomInvitationYahooImpl.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/protocol/yahoo/AdHocChatRoomInvitationYahooImpl.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,79 @@
+/*
+ * 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.yahoo;
+
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * The Yahoo implementation of the<tt>AdHocChatRoomInvitation</tt> interface.
+ *
+ * @author Rupert Burchardi
+ * @author Valentin Martinet
+ */
+public class AdHocChatRoomInvitationYahooImpl
+ implements AdHocChatRoomInvitation
+{
+ /**
+ * Corresponding chat room instance.
+ */
+ private AdHocChatRoom chatRoom;
+ /**
+ * The name of the inviter
+ */
+ private String inviter;
+
+ /**
+ * The invitation reason.
+ */
+ private String reason;
+
+ /**
+ * Creates an instance of the<tt>ChatRoomInvitationMsnImpl</tt> by
+ * specifying the targetChatRoom, the inviter, the reason.
+ *
+ * @param targetChatRoom The<tt>AdHocChatRoom</tt> for which the invitation
+ * is
+ * @param inviter The<tt>Contact</tt>, which sent the invitation
+ * @param reason The Reason for the invitation
+ */
+ public AdHocChatRoomInvitationYahooImpl( AdHocChatRoom targetChatRoom,
+ String inviter,
+ String reason)
+ {
+ this.chatRoom = targetChatRoom;
+ this.inviter = inviter;
+ this.reason = reason;
+ }
+
+ /**
+ * Returns the corresponding chat room.
+ * @return The ad-hoc chat room
+ */
+ public AdHocChatRoom getTargetAdHocChatRoom()
+ {
+ return chatRoom;
+ }
+
+ /**
+ * Returns the corresponding inviter.
+ * @return The name of the inviter
+ */
+ public String getInviter()
+ {
+ return inviter;
+ }
+
+ /**
+ * Returns the invitation reason.
+ * @return the invitation reason
+ */
+ public String getReason()
+ {
+ return reason;
+ }
+}

Added: trunk/src/net/java/sip/communicator/impl/protocol/yahoo/AdHocChatRoomYahooImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/yahoo/AdHocChatRoomYahooImpl.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/protocol/yahoo/AdHocChatRoomYahooImpl.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,596 @@
+/*
+ * 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.yahoo;
+
+import java.io.*;
+import java.util.*;
+
+import ymsg.network.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.event.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * Represents a Yahoo ad-hoc chat room, where multiple chat users could
+ * communicate in a many-to-many fashion.
+ *
+ * @author Rupert Burchardi
+ * @author Valentin Martinet
+ */
+public class AdHocChatRoomYahooImpl
+ implements AdHocChatRoom
+{
+ private static final Logger logger = Logger
+ .getLogger(AdHocChatRoomYahooImpl.class);
+
+ /**
+ * Listeners that will be notified of changes in member status in the room
+ * such as member joined, left or being kicked or dropped.
+ */
+ private Vector<AdHocChatRoomParticipantPresenceListener> memberListeners
+ = new Vector<AdHocChatRoomParticipantPresenceListener>();
+
+ /**
+ * Listeners that will be notified every time a new message is received on
+ * this ad-hoc chat room.
+ */
+ private Vector<AdHocChatRoomMessageListener> messageListeners
+ = new Vector<AdHocChatRoomMessageListener>();
+
+ /**
+ * The protocol provider that created us
+ */
+ private ProtocolProviderServiceYahooImpl provider = null;
+
+ /**
+ * The operation set that created us.
+ */
+ private OperationSetAdHocMultiUserChatYahooImpl opSetMuc = null;
+
+ /**
+ * The list of participants of this chat room.
+ */
+ private Hashtable<String, Contact> participants
+ = new Hashtable<String, Contact>();
+
+ /**
+ * The nickname of this chat room local user participant.
+ */
+ private String nickname;
+
+ /**
+ * The yahoo conference model of this ad-hoc chat room, its the
+ * representation of an ad-hoc chat room in the lib for this protocol.
+ */
+ private YahooConference yahooConference = null;
+
+ /**
+ * Creates an instance of a chat room that has been.
+ *
+ * @param multiUserChat
+ * MultiUserChat
+ * @param provider
+ * a reference to the currently valid jabber protocol provider.
+ */
+ public AdHocChatRoomYahooImpl( YahooConference multiUserChat,
+ ProtocolProviderServiceYahooImpl provider)
+ {
+ this.yahooConference = multiUserChat;
+ this.provider = provider;
+ this.opSetMuc = (OperationSetAdHocMultiUserChatYahooImpl) provider
+ .getOperationSet(OperationSetAdHocMultiUserChat.class);
+ }
+
+ /**
+ * Registers<tt>listener</tt> so that it would receive events every time a
+ * new message is received on this chat room.
+ *
+ * @param listener A<tt>MessageListener</tt> that would be notified every
+ * time a new message is received on this chat room.
+ */
+ public void addMessageListener(AdHocChatRoomMessageListener listener)
+ {
+ synchronized (messageListeners)
+ {
+ if (!messageListeners.contains(listener))
+ messageListeners.add(listener);
+ }
+ }
+
+ /**
+ * Removes<tt>listener</tt> so that it won't receive any further message
+ * events from this room.
+ *
+ * @param listener The<tt>MessageListener</tt> to remove from this room
+ */
+ public void removeMessageListener(AdHocChatRoomMessageListener listener)
+ {
+ synchronized (messageListeners)
+ {
+ messageListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Adds a listener that will be notified of changes in our status in the
+ * room.
+ *
+ * @param listener A participant status listener.
+ */
+ public void addParticipantPresenceListener(
+ AdHocChatRoomParticipantPresenceListener listener)
+ {
+ synchronized (memberListeners)
+ {
+ if (!memberListeners.contains(listener))
+ memberListeners.add(listener);
+ }
+ }
+
+ /**
+ * Removes a listener that was being notified of changes in the status of
+ * other chat room participants.
+ *
+ * @param listener A participant status listener.
+ */
+ public void removeParticipantPresenceListener(
+ AdHocChatRoomParticipantPresenceListener listener)
+ {
+ synchronized (memberListeners)
+ {
+ memberListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Create a Message instance for sending arbitrary MIME-encoding content.
+ *
+ * @param content
+ * content value
+ * @param contentType
+ * the MIME-type for<tt>content</tt>
+ * @param contentEncoding
+ * encoding used for<tt>content</tt>
+ * @param subject
+ * a<tt>String</tt> subject or<tt>null</tt> for now subject.
+ * @return the newly created message.
+ */
+ public Message createMessage(byte[] content, String contentType,
+ String contentEncoding, String subject)
+ {
+ return new MessageYahooImpl(new String(content), contentType,
+ contentEncoding, subject);
+ }
+
+ /**
+ * Create a Message instance for sending a simple text messages with default
+ * (text/plain) content type and encoding.
+ *
+ * @param messageText
+ * the string content of the message.
+ * @return Message the newly created message
+ */
+ public Message createMessage(String messageText)
+ {
+ Message msg = new MessageYahooImpl(messageText,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_ENCODING, null);
+ return msg;
+ }
+
+ /**
+ * Returns a<tt>List</tt> of<tt>Contact</tt>s corresponding to all members
+ * currently participating in this room.
+ *
+ * @return a<tt>List</tt> of<tt>Contact</tt> corresponding to all room
+ * members.
+ */
+ public List<Contact> getParticipants()
+ {
+ return new LinkedList<Contact>(participants.values());
+ }
+
+ /**
+ * Updates the member list of the chat room.
+ *
+ */
+ public void updateParticipantsList()
+ {
+ Iterator<?> it = yahooConference.getMembers().iterator();
+
+ while (it.hasNext())
+ {
+ YahooUser user = (YahooUser) it.next();
+ Contact contact;
+ OperationSetPersistentPresenceYahooImpl presenceOpSet
+ = (OperationSetPersistentPresenceYahooImpl) this
+ .getParentProvider().getOperationSet(
+ OperationSetPersistentPresence.class);
+
+ contact = presenceOpSet.findContactByID(user.getId());
+
+ if(!participants.containsKey(contact.getDisplayName()))
+ {
+ participants.put(contact.getDisplayName(), contact);
+ }
+ }
+ }
+
+ /**
+ * Returns the identifier of this<tt>AdHocChatRoom</tt>.
+ *
+ * @return a<tt>String</tt> containing the identifier of this
+ *<tt>AdHocChatRoom</tt>.
+ */
+ public String getIdentifier()
+ {
+ return yahooConference.getName();
+ }
+
+ /**
+ * Returns the number of participants that are currently in this ad-hoc chat
+ * room.
+ *
+ * @return the number of<tt>Contact</tt>s, currently participating in
+ * this ad-hoc room.
+ */
+ public int getParticipantsCount()
+ {
+ return yahooConference.getMembers().size();
+ }
+
+ /**
+ * Returns the name of this<tt>AdHocChatRoom</tt>.
+ *
+ * @return a<tt>String</tt> containing the name of this
+ *<tt>AdHocChatRoom</tt>.
+ */
+ public String getName()
+ {
+ return yahooConference.getName();
+ }
+
+ /**
+ * Returns the protocol provider service that created us.
+ *
+ * @return the protocol provider service that created us.
+ */
+ public ProtocolProviderService getParentProvider()
+ {
+ return provider;
+ }
+
+ /**
+ * Returns the local user's nickname in the context of this chat room or
+ *<tt>null</tt> if not currently joined.
+ *
+ * @return the nickname currently being used by the local user in the
+ * context of the local ad-hoc chat room.
+ */
+
+ public String getUserNickname()
+ {
+ if(nickname == null)
+ nickname = provider.getYahooSession().getLoginIdentity().getId();
+
+ return nickname;
+ }
+
+ /**
+ * Invites another user to this room. If we're not joined nothing will
+ * happen.
+ *
+ * @param userAddress The identifier of the contact (email address or yahoo
+ * id)
+ * @param reason The invite reason, which is send to the invitee.
+ */
+ public void invite(String userAddress, String reason)
+ {
+ try
+ {
+ // the contact is invited unless if he wasn't invited during room's
+ // creation:
+ if(!opSetMuc.getAlreadyInvitedContactAddresses().contains(
+ userAddress))
+ {
+ provider.getYahooSession().extendConference(yahooConference,
+ userAddress, reason);
+ }
+ }
+ catch (IOException ioe)
+ {
+ logger.debug("Failed to invite the user: " + userAddress
+ + " Error: " + ioe);
+ }
+ }
+
+ /**
+ * Indicates whether or not this chat room is corresponding to a server
+ * channel. Note: Returns always<code>false</code>.
+ *
+ * @return Always<code>false</code> since system chat room can't be joined
+ * with current yahoo library.
+ */
+ public boolean isSystem()
+ {
+ return false;
+ }
+
+ /**
+ * Joins this chat room with the nickname of the local user so that the user
+ * would start receiving events and messages for it.
+ *
+ * @throws OperationFailedException with the corresponding code if an error
+ * occurs while joining the room.
+ */
+ public void join() throws OperationFailedException
+ {
+ this.nickname = provider.getAccountID().getUserID();
+ try
+ {
+ provider.getYahooSession().acceptConferenceInvite(yahooConference);
+
+ // We don't specify a reason.
+ opSetMuc.fireLocalUserPresenceEvent(this,
+ LocalUserAdHocChatRoomPresenceChangeEvent.LOCAL_USER_JOINED,
+ null);
+ }
+ catch (Exception e)
+ {
+ logger.setLevelDebug();
+ logger.debug("Couldn't join the chat room: "
+ + yahooConference.getName() + e);
+ }
+ }
+
+ /**
+ * Leave this chat room. Once this method is called, the user won't be
+ * listed as a member of the chat room any more and no further chat events
+ * will be delivered. Depending on the underlying protocol and
+ * implementation leave() might cause the room to be destroyed if it has
+ * been created by the local user.
+ */
+ public void leave()
+ {
+ try
+ {
+ provider.getYahooSession().leaveConference(yahooConference);
+
+ Iterator< Map.Entry<String, Contact>> membersSet
+ = participants.entrySet().iterator();
+
+ while (membersSet.hasNext())
+ {
+ Map.Entry<String, Contact> memberEntry
+ = (Map.Entry<String, Contact>) membersSet.next();
+
+ Contact participant = memberEntry.getValue();
+
+ fireParticipantPresenceEvent(participant,
+ AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_LEFT,
+ "Local user has left the chat room.");
+ }
+ }
+ catch (IOException ioe)
+ {
+ logger.debug("Failed to leave the chat room: "
+ + yahooConference.getName() + " Error: " + ioe);
+ }
+
+ participants.clear();
+ }
+
+ /**
+ * Sends the<tt>message</tt> to the destination indicated by the
+ *<tt>to</tt> contact.
+ *
+ * @param message The<tt>Message</tt> to send.
+ * @throws OperationFailedException if the underlying stack is not
+ * registered or initialized or if the chat room is not joined.
+ */
+ public void sendMessage(Message message) throws OperationFailedException
+ {
+ assertConnected();
+
+ try
+ {
+ provider.getYahooSession().sendConferenceMessage(yahooConference,
+ message.getContent());
+
+ AdHocChatRoomMessageDeliveredEvent msgDeliveredEvt
+ = new AdHocChatRoomMessageDeliveredEvent(
+ this,
+ System.currentTimeMillis(),
+ message,
+ ChatRoomMessageDeliveredEvent.CONVERSATION_MESSAGE_DELIVERED);
+
+ fireMessageEvent(msgDeliveredEvt);
+ }
+ catch (Exception e)
+ {
+ logger.debug("Failed to send a conference message.");
+ }
+ }
+
+ /**
+ * Notifies all interested listeners that a
+ *<tt>AdHocChatRoomMessageDeliveredEvent</tt>,
+ *<tt>AdHocChatRoomMessageReceivedEvent</tt> or a
+ *<tt>AdHocChatRoomMessageDeliveryFailedEvent</tt> has been fired.
+ * @param evt The specific event
+ */
+ public void fireMessageEvent(EventObject evt)
+ {
+ Iterator<AdHocChatRoomMessageListener> listeners = null;
+ synchronized (messageListeners)
+ {
+ listeners = new ArrayList<AdHocChatRoomMessageListener>(
+ messageListeners).iterator();
+ }
+
+ while (listeners.hasNext())
+ {
+ AdHocChatRoomMessageListener listener
+ = (AdHocChatRoomMessageListener) listeners.next();
+
+ if (evt instanceof AdHocChatRoomMessageDeliveredEvent)
+ {
+ listener.messageDelivered(
+ (AdHocChatRoomMessageDeliveredEvent) evt);
+ }
+ else if (evt instanceof AdHocChatRoomMessageReceivedEvent)
+ {
+ listener.messageReceived(
+ (AdHocChatRoomMessageReceivedEvent) evt);
+ }
+ else if (evt instanceof AdHocChatRoomMessageDeliveryFailedEvent)
+ {
+ listener.messageDeliveryFailed(
+ (AdHocChatRoomMessageDeliveryFailedEvent) evt);
+ }
+ }
+ }
+
+ /**
+ * Creates the corresponding AdHocChatRoomParticipantPresenceChangeEvent and
+ * notifies all<tt>AdHocChatRoomParticipantPresenceListener</tt>s that a
+ * Contact has joined or left this<tt>AdHocChatRoom</tt>.
+ *
+ * @param participant the<tt>Contact</tt> that this
+ * @param eventID the identifier of the event
+ * @param eventReason the reason of the event
+ */
+ public void fireParticipantPresenceEvent(Contact participant, String eventID,
+ String eventReason)
+ {
+ AdHocChatRoomParticipantPresenceChangeEvent evt
+ = new AdHocChatRoomParticipantPresenceChangeEvent(this,
+ participant,
+ eventID,
+ eventReason);
+
+ logger.trace("Will dispatch the following ChatRoom event: " + evt);
+
+ Iterator<AdHocChatRoomParticipantPresenceListener> listeners = null;
+ synchronized (memberListeners)
+ {
+ listeners = new ArrayList<AdHocChatRoomParticipantPresenceListener>
+ (memberListeners).iterator();
+ }
+
+ while (listeners.hasNext())
+ {
+ AdHocChatRoomParticipantPresenceListener listener
+ = (AdHocChatRoomParticipantPresenceListener) listeners.next();
+
+ listener.participantPresenceChanged(evt);
+ }
+ }
+
+ /**
+ * Finds the participant of this ad-hoc chat room corresponding to the
+ * given address.
+ *
+ * @param address the address to search for.
+ * @return the participant of this chat room corresponding to the given
+ * nick name.
+ */
+ public Contact findParticipantForAddress(String address)
+ {
+ Iterator<Contact> participantsIter
+ = this.participants.values().iterator();
+
+ while (participantsIter.hasNext())
+ {
+ Contact contact = participantsIter.next();
+
+ if (contact.getAddress().equals(address))
+ {
+ return contact;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Removes the specified ad-hoc chat room participant from the participants
+ * list of this ad-hoc chat room.
+ * @param contact The member, who should be removed from the ad-hoc chat room
+ * participants list.
+ */
+ public void removeChatRoomParticipant(Contact participant)
+ {
+ if(participant == null)
+ return;
+
+ participants.remove(participant.getDisplayName());
+
+ fireParticipantPresenceEvent(participant,
+ AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_LEFT, null);
+ }
+
+ /**
+ * Adds a participant to the ad-hoc chat room participant list.
+ * @param participant The participant, who should be added to the ad-hoc
+ * chat room participant list.
+ */
+ public void addChatRoomParticipant(Contact participant)
+ {
+ if (participant == null)
+ return;
+
+ if (!participants.containsKey(participant.getDisplayName()))
+ {
+ participants.put(participant.getDisplayName(), participant);
+
+ fireParticipantPresenceEvent(participant,
+ AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_JOINED,
+ null);
+ }
+ }
+
+ /**
+ * Returns the yahoo conference model of this chat room.
+ * @return The yahoo conference.
+ */
+ public YahooConference getYahooConference()
+ {
+ return yahooConference;
+ }
+
+ /**
+ * Utility method throwing an exception if the stack is not properly
+ * initialized.
+ * @throws java.lang.IllegalStateException if the underlying stack is
+ * not registered and initialized.
+ */
+ private void assertConnected() throws IllegalStateException
+ {
+ if (provider == null)
+ throw new IllegalStateException(
+ "The provider must be non-null and signed on the "
+ +"service before being able to communicate.");
+ if (!provider.isRegistered())
+ throw new IllegalStateException(
+ "The provider must be signed on the service before "
+ +"being able to communicate.");
+ }
+
+ /**
+ * Determines whether this chat room should be stored in the configuration
+ * file or not. If the chat room is persistent it still will be shown after a
+ * restart in the chat room list. A non-persistent chat room will be only in
+ * the chat room list until the the program is running.
+ *
+ * @return true if this chat room is persistent, false otherwise
+ */
+ public boolean isPersistent()
+ {
+ return false;
+ }
+}

Removed: trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ChatRoomInvitationYahooImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ChatRoomInvitationYahooImpl.java?view=auto&rev=5963

Removed: trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ChatRoomMemberYahooImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ChatRoomMemberYahooImpl.java?view=auto&rev=5963

Removed: trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ChatRoomYahooImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ChatRoomYahooImpl.java?view=auto&rev=5963

Added: trunk/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetAdHocMultiUserChatYahooImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetAdHocMultiUserChatYahooImpl.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetAdHocMultiUserChatYahooImpl.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,776 @@
+package net.java.sip.communicator.impl.protocol.yahoo;
+
+import java.io.*;
+import java.util.*;
+
+import ymsg.network.*;
+import ymsg.network.event.*;
+import ymsg.support.MessageDecoder;
+
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.event.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * A Yahoo implementation of the ad-hoc multi user chat operation set.
+ *
+ * @author Rupert Burchardi
+ * @author Valentin Martinet
+ */
+public class OperationSetAdHocMultiUserChatYahooImpl
+ implements OperationSetAdHocMultiUserChat
+{
+ private static final Logger logger = Logger
+ .getLogger(OperationSetAdHocMultiUserChatYahooImpl.class);
+ /**
+ * A list of listeners subscribed for invitations multi user chat events.
+ */
+ private Vector<AdHocChatRoomInvitationListener> invitationListeners
+ = new Vector<AdHocChatRoomInvitationListener>();
+
+ /**
+ * A list of listeners subscribed for events indicating rejection of a multi
+ * user chat invitation sent by us.
+ */
+ private Vector<AdHocChatRoomInvitationRejectionListener>
+ invitationRejectionListeners
+ = new Vector<AdHocChatRoomInvitationRejectionListener>();
+
+ /**
+ * Listeners that will be notified of changes in our status in the room such
+ * as us being kicked, banned, or granted admin permissions.
+ */
+ private Vector<LocalUserAdHocChatRoomPresenceListener> presenceListeners
+ = new Vector<LocalUserAdHocChatRoomPresenceListener>();
+
+ /**
+ * A list of the rooms that are currently open by this account.
+ */
+ private Hashtable<String, AdHocChatRoomYahooImpl> chatRoomCache
+ = new Hashtable<String, AdHocChatRoomYahooImpl>();
+
+ /**
+ * The currently valid Yahoo protocol provider service implementation.
+ */
+ private ProtocolProviderServiceYahooImpl yahooProvider = null;
+
+ /**
+ * The operation set for the basic instant messaging, provides some
+ * message format functions.
+ */
+ private OperationSetBasicInstantMessagingYahooImpl opSetBasic = null;
+
+ /**
+ * Message decoder allows to convert Yahoo formated messages, which can
+ * contains some specials characters, to HTML or to plain text.
+ */
+ private MessageDecoder messageDecoder = new MessageDecoder();
+
+ /**
+ * Contacts who have been invited to a chat room during his creation (when a
+ * Yahoo! chat room is created with contacts, an invitation to this chat room
+ * is sent to each of them). These contacts are stored here in order to avoid
+ * them to be invited again after room's creation.
+ */
+ private Vector<String> alreadyInvitedContactAddresses = new Vector<String>();
+
+ /**
+ * Instantiates the user operation set with a currently valid instance of
+ * the Yahoo protocol provider.
+ *
+ * @param yahooProvider
+ * a currently valid instance of
+ * ProtocolProviderServiceYahooImpl.
+ */
+ OperationSetAdHocMultiUserChatYahooImpl(
+ ProtocolProviderServiceYahooImpl yahooProvider)
+ {
+ this.yahooProvider = yahooProvider;
+
+ yahooProvider.addRegistrationStateChangeListener(
+ new RegistrationStateListener());
+
+ opSetBasic = (OperationSetBasicInstantMessagingYahooImpl) yahooProvider
+ .getOperationSet(OperationSetBasicInstantMessaging.class);
+ }
+
+ /**
+ * Adds a listener to invitation notifications.
+ *
+ * @param listener
+ * An invitation listener.
+ */
+ public void addInvitationListener(AdHocChatRoomInvitationListener listener)
+ {
+ synchronized (invitationListeners)
+ {
+ if (!invitationListeners.contains(listener))
+ invitationListeners.add(listener);
+ }
+ }
+
+ /**
+ * Removes a listener that was being notified of changes in our status in a
+ * room such as us being kicked, banned or dropped.
+ *
+ * @param listener
+ * the<tt>LocalUserAdHocChatRoomPresenceListener</tt>.
+ */
+ public void removeInvitationListener(
+ AdHocChatRoomInvitationListener listener)
+ {
+ synchronized (invitationListeners)
+ {
+ invitationListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Subscribes<tt>listener</tt> so that it would receive events indicating
+ * rejection of a multi user chat invitation that we've sent earlier.
+ *
+ * @param listener
+ * the listener that we'll subscribe for invitation rejection
+ * events.
+ */
+
+ public void addInvitationRejectionListener(
+ AdHocChatRoomInvitationRejectionListener listener)
+ {
+ synchronized (invitationRejectionListeners)
+ {
+ if (!invitationRejectionListeners.contains(listener))
+ invitationRejectionListeners.add(listener);
+ }
+ }
+
+ /**
+ * Removes<tt>listener</tt> from the list of invitation listeners
+ * registered to receive invitation rejection events.
+ *
+ * @param listener
+ * the invitation listener to remove.
+ */
+ public void removeInvitationRejectionListener(
+ AdHocChatRoomInvitationRejectionListener listener)
+ {
+ synchronized (invitationRejectionListeners)
+ {
+ invitationRejectionListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Adds a listener that will be notified of changes in our status in a chat
+ * room such as us being kicked, banned or dropped.
+ *
+ * @param listener
+ * the<tt>LocalUserAdHocChatRoomPresenceListener</tt>.
+ */
+ public void addPresenceListener(
+ LocalUserAdHocChatRoomPresenceListener listener)
+ {
+ synchronized (presenceListeners)
+ {
+ if (!presenceListeners.contains(listener))
+ presenceListeners.add(listener);
+ }
+ }
+
+ /**
+ * Removes a listener that was being notified of changes in our status in a
+ * room such as us being kicked, banned or dropped.
+ *
+ * @param listener
+ * the<tt>LocalUserChatRoomPresenceListener</tt>.
+ */
+ public void removePresenceListener(
+ LocalUserAdHocChatRoomPresenceListener listener)
+ {
+ synchronized (presenceListeners)
+ {
+ presenceListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Creates a room with the named<tt>roomName</tt> and according to the
+ * specified<tt>roomProperties</tt> on the server that this protocol
+ * provider is currently connected to. Note the roomProperties also contain
+ * users that we like to invite to the chatRoom, this is required in the
+ * yahoo protocol.
+ *
+ * @param roomName
+ * the name of the<tt>AdHocChatRoom</tt> to create.
+ * @param roomProperties
+ * properties specifying how the room should be created.
+ *
+ * @throws OperationFailedException
+ * if the room couldn't be created for some reason (e.g. room
+ * already exists; user already joined to an existent room or
+ * user has no permissions to create a chat room).
+ * @throws OperationNotSupportedException
+ * if chat room creation is not supported by this server
+ *
+ * @return ChatRoom the chat room that we've just created.
+ */
+ public AdHocChatRoom createAdHocChatRoom(String roomName,
+ Map<String, Object> roomProperties)
+ throws OperationFailedException,
+ OperationNotSupportedException
+ {
+ AdHocChatRoom chatRoom = null;
+
+ try
+ {
+ YahooConference conference = yahooProvider.getYahooSession()
+ .createConference(
+ new String[]{}, //users invited to this conference
+ "", //invite message / topic
+ yahooProvider.getYahooSession().getLoginIdentity());
+
+ chatRoom = findRoom(conference);
+ }
+ catch (Exception e)
+ {
+ logger.debug("Failed to create the chat Room" + e);
+ }
+ return chatRoom;
+ }
+
+ /**
+ * Creates an ad-hoc room with the named<tt>adHocRoomName</tt> and in
+ * including to the specified<tt>contacts</tt>. When the method
+ * returns the ad-hoc room the local user will not have joined it and thus
+ * will not receive messages on it until the<tt>AdHocChatRoom.join()</tt>
+ * method is called.
+ *
+ * @param adHocRoomName the name of the room to be created
+ * @param contacts the list of contacts
+ */
+ public AdHocChatRoom createAdHocChatRoom(String adHocRoomName,
+ List<Contact> contacts)
+ {
+ AdHocChatRoom chatRoom = null;
+ String[] invitedContacts = null; // parameter used for room's creation
+ int contactsIndex = 0;
+
+ if(contacts != null)
+ {
+ invitedContacts = new String[contacts.size()];
+ for(Contact contact : contacts)
+ {
+ ContactYahooImpl newContact = (ContactYahooImpl)contact;
+ invitedContacts[contactsIndex] = newContact.getAddress();
+
+ // contact's address is stored here in order to avoid this
+ // contact to be invited again in the chat room implementation:
+ this.alreadyInvitedContactAddresses.add(newContact.getAddress());
+ contactsIndex++;
+ }
+ }
+
+ try
+ {
+ YahooConference conference = yahooProvider.getYahooSession()
+ .createConference(
+ invitedContacts, //users invited to this conference
+ "", //invite message / topic
+ yahooProvider.getYahooSession().getLoginIdentity());
+
+ chatRoom = findRoom(conference);
+
+ }
+ catch (Exception e)
+ {
+ logger.debug("Failed to create the chat Room" + e);
+ }
+ return chatRoom;
+ }
+
+ /**
+ * Returns a reference to a chatRoom named<tt>roomName</tt> or null.
+ *
+ * @param roomName
+ * the name of the<tt>AdHocChatRoom</tt> that we're looking for.
+ * @return the<tt>ChatRoom</tt> named<tt>roomName</tt> or null if no such
+ * room exists on the server that this provider is currently
+ * connected to.
+ * @throws OperationFailedException
+ * if an error occurs while trying to discover the room on the
+ * server.
+ * @throws OperationNotSupportedException
+ * if the server does not support multi user chat
+ */
+ public AdHocChatRoom findRoom(String roomName)
+ throws OperationFailedException,
+ OperationNotSupportedException
+ {
+ AdHocChatRoom room = (AdHocChatRoom) chatRoomCache.get(roomName);
+
+ return room;
+ }
+
+ /**
+ * Returns a reference to a chatRoom based on the YahooConference, or
+ * creates a chatRoom with it.
+ *
+ * @param yahooConference
+ * The yahoo conference model for a chat room
+ * @return the<tt>ChatRoom</tt> with the name that is in the yahoo
+ * conference specified.
+ * @throws OperationFailedException
+ * if an error occurs while trying to discover the room on the
+ * server.
+ * @throws OperationNotSupportedException
+ * if the server does not support multi user chat
+ */
+ public AdHocChatRoom findRoom(YahooConference yahooConference)
+ throws OperationFailedException, OperationNotSupportedException
+ {
+ AdHocChatRoomYahooImpl room =
+ chatRoomCache.get(yahooConference.getName());
+
+ if (room == null)
+ {
+ room = createLocalChatRoomInstance(yahooConference);
+ chatRoomCache.put(yahooConference.getName(), room);
+ }
+ room.join();
+ return room;
+ }
+
+ /**
+ * Creates a<tt>AdHocChatRoom</tt> instance from the specified Yahoo
+ * conference.
+ *
+ * @param yahooConference
+ * The chat room model from the yahoo lib.
+ *
+ * @return AdHocChatRoom the chat room that we've just created.
+ */
+ private AdHocChatRoomYahooImpl
+ createLocalChatRoomInstance(YahooConference yahooConference)
+ {
+ synchronized (chatRoomCache)
+ {
+ AdHocChatRoomYahooImpl newChatRoom
+ = new AdHocChatRoomYahooImpl(yahooConference, yahooProvider);
+
+ return newChatRoom;
+ }
+ }
+
+ /**
+ * Returns true if<tt>contact</tt> supports multi user chat sessions.
+ *
+ * @param contact
+ * reference to the contact whose support for chat rooms we are
+ * currently querying.
+ * @return a boolean indicating whether<tt>contact</tt> supports chatrooms.
+ * @todo Implement this
+ * net.java.sip.communicator.service.protocol.OperationSetMultiUserChat
+ * method
+ */
+ public boolean isMultiChatSupportedByContact(Contact contact)
+ {
+ if (contact.getProtocolProvider().getOperationSet(
+ OperationSetAdHocMultiUserChat.class) != null)
+ return true;
+
+ return false;
+ }
+
+ /**
+ * Informs the sender of an invitation that we decline their invitation.
+ *
+ * @param invitation
+ * the connection to use for sending the rejection.
+ * @param rejectReason
+ * the reason to reject the given invitation
+ */
+ public void rejectInvitation(AdHocChatRoomInvitation invitation,
+ String rejectReason)
+ {
+ AdHocChatRoomYahooImpl chatRoom = (AdHocChatRoomYahooImpl) invitation
+ .getTargetAdHocChatRoom();
+
+ try
+ {
+ yahooProvider.getYahooSession().declineConferenceInvite(
+ chatRoom.getYahooConference(), rejectReason);
+
+ }
+ catch (IOException e)
+ {
+ logger.debug("Failed to reject Invitation: " + e);
+ }
+ }
+
+ /**
+ * Delivers a<tt>AdHocChatRoomInvitationReceivedEvent</tt> to all registered
+ *<tt>AdHocChatRoomInvitationListener</tt>s.
+ *
+ * @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)
+ {
+ AdHocChatRoomInvitationYahooImpl invitation =
+ new AdHocChatRoomInvitationYahooImpl(
+ targetChatRoom, inviter, reason);
+
+ AdHocChatRoomInvitationReceivedEvent evt =
+ new AdHocChatRoomInvitationReceivedEvent(
+ this, invitation, new Date(System.currentTimeMillis()));
+
+ Iterator<AdHocChatRoomInvitationListener> listeners = null;
+ synchronized (invitationListeners)
+ {
+ listeners = new ArrayList<AdHocChatRoomInvitationListener>(
+ invitationListeners).iterator();
+ }
+
+ while (listeners.hasNext())
+ {
+ AdHocChatRoomInvitationListener listener
+ = (AdHocChatRoomInvitationListener) listeners.next();
+
+ listener.invitationReceived(evt);
+ }
+ }
+
+ /**
+ * Delivers a<tt>AdHocChatRoomInvitationRejectedEvent</tt> to all registered
+ *<tt>AdHocChatRoomInvitationRejectionListener</tt>s.
+ *
+ * @param sourceChatRoom
+ * the room that invitation refers to
+ * @param invitee
+ * the name of the invitee that rejected the invitation
+ * @param reason
+ * the reason of the rejection
+ */
+ public void fireInvitationRejectedEvent(AdHocChatRoom sourceChatRoom,
+ String invitee, String reason)
+ {
+ AdHocChatRoomInvitationRejectedEvent evt =
+ new AdHocChatRoomInvitationRejectedEvent(
+ (OperationSetAdHocMultiUserChat) this,
+ sourceChatRoom,
+ invitee,
+ reason,
+ new Date(System.currentTimeMillis()));
+
+ Iterator<AdHocChatRoomInvitationRejectionListener> listeners = null;
+ synchronized (invitationRejectionListeners)
+ {
+ listeners = new ArrayList<AdHocChatRoomInvitationRejectionListener>(
+ invitationRejectionListeners).iterator();
+ }
+
+ while (listeners.hasNext())
+ {
+ AdHocChatRoomInvitationRejectionListener listener
+ = (AdHocChatRoomInvitationRejectionListener) listeners.next();
+
+ listener.invitationRejected(evt);
+ }
+ }
+
+ /**
+ * Delivers a<tt>LocalUserAdHocChatRoomPresenceChangeEvent</tt> to all
+ * registered<tt>LocalUserAdHocChatRoomPresenceListener</tt>s.
+ *
+ * @param chatRoom
+ * the<tt>ChatRoom</tt> which has been joined, left, etc.
+ * @param eventType
+ * the type of this event; one of LOCAL_USER_JOINED,
+ * LOCAL_USER_LEFT, etc.
+ * @param reason
+ * the reason
+ */
+ public void fireLocalUserPresenceEvent( AdHocChatRoom chatRoom,
+ String eventType,
+ String reason)
+ {
+ LocalUserAdHocChatRoomPresenceChangeEvent evt
+ = new LocalUserAdHocChatRoomPresenceChangeEvent(
+ (OperationSetAdHocMultiUserChat) this,
+ chatRoom,
+ eventType,
+ reason);
+
+ Iterator<LocalUserAdHocChatRoomPresenceListener> listeners = null;
+ synchronized (presenceListeners)
+ {
+ listeners = new ArrayList<LocalUserAdHocChatRoomPresenceListener>(
+ presenceListeners).iterator();
+ }
+
+ while (listeners.hasNext())
+ {
+ LocalUserAdHocChatRoomPresenceListener listener
+ = (LocalUserAdHocChatRoomPresenceListener) listeners.next();
+
+ listener.localUserAdHocPresenceChanged(evt);
+ }
+ }
+
+ /**
+ * Returns the Vector of addresses of the contacts invited during a chat room
+ * creation.
+ *
+ * @return Vector<String> contact addresses
+ */
+ public Vector<String> getAlreadyInvitedContactAddresses() {
+ return alreadyInvitedContactAddresses;
+ }
+
+ /**
+ * Create a Message instance for sending arbitrary MIME-encoding content.
+ *
+ * @param content content value
+ * @param contentType the MIME-type for<tt>content</tt>
+ * @param contentEncoding encoding used for<tt>content</tt>
+ * @param subject a<tt>String</tt> subject or<tt>null</tt> for now subject.
+ * @return the newly created message.
+ */
+ public Message createMessage(byte[] content, String contentType,
+ String contentEncoding, String subject)
+ {
+ return new MessageYahooImpl(new String(content), contentType,
+ contentEncoding, subject);
+ }
+
+ /**
+ * Creates a message by a given message text.
+ *
+ * @param messageText
+ * The message text.
+ * @return the newly created message.
+ */
+ public Message createMessage(String messageText)
+ {
+ return new MessageYahooImpl(messageText,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_ENCODING, null);
+ }
+
+ /**
+ * Our listener that will tell us when we're registered to yahoo network.
+ *
+ */
+ private class RegistrationStateListener implements
+ RegistrationStateChangeListener
+ {
+ /**
+ * The method is called by a ProtocolProvider implementation whenever a
+ * change in the registration state of the corresponding provider had
+ * occurred.
+ *
+ * @param evt
+ * ProviderStatusChangeEvent the event describing the status
+ * change.
+ */
+ public void registrationStateChanged(RegistrationStateChangeEvent evt)
+ {
+ if (evt.getNewState() == RegistrationState.REGISTERED)
+ {
+ yahooProvider.getYahooSession().addSessionListener(
+ new YahooMessageListener());
+ }
+ }
+ }
+
+ /**
+ * Our group chat message listener, it extends the SessionAdapter from the
+ * the yahoo library.
+ *
+ */
+ private class YahooMessageListener extends SessionAdapter
+ {
+
+ public void conferenceInviteDeclinedReceived(SessionConferenceEvent ev)
+ {
+ logger.debug("Group Chat invite declined received. "
+ + ev.toString());
+ try
+ {
+ AdHocChatRoom chatRoom = findRoom(ev.getRoom());
+
+ fireInvitationRejectedEvent(chatRoom, ev.getFrom(), ev
+ .getMessage());
+ }
+ catch (Exception e)
+ {
+ logger.debug("Error: " + e);
+ }
+ }
+
+ public void conferenceInviteReceived(SessionConferenceEvent ev)
+ {
+ logger.debug("Conference Invite Received: " + ev.toString());
+
+ try
+ {
+ AdHocChatRoom chatRoom = findRoom(ev.getRoom().getName());
+ if (chatRoom != null)
+ {
+ chatRoom.join();
+ } else
+ {
+ chatRoom = findRoom(ev.getRoom());
+ fireInvitationEvent(chatRoom, ev.getFrom(), ev.getMessage());
+ }
+
+ }
+ catch (Exception e)
+ {
+ logger.debug("Error: " + e);
+ }
+ }
+
+ public void conferenceLogoffReceived(SessionConferenceEvent ev)
+ {
+ logger.debug("Conference Logoff Received: " + ev.toString());
+
+ try
+ {
+ AdHocChatRoomYahooImpl chatRoom =
+ (AdHocChatRoomYahooImpl) findRoom(ev
+ .getRoom().getName());
+
+ if (chatRoom != null)
+ {
+ Contact participant = chatRoom
+ .findParticipantForAddress(ev.getFrom());
+ chatRoom.removeChatRoomParticipant(participant);
+ }
+ }
+ catch (Exception e)
+ {
+ logger.debug("Failed to remove a user from the chat room. " + e);
+ }
+ }
+
+ public void conferenceLogonReceived(SessionConferenceEvent ev)
+ {
+ logger.debug("Conference Logon Received: " + ev.toString());
+
+ try
+ {
+ AdHocChatRoomYahooImpl chatRoom =
+ (AdHocChatRoomYahooImpl) findRoom(ev
+ .getRoom().getName());
+
+ if (chatRoom != null)
+ {
+ OperationSetPersistentPresenceYahooImpl presenceOpSet
+ = (OperationSetPersistentPresenceYahooImpl) chatRoom
+ .getParentProvider().getOperationSet(
+ OperationSetPersistentPresence.class);
+
+ Contact participant
+ = presenceOpSet.findContactByID(ev.getFrom());
+
+ if(alreadyInvitedContactAddresses.contains(
+ participant.getAddress()))
+ {
+ alreadyInvitedContactAddresses.remove(
+ participant.getAddress());
+ }
+
+ chatRoom.addChatRoomParticipant(participant);
+ }
+ }
+ catch (Exception e)
+ {
+ logger.debug("Failed to add a user to the chat room. " + e);
+ }
+ }
+
+ public void conferenceMessageReceived(SessionConferenceEvent ev)
+ {
+ logger.debug("Conference Message Received: " + ev.toString());
+
+ try
+ {
+ String formattedMessage = ev.getMessage();
+ logger.debug("original message received : " + formattedMessage);
+
+ // if the message is decorated by Yahoo, we try to "decode" it
+ // first.
+ if (formattedMessage.startsWith("\u001b"))
+ {
+ formattedMessage = opSetBasic.processLinks(messageDecoder
+ .decodeToHTML(formattedMessage));
+ } else
+ {
+ formattedMessage = opSetBasic
+ .processLinks(formattedMessage);
+ }
+
+ // now, we try to fix a wrong usage of the size attribute in the
+ //<font> HTML element
+ // here, the zero 0 correspond to 10px
+ formattedMessage = formattedMessage.replaceAll(
+ "(<font) (.*) size=\"0\">", "$1 $2 size=\"10\">");
+ formattedMessage = formattedMessage.replaceAll(
+ "(<font) (.*) size=\"(\\d+)\">",
+ "$1 $2 style=\"font-size: $3px;\">");
+
+ logger.debug("formatted Message : " + formattedMessage);
+ // As no indications in the protocol is it html or not. No harm
+ // to set all messages html - doesn't affect the appearance of
+ // the gui
+
+ Message newMessage = createMessage(formattedMessage.getBytes(),
+ OperationSetBasicInstantMessaging.HTML_MIME_TYPE,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_ENCODING,
+ null);
+
+ AdHocChatRoomYahooImpl chatRoom =
+ (AdHocChatRoomYahooImpl) findRoom(ev
+ .getRoom().getName());
+
+ if (chatRoom != null)
+ {
+ Contact member = chatRoom.findParticipantForAddress(
+ ev.getFrom());
+
+ AdHocChatRoomMessageReceivedEvent msgReceivedEvent
+ = new AdHocChatRoomMessageReceivedEvent(
+ chatRoom,
+ member,
+ System.currentTimeMillis(),
+ newMessage,
+ AdHocChatRoomMessageReceivedEvent
+ .CONVERSATION_MESSAGE_RECEIVED);
+
+ chatRoom.fireMessageEvent(msgReceivedEvent);
+ }
+ }
+ catch (Exception e)
+ {
+ logger.debug("Error while receiving a multi user chat message: "
+ + e);
+ }
+
+ }
+
+ public void connectionClosed(SessionEvent ev)
+ {
+ logger.debug("Connection Closed: " + ev.toString());
+ }
+ }
+}

Removed: trunk/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetMultiUserChatYahooImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetMultiUserChatYahooImpl.java?view=auto&rev=5963

Modified: trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolProviderServiceYahooImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolProviderServiceYahooImpl.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolProviderServiceYahooImpl.java&p2=trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolProviderServiceYahooImpl.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolProviderServiceYahooImpl.java (original)
+++ trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolProviderServiceYahooImpl.java 2009-09-14 15:51:47+0000
@@ -342,11 +342,12 @@
                  basicInstantMessaging);

             //initialize the multi user chat operation set
- OperationSetMultiUserChatYahooImpl multiUserChatOpSet =
- new OperationSetMultiUserChatYahooImpl(this);
+ OperationSetAdHocMultiUserChatYahooImpl multiUserChatOpSet =
+ new OperationSetAdHocMultiUserChatYahooImpl(this);

- supportedOperationSets.put(OperationSetMultiUserChat.class.getName(),
- multiUserChatOpSet);
+ supportedOperationSets.put(
+ OperationSetAdHocMultiUserChat.class.getName(),
+ multiUserChatOpSet);

              //initialize the typing notifications operation set
              typingNotifications =

Modified: trunk/src/net/java/sip/communicator/plugin/chatalerter/ChatAlerterActivator.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/plugin/chatalerter/ChatAlerterActivator.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/plugin/chatalerter/ChatAlerterActivator.java&p2=trunk/src/net/java/sip/communicator/plugin/chatalerter/ChatAlerterActivator.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/plugin/chatalerter/ChatAlerterActivator.java (original)
+++ trunk/src/net/java/sip/communicator/plugin/chatalerter/ChatAlerterActivator.java 2009-09-14 15:51:47+0000
@@ -31,7 +31,9 @@
                  ServiceListener,
                  MessageListener,
                  ChatRoomMessageListener,
- LocalUserChatRoomPresenceListener
+ AdHocChatRoomMessageListener,
+ LocalUserChatRoomPresenceListener,
+ LocalUserAdHocChatRoomPresenceListener
  {
      /**
       * The logger for this class.
@@ -106,6 +108,7 @@
                  this.handleProviderAdded(provider);
              }
          }
+
      }

      public void stop(BundleContext bc) throws Exception
@@ -336,4 +339,59 @@
              break;
          }
      }
+
+ public void messageDelivered(AdHocChatRoomMessageDeliveredEvent evt)
+ {
+ // do nothing
+ }
+
+ public void messageDeliveryFailed(
+ AdHocChatRoomMessageDeliveryFailedEvent evt)
+ {
+ // do nothing
+ }
+
+ public void messageReceived(AdHocChatRoomMessageReceivedEvent evt)
+ {
+ try
+ {
+ ExportedWindow win =
+ uiService.getExportedWindow(ExportedWindow.CHAT_WINDOW);
+
+ if(win == null || win.getSource() == null ||
+ !(win.getSource() instanceof JFrame))
+ return;
+
+ JFrame fr = (JFrame)win.getSource();
+
+ if(fr != null)
+ Alerter.newInstance().alert(fr);
+ }
+ catch (Exception ex)
+ {
+ logger.error("Cannot alert chat window!");
+ }
+ }
+
+ /**
+ * Called to notify interested parties that a change in our presence in
+ * an ad-hoc chat room has occurred. Changes may include us being join,
+ * left.
+ * @param evt the<tt>LocalUserAdHocChatRoomPresenceChangeEvent</tt>
+ * instance containing the ad-hoc chat room and the type, and reason of the
+ * change
+ */
+ public void localUserAdHocPresenceChanged(
+ LocalUserAdHocChatRoomPresenceChangeEvent evt)
+ {
+ if(evt.getEventType() ==
+ LocalUserAdHocChatRoomPresenceChangeEvent.LOCAL_USER_JOINED)
+ {
+ evt.getAdHocChatRoom().addMessageListener(this);
+ }
+ else
+ {
+ evt.getAdHocChatRoom().removeMessageListener(this);
+ }
+ }
  }

Modified: trunk/src/net/java/sip/communicator/plugin/contactinfo/resources/personPhoto.png
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/plugin/contactinfo/resources/personPhoto.png?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/plugin/contactinfo/resources/personPhoto.png&p2=trunk/src/net/java/sip/communicator/plugin/contactinfo/resources/personPhoto.png&r1=5963&r2=5964

Binary files. No diff available.

Modified: trunk/src/net/java/sip/communicator/plugin/contactinfo/resources/userInfo16x16.png
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/plugin/contactinfo/resources/userInfo16x16.png?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/plugin/contactinfo/resources/userInfo16x16.png&p2=trunk/src/net/java/sip/communicator/plugin/contactinfo/resources/userInfo16x16.png&r1=5963&r2=5964

Binary files. No diff available.

Modified: trunk/src/net/java/sip/communicator/plugin/facebookaccregwizz/FacebookAccountRegistrationWizard.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/plugin/facebookaccregwizz/FacebookAccountRegistrationWizard.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/plugin/facebookaccregwizz/FacebookAccountRegistrationWizard.java&p2=trunk/src/net/java/sip/communicator/plugin/facebookaccregwizz/FacebookAccountRegistrationWizard.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/plugin/facebookaccregwizz/FacebookAccountRegistrationWizard.java (original)
+++ trunk/src/net/java/sip/communicator/plugin/facebookaccregwizz/FacebookAccountRegistrationWizard.java 2009-09-14 15:51:47+0000
@@ -143,7 +143,7 @@
       */
      public ProtocolProviderService signin(String userName, String password)
      {
- firstWizardPage = null;
+ firstWizardPage = null;
          ProtocolProviderFactory factory
              = FacebookAccRegWizzActivator.getFacebookProtocolProviderFactory();

@@ -342,8 +342,8 @@
          return false;
      }

- public Object getSimpleForm() {
- firstWizardPage = new FirstWizardPage(this);
+ public Object getSimpleForm() {
+ firstWizardPage = new FirstWizardPage(this);
          return firstWizardPage.getSimpleForm();
- }
+ }
  }

Modified: trunk/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java&p2=trunk/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java (original)
+++ trunk/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java 2009-09-14 15:51:47+0000
@@ -128,11 +128,11 @@
      }

      enum MessageEventType{
- None,
- MessageDelivered,
- MessageReceived,
- MessageDeliveryFailed,
- MessageDeliveryPending,
+ None,
+ MessageDelivered,
+ MessageReceived,
+ MessageDeliveryFailed,
+ MessageDeliveryPending,
      }

      /**
@@ -157,21 +157,21 @@
          MessageEventType eventType = MessageEventType.None;
          if (evt instanceof MessageDeliveredEvent)
          {
- eventType = MessageEventType.MessageDelivered;
+ eventType = MessageEventType.MessageDelivered;
          }
          else if (evt instanceof MessageReceivedEvent)
          {
- eventType = MessageEventType.MessageReceived;
+ eventType = MessageEventType.MessageReceived;
          }
          else if (evt instanceof MessageDeliveryFailedEvent)
          {
- eventType = MessageEventType.MessageDeliveryFailed;
+ eventType = MessageEventType.MessageDeliveryFailed;
          }

          // Transform the event.
          evt = messageTransform(evt, eventType);
          if (evt == null)
- return;
+ return;

          for (Iterator<MessageListener> listenerIter = listeners.iterator(); listenerIter
              .hasNext():wink:
@@ -179,15 +179,15 @@
              MessageListener listener = listenerIter.next();
              switch (eventType){
              case MessageDelivered:
- listener.messageDelivered((MessageDeliveredEvent) evt);
- break;
+ listener.messageDelivered((MessageDeliveredEvent) evt);
+ break;
              case MessageDeliveryFailed:
- listener
+ listener
                  .messageDeliveryFailed((MessageDeliveryFailedEvent) evt);
- break;
+ break;
              case MessageReceived:
- listener.messageReceived((MessageReceivedEvent) evt);
- break;
+ listener.messageReceived((MessageReceivedEvent) evt);
+ break;
              }
          }
      }
@@ -221,35 +221,35 @@
      }

      public MessageDeliveredEvent messageDeliveryPendingTransform(MessageDeliveredEvent evt){
- return (MessageDeliveredEvent)messageTransform(evt, MessageEventType.MessageDeliveryPending);
+ return (MessageDeliveredEvent)messageTransform(evt, MessageEventType.MessageDeliveryPending);
      }

      private EventObject messageTransform(EventObject evt, MessageEventType eventType){
-
- ProtocolProviderService protocolProvider;
- switch (eventType){
- case MessageDelivered:
- protocolProvider = ((MessageDeliveredEvent)evt).getDestinationContact().getProtocolProvider();
- break;
- case MessageDeliveryFailed:
- protocolProvider = ((MessageDeliveryFailedEvent)evt).getDestinationContact().getProtocolProvider();
- break;
- case MessageDeliveryPending:
- protocolProvider = ((MessageDeliveredEvent)evt).getDestinationContact().getProtocolProvider();
- break;
- case MessageReceived:
- protocolProvider = ((MessageReceivedEvent)evt).getSourceContact().getProtocolProvider();
- break;
- default:
- return evt;
- }
-
- OperationSetInstantMessageTransformImpl opSetMessageTransform =
+
+ ProtocolProviderService protocolProvider;
+ switch (eventType){
+ case MessageDelivered:
+ protocolProvider = ((MessageDeliveredEvent)evt).getDestinationContact().getProtocolProvider();
+ break;
+ case MessageDeliveryFailed:
+ protocolProvider = ((MessageDeliveryFailedEvent)evt).getDestinationContact().getProtocolProvider();
+ break;
+ case MessageDeliveryPending:
+ protocolProvider = ((MessageDeliveredEvent)evt).getDestinationContact().getProtocolProvider();
+ break;
+ case MessageReceived:
+ protocolProvider = ((MessageReceivedEvent)evt).getSourceContact().getProtocolProvider();
+ break;
+ default:
+ return evt;
+ }
+
+ OperationSetInstantMessageTransformImpl opSetMessageTransform =
              (OperationSetInstantMessageTransformImpl)protocolProvider.getOperationSet(OperationSetInstantMessageTransform.class);

- if (opSetMessageTransform == null)
- return evt;
-
+ if (opSetMessageTransform == null)
+ return evt;
+
          for (Map.Entry<Integer, Vector<TransformLayer>> entry
                  : opSetMessageTransform.transformLayers.entrySet())
          {

Added: trunk/src/net/java/sip/communicator/service/protocol/AdHocChatRoom.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/AdHocChatRoom.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/AdHocChatRoom.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,144 @@
+/*
+ * 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.service.protocol;
+
+import java.util.List;
+
+import net.java.sip.communicator.service.protocol.event.*;
+
+/**
+ * Represents an ad-hoc rendez-vous point where multiple chat users could
+ * communicate together. This interface describes the main methods used by some
+ * protocols for multi user chat, without useless methods (such as kicking a
+ * participant) which aren't supported by these protocols (MSN, ICQ, Yahoo!,
+ * etc.).
+ *
+ *<tt>AdHocChatRoom</tt> acts like a simplified<tt>ChatRoom</tt>.
+ *
+ * @author Valentin Martinet
+ */
+public interface AdHocChatRoom
+{
+ /**
+ * Returns the name of this<tt>AdHocChatRoom</tt>. The name can't be
+ * changed until the<tt>AdHocChatRoom</tt> is ended.
+ *
+ * @return a<tt>String</tt> containing the name
+ */
+ public String getName();
+
+ /**
+ * Returns the identifier of this<tt>AdHocChatRoom</tt>. The identifier of
+ * the ad-hoc chat room would have the following syntax:
+ * [adHocChatRoomName]@[adHocChatRoomServer]@[accountID]
+ *
+ * @return a<tt>String</tt> containing the identifier of this
+ *<tt>AdHocChatRoom</tt>.
+ */
+ public String getIdentifier();
+
+ /**
+ * Adds a listener that will be notified of changes in our participation in
+ * the ad-hoc room such as us being join, left...
+ *
+ * @param listener a member participation listener.
+ */
+ public void addParticipantPresenceListener(
+ AdHocChatRoomParticipantPresenceListener listener);
+
+ /**
+ * Removes a participant presence listener.
+ *
+ * @param listener a member participation listener.
+ */
+ public void removeParticipantPresenceListener(
+ AdHocChatRoomParticipantPresenceListener listener);
+
+ /**
+ * Registers<tt>listener</tt> so that it would receive events every time a
+ * new message is received on this ad-hoc chat room.
+ *
+ * @param listener a<tt>MessageListener</tt> that would be notified every
+ * time a new message is received on this ad-hoc chat room.
+ */
+ public void addMessageListener(AdHocChatRoomMessageListener listener);
+
+ /**
+ * Removes<tt>listener</tt> so that it won't receive any further message
+ * events from this ad-hoc room.
+ *
+ * @param listener the<tt>MessageListener</tt> to remove from this ad-hoc
+ * room
+ */
+ public void removeMessageListener(AdHocChatRoomMessageListener listener);
+
+ /**
+ * Invites another<tt>Contact</tt> to this ad-hoc chat room.
+ *
+ * @param userAddress the address of the<tt>Contact</tt> of the user to
+ * invite to the ad-hoc room.
+ * @param reason a reason, subject, or welcome message that would tell
+ * users why they are being invited.
+ */
+ public void invite(String userAddress, String reason);
+
+ /**
+ * Returns a<tt>List</tt> of<tt>Contact</tt>s corresponding to all
+ * participants currently participating in this room.
+ *
+ * @return a<tt>List</tt> of<tt>Contact</tt>s instances
+ * corresponding to all room members.
+ * @throws OperationFailedException if we fail retrieving the list of room
+ * participants.
+ */
+ public List<Contact> getParticipants();
+
+ /**
+ * Returns the number of participants that are currently in this ad-hoc
+ * chat room.
+ * @return int the number of<tt>Contact</tt>s, currently participating in
+ * this ad-hoc room.
+ */
+ public int getParticipantsCount();
+
+ /**
+ * Create a<tt>Message</tt> instance for sending a simple text messages
+ * with default (text/plain) content type and encoding.
+ *
+ * @param messageText the string content of the message.
+ * @return Message the newly created message
+ */
+ public Message createMessage(String messageText);
+
+ /**
+ * Sends the<tt>Message</tt> to this ad-hoc chat room.
+ *
+ * @param message the<tt>Message</tt> to send.
+ * @throws OperationFailedException if sending the message fails for some
+ * reason.
+ */
+ public void sendMessage(Message message)
+ throws OperationFailedException;
+
+ /**
+ * Returns a reference to the provider that created this room.
+ *
+ * @return a reference to the<tt>ProtocolProviderService</tt> instance
+ * that created this ad-hoc room.
+ */
+ public ProtocolProviderService getParentProvider();
+
+ /**
+ * Joins this ad-hoc chat room with the nickname of the local user so that
+ * the user would start receiving events and messages for it.
+ *
+ * @throws OperationFailedException with the corresponding code if an error
+ * occurs while joining the ad-hoc room.
+ */
+ public void join()
+ throws OperationFailedException;
+}

Added: trunk/src/net/java/sip/communicator/service/protocol/AdHocChatRoomInvitation.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/AdHocChatRoomInvitation.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/AdHocChatRoomInvitation.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,43 @@
+/*
+ * 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.service.protocol;
+
+/**
+ * This interface represents an invitation, which is send from an ad-hoc chat
+ * room participant to another user in order to invite this user to join the
+ * ad-hoc chat room.
+ *
+ * @author Valentin Martinet
+ */
+public interface AdHocChatRoomInvitation
+{
+ /**
+ * Returns the<tt>AdHocChatRoom</tt>, which is the target of this
+ * invitation.
+ * The ad-hoc chat room returned by this method will be the room to which
+ * the user
+ * is invited to join to.
+ *
+ * @return the<tt>AdHocChatRoom</tt>, which is the target of this
+ * invitation
+ */
+ public AdHocChatRoom getTargetAdHocChatRoom();
+
+ /**
+ * Returns the<tt>Contact</tt> that sent this invitation.
+ *
+ * @return the<tt>Contact</tt> that sent this invitation.
+ */
+ public String getInviter();
+
+ /**
+ * Returns the reason of this invitation, or null if there is no reason.
+ *
+ * @return the reason of this invitation, or null if there is no reason
+ */
+ public String getReason();
+}

Added: trunk/src/net/java/sip/communicator/service/protocol/OperationSetAdHocMultiUserChat.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/OperationSetAdHocMultiUserChat.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/OperationSetAdHocMultiUserChat.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,143 @@
+/*
+ * 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.service.protocol;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.protocol.event.*;
+
+/**
+ * Allows creating, configuring, joining and administering of individual
+ * text-based ad-hoc conference rooms.
+ *
+ * @author Valentin Martinet
+ */
+public interface OperationSetAdHocMultiUserChat
+ extends OperationSet
+{
+ /**
+ * Creates an ad-hoc room with the named<tt>adHocRoomName</tt> and
+ * according to the specified<tt>adHocRoomProperties</tt>. When the method
+ * returns the ad-hoc room the local user will not have joined it and thus
+ * will not receive messages on it until the<tt>AdHocChatRoom.join()</tt>
+ * method is called.
+ *<p>
+ *
+ * @param adHocRoomName
+ * the name of the<tt>AdHocChatRoom</tt> to create.
+ * @param adHocRoomProperties
+ * properties specifying how the ad-hoc room should be created;
+ *<tt>null</tt> for no properties just like an empty
+ *<code>Map</code>
+ * @throws OperationFailedException
+ * if the ad-hoc room couldn't be created for some reason.
+ * @throws OperationNotSupportedException
+ * if chat room creation is not supported by this server
+ *
+ * @return the newly created<tt>AdHocChatRoom</tt> named<tt>roomName</tt>.
+ */
+ public AdHocChatRoom createAdHocChatRoom(String adHocRoomName,
+ Map<String, Object> adHocRoomProperties)
+ throws OperationFailedException, OperationNotSupportedException;
+
+ /**
+ * Creates an ad-hoc room with the named<tt>adHocRoomName</tt> and in
+ * including to the specified<tt>contacts</tt>. When the method
+ * returns the ad-hoc room the local user will not have joined it and thus
+ * will not receive messages on it until the<tt>AdHocChatRoom.join()</tt>
+ * method is called.
+ *<p>
+ *
+ * @param adHocRoomName
+ * the name of the<tt>AdHocChatRoom</tt> to create.
+ * @param contacts
+ * the contacts who are added to the room when it's created;
+ *<tt>null</tt> for no contacts
+ * @throws OperationFailedException
+ * if the ad-hoc room couldn't be created for some reason.
+ * @throws OperationNotSupportedException
+ * if chat room creation is not supported by this server
+ *
+ * @return the newly created<tt>AdHocChatRoom</tt> named<tt>roomName</tt>.
+ */
+ public AdHocChatRoom createAdHocChatRoom(String adHocRoomName,
+ List<Contact> contacts)
+ throws OperationFailedException, OperationNotSupportedException;
+
+ /**
+ * Returns a reference to an AdHocChatRoom named<tt>adHocRoomName</tt> or
+ * null if no ad-hoc room with the given name exist on the server.
+ *<p>
+ * @param adHocRroomName the name of the<tt>AdHocChatRoom</tt> that we're
+ * looking for.
+ * @return the<tt>AdHocChatRoom</tt> named<tt>adHocRoomName</tt> if it
+ * exists, null otherwise.
+ *
+ * @throws OperationFailedException if an error occurs while trying to
+ * discover the ad-hoc room on the server.
+ * @throws OperationNotSupportedException if the server does not support
+ * multi-user chat
+ */
+ public AdHocChatRoom findRoom(String adHocRoomName)
+ throws OperationFailedException, OperationNotSupportedException;
+
+ /**
+ * Returns true if<tt>contact</tt> supports multi-user chat sessions.
+ *
+ * @param contact reference to the contact whose support for ad-hoc chat
+ * rooms we are currently querying.
+ * @return a boolean indicating whether<tt>contact</tt> supports ad-hoc
+ * chat rooms.
+ */
+ public boolean isMultiChatSupportedByContact(Contact contact);
+
+ /**
+ * Adds a listener that will be notified of changes in our participation in
+ * an ad-hoc chat room such as us being joined, left.
+ *
+ * @param listener a local user participation listener.
+ */
+ public void addPresenceListener(
+ LocalUserAdHocChatRoomPresenceListener listener);
+
+ /**
+ * Removes a listener that was being notified of changes in our
+ * participation in an ad-hoc room such as us being joined, left.
+ *
+ * @param listener a local user participation listener.
+ */
+ public void removePresenceListener(
+ LocalUserAdHocChatRoomPresenceListener listener);
+
+ /**
+ * Adds the given<tt>listener</tt> to the list of
+ *<tt>AdHocChatRoomInvitationListener</tt>-s that would be notified when
+ * an add-hoc chat room invitation has been received.
+ *
+ * @param listener the<tt>AdHocChatRoomInvitationListener</tt> to add
+ */
+ public void addInvitationListener(AdHocChatRoomInvitationListener listener);
+
+ /**
+ * Adds the given<tt>listener</tt> to the list of
+ *<tt>AdHocChatRoomInvitationRejectionListener</tt>-s that would be
+ * notified when an add-hoc chat room invitation has been rejected.
+ *
+ * @param listener the<tt>AdHocChatRoomInvitationListener</tt> to add
+ */
+ public void addInvitationRejectionListener(
+ AdHocChatRoomInvitationRejectionListener listener);
+
+ /**
+ * Informs the sender of an invitation that we decline their invitation.
+ *
+ * @param invitation the invitation we are rejecting.
+ * @param rejectReason the reason to reject the invitation (optional)
+ */
+ public void rejectInvitation( AdHocChatRoomInvitation invitation,
+ String rejectReason);
+}

Added: trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomCreatedEvent.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomCreatedEvent.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomCreatedEvent.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,59 @@
+/*
+ * 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.service.protocol.event;
+
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * The event that occurs when an ad-hoc chat room has been created.
+ *
+ * @author Valentin Martinet
+ */
+public class AdHocChatRoomCreatedEvent
+{
+ /**
+ * The ad-hoc room that has been created.
+ */
+ private AdHocChatRoom adHocChatRoom;
+
+ /**
+ * The<tt>Contact</tt> who created the ad-hoc room.
+ */
+ private Contact by;
+
+ /**
+ * Initializes an<tt>AdHocChatRoomCreatedEvent</tt> with the creator (<tt>
+ * by</tt>) and the ad-hoc room<tt>adHocChatRoom</tt>.
+ *
+ * @param adHocChatRoom the<tt>AdHocChatRoom</tt>
+ * @param by the<tt>Contact</tt> who created this ad-hoc room
+ */
+ public AdHocChatRoomCreatedEvent(AdHocChatRoom adHocChatRoom, Contact by)
+ {
+ this.adHocChatRoom = adHocChatRoom;
+ this.by = by;
+ }
+
+ /**
+ * Returns the<tt>Contact</tt> who created the room.
+ *
+ * @return<tt>Contact</tt>
+ */
+ public Contact getBy()
+ {
+ return this.by;
+ }
+
+ /**
+ * Returns the ad-hoc room concerned by this event.
+ *
+ * @return<tt>AdHocChatRoom</tt>
+ */
+ public AdHocChatRoom getAdHocCreatedRoom()
+ {
+ return this.adHocChatRoom;
+ }
+}

Added: trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomDestroyedEvent.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomDestroyedEvent.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomDestroyedEvent.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,59 @@
+/*
+ * 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.service.protocol.event;
+
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * The event that occurs when an ad-hoc chat room has been created.
+ *
+ * @author Valentin Martinet
+ */
+public class AdHocChatRoomDestroyedEvent
+{
+ /**
+ * The ad-hoc room that has been created.
+ */
+ private AdHocChatRoom adHocChatRoom;
+
+ /**
+ * The<tt>Contact</tt> who created the ad-hoc room.
+ */
+ private Contact by;
+
+ /**
+ * Initializes an<tt>AdHocChatRoomDestroyedEvent</tt> with the creator
+ * (<tt> by</tt>) and the ad-hoc room<tt>adHocChatRoom</tt>.
+ *
+ * @param adHocChatRoom the<tt>AdHocChatRoom</tt>
+ * @param by the<tt>Contact</tt> who created this ad-hoc room
+ */
+ public AdHocChatRoomDestroyedEvent(AdHocChatRoom adHocChatRoom, Contact by)
+ {
+ this.adHocChatRoom = adHocChatRoom;
+ this.by = by;
+ }
+
+ /**
+ * Returns the<tt>Contact</tt> who created the room.
+ *
+ * @return<tt>Contact</tt>
+ */
+ public Contact getBy()
+ {
+ return this.by;
+ }
+
+ /**
+ * Returns the ad-hoc room concerned by this event.
+ *
+ * @return<tt>AdHocChatRoom</tt>
+ */
+ public AdHocChatRoom getAdHocDestroyedRoom()
+ {
+ return this.adHocChatRoom;
+ }
+}

Added: trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationListener.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationListener.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationListener.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,26 @@
+/*
+ * 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.service.protocol.event;
+
+/**
+ * A listener that dispatches events notifying that an invitation to join an
+ * ad-hoc MUC room is received.
+ *
+ * @author Valentin Martinet
+ */
+public interface AdHocChatRoomInvitationListener
+{
+ /**
+ * Called when we receive an invitation to join an existing
+ *<tt>AdHocChatRoom</tt>.
+ *<p>
+ * @param evt the<tt>AdHocChatRoomInvitationReceivedEvent</tt> that
+ * contains the newly received invitation and its source provider.
+ */
+ public abstract void invitationReceived(
+ AdHocChatRoomInvitationReceivedEvent evt);
+}

Added: trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationReceivedEvent.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationReceivedEvent.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationReceivedEvent.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,85 @@
+/*
+ * 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.service.protocol.event;
+
+import java.util.*;
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ *<tt>AdHocChatRoomInvitationReceivedEvent</tt>s indicate reception of an
+ * invitation to join an ad-hoc chat room.
+ *
+ * @author Valentin Martinet
+ */
+@SuppressWarnings("serial")
+public class AdHocChatRoomInvitationReceivedEvent
+ extends EventObject
+{
+ /**
+ * The invitation corresponding to this event.
+ */
+ private final AdHocChatRoomInvitation invitation;
+
+ /**
+ * A timestamp indicating the exact date when the event occurred.
+ */
+ private final Date timestamp;
+
+ /**
+ * Creates an<tt>InvitationReceivedEvent</tt> representing reception of
+ * the<tt>source</tt> invitation received from the specified
+ *<tt>from</tt> ad-hoc chat room participant.
+ *
+ * @param adHocMultiUserChatOpSet the
+ *<tt>OperationSetAdHocMultiUserChat</tt>, which dispatches this event
+ * @param invitation the<tt>AdHocChatRoomInvitation</tt> that this event is
+ * for
+ * @param timestamp the exact date when the event occurred.
+ */
+ public AdHocChatRoomInvitationReceivedEvent(
+ OperationSetAdHocMultiUserChat adHocMultiUserChatOpSet,
+ AdHocChatRoomInvitation invitation,
+ Date timestamp)
+ {
+ super(adHocMultiUserChatOpSet);
+
+ this.invitation = invitation;
+ this.timestamp = timestamp;
+ }
+
+ /**
+ * Returns the ad-hoc multi user chat operation set that dispatches this
+ * event.
+ *
+ * @return the ad-hoc multi user chat operation set that dispatches this
+ * event.
+ */
+ public OperationSetAdHocMultiUserChat getSourceOperationSet()
+ {
+ return (OperationSetAdHocMultiUserChat) getSource();
+ }
+
+ /**
+ * Returns the<tt>AdHocChatRoomInvitation</tt> that this event is for.
+ *
+ * @return the<tt>AdHocChatRoomInvitation</tt> that this event is for.
+ */
+ public AdHocChatRoomInvitation getInvitation()
+ {
+ return invitation;
+ }
+
+ /**
+ * A timestamp indicating the exact date when the event ocurred.
+ *
+ * @return a Date indicating when the event ocurred.
+ */
+ public Date getTimestamp()
+ {
+ return timestamp;
+ }
+}

Added: trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationRejectedEvent.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationRejectedEvent.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationRejectedEvent.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,123 @@
+/*
+ * 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.service.protocol.event;
+
+import java.util.*;
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ *<tt>AdHocChatRoomInvitationRejectedEvent</tt>s indicates the reception of a
+ * rejection of an invitation.
+ *
+ * @author Valentin Martinet
+ */
+@SuppressWarnings("serial")
+public class AdHocChatRoomInvitationRejectedEvent
+ extends EventObject
+{
+ /**
+ * The<tt>AdHocChatRoom</tt> for which the initial invitation was.
+ */
+ private AdHocChatRoom adHocChatRoom;
+
+ /**
+ * The invitee that rejected the invitation.
+ */
+ private String invitee;
+
+ /**
+ * The reason why this invitation is rejected or null if there is no reason
+ * specified.
+ */
+ private String reason;
+
+ /**
+ * The exact date at which this event occured.
+ */
+ private Date timestamp;
+
+ /**
+ * Creates a<tt>AdHocChatRoomInvitationRejectedEvent</tt> representing the
+ * rejection of an invitation, rejected by the given<tt>invitee</tt>.
+ *
+ * @param source the<tt>OperationSetAdHocMultiUserChat</tt> that dispatches
+ * this
+ * event
+ * @param adHocChatRoom the<tt>AdHocChatRoom</tt> for which the initial
+ * invitation was
+ * @param invitee the name of the invitee that rejected the invitation
+ * @param reason the reason of the rejection
+ * @param timestamp the exact date when the event ocurred
+ */
+ public AdHocChatRoomInvitationRejectedEvent(
+ OperationSetAdHocMultiUserChat source,
+ AdHocChatRoom adHocChatRoom,
+ String invitee,
+ String reason,
+ Date timestamp)
+ {
+ super(source);
+
+ this.adHocChatRoom = adHocChatRoom;
+ this.invitee = invitee;
+ this.reason = reason;
+ this.timestamp = timestamp;
+ }
+
+ /**
+ * Returns the ad-hoc multi user chat operation set that dispatches this
+ * event.
+ *
+ * @return the ad-hoc multi user chat operation set that dispatches this
+ * event
+ */
+ public OperationSetAdHocMultiUserChat getSourceOperationSet()
+ {
+ return (OperationSetAdHocMultiUserChat)getSource();
+ }
+
+ /**
+ * Returns the<tt>AdHocChatRoom</tt> for which the initial invitation was.
+ *
+ * @return the<tt>AdHocChatRoom</tt> for which the initial invitation was
+ */
+ public AdHocChatRoom getChatRoom()
+ {
+ return adHocChatRoom;
+ }
+
+ /**
+ * Returns the name of the invitee that rejected the invitation.
+ *
+ * @return the name of the invitee that rejected the invitation
+ */
+ public String getInvitee()
+ {
+ return invitee;
+ }
+
+ /**
+ * Returns the reason for which the<tt>AdHocChatRoomInvitation</tt> is
+ * rejected.
+ *
+ * @return the reason for which the<tt>AdHocChatRoomInvitation</tt> is
+ * rejected.
+ */
+ public String getReason()
+ {
+ return reason;
+ }
+
+ /**
+ * A timestamp indicating the exact date when the event occurred.
+ * @return a Date indicating when the event occurred.
+ */
+ public Date getTimestamp()
+ {
+ return timestamp;
+ }
+}

Added: trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationRejectionListener.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationRejectionListener.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationRejectionListener.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,26 @@
+/*
+ * 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.service.protocol.event;
+
+/**
+ * A listener that dispatches events notifying that an invitation which was
+ * sent earlier has been rejected by the invitee.
+ *
+ * @author Valentin Martinet
+ */
+public interface AdHocChatRoomInvitationRejectionListener
+{
+ /**
+ * Called when an invitee rejects an invitation previously sent by us.
+ *
+ * @param evt the instance of the<tt>AdHocChatRoomInvitationRejectedEvent
+ *</tt>
+ * containing the rejected ad-hoc chat room invitation as well as the source
+ * provider where this happened.
+ */
+ public void invitationRejected(AdHocChatRoomInvitationRejectedEvent evt);
+}

Added: trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomListener.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomListener.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomListener.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,29 @@
+/*
+ * 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.service.protocol.event;
+
+/**
+ * A listener which dispatches events notifying ad-hoc chat rooms who have been
+ * created, joined and destroyed.
+ *
+ * @author Valentin Martinet
+ */
+public interface AdHocChatRoomListener
+{
+ /**
+ * Called when we receive an<tt>AdHocChatRoomCreatedEvent</tt>.
+ *
+ * @param evt the<tt>AdHocChatRoomCreatedEvent</tt>
+ */
+ public void adHocChatRoomCreated(AdHocChatRoomCreatedEvent evt);
+
+ /**
+ * Called when we receive an<tt>AdHocChatRoomDestroyedEvent</tt>.
+ *
+ * @param evt the<tt>AdHocChatRoomDestroyedEvent</tt>
+ */
+ public void adHocChatRoomDestroyed(AdHocChatRoomDestroyedEvent evt);
+}

Added: trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageDeliveredEvent.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageDeliveredEvent.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageDeliveredEvent.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,119 @@
+/*
+ * 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.service.protocol.event;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ *<tt>MessageDeliveredEvent</tt>s confirm successful delivery of an instant
+ * message. Here, it's applied to an<tt>AdHocChatRoom</tt>.
+ *
+ * @author Valentin Martinet
+ */
+@SuppressWarnings("serial")
+public class AdHocChatRoomMessageDeliveredEvent
+ extends EventObject
+{
+ /**
+ * An event type indicating that the message being received is a standard
+ * conversation message sent by another participant of the ad-hoc chat room
+ * to all current participants.
+ */
+ public static final int CONVERSATION_MESSAGE_DELIVERED = 1;
+
+ /**
+ * An event type indicating that the message being received is a special
+ * message that sent by either another participant or the server itself,
+ * indicating that some kind of action (other than the delivery of a
+ * conversation message) has occurred. Action messages are widely used
+ * in IRC through the /action and /me commands
+ */
+ public static final int ACTION_MESSAGE_DELIVERED = 2;
+
+ /**
+ * A timestamp indicating the exact date when the event occurred.
+ */
+ private final long timestamp;
+
+ /**
+ * The received<tt>Message</tt>.
+ */
+ private Message message = null;
+
+ /**
+ * The type of message event that this instance represents.
+ */
+ private int eventType = -1;
+
+ /**
+ * Creates a<tt>MessageDeliveredEvent</tt> representing delivery of the
+ *<tt>source</tt> message to the specified<tt>to</tt> contact.
+ *
+ * @param source the<tt>AdHocChatRoom</tt> which triggered this event.
+ * @param timestamp a date indicating the exact moment when the event
+ * occurred
+ * @param message the message that triggered this event.
+ * @param eventType indicating the type of the delivered event. It's
+ * either an ACTION_MESSAGE_DELIVERED or a CONVERSATION_MESSAGE_DELIVERED.
+ */
+ public AdHocChatRoomMessageDeliveredEvent( AdHocChatRoom source,
+ long timestamp,
+ Message message,
+ int eventType)
+ {
+ super(source);
+
+ this.timestamp = timestamp;
+ this.message = message;
+ this.eventType = eventType;
+ }
+
+ /**
+ * Returns the received message.
+ *
+ * @return the<tt>Message</tt> that triggered this event.
+ */
+ public Message getMessage()
+ {
+ return this.message;
+ }
+
+ /**
+ * A timestamp indicating the exact date when the event occurred.
+ *
+ * @return a Date indicating when the event occurred.
+ */
+ public long getTimestamp()
+ {
+ return this.timestamp;
+ }
+
+ /**
+ * Returns the<tt>AdHocChatRoom</tt> that triggered this event.
+ *
+ * @return the<tt>AdHocChatRoom</tt> that triggered this event.
+ */
+ public AdHocChatRoom getSourceAdHocChatRoom()
+ {
+ return (AdHocChatRoom) this.getSource();
+ }
+
+ /**
+ * Returns the type of message event represented by this event instance.
+ * Message event type is one of the XXX_MESSAGE_DELIVERED fields of this
+ * class.
+ *
+ * @return one of the XXX_MESSAGE_DELIVERED fields of this
+ * class indicating the type of this event.
+ */
+ public int getEventType()
+ {
+ return this.eventType;
+ }
+}

Added: trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageDeliveryFailedEvent.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageDeliveryFailedEvent.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageDeliveryFailedEvent.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,149 @@
+/*
+ * 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.service.protocol.event;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ *<tt>AdHocChatRoomMessageDeliveredEvent</tt>s confirm successful delivery of
+ * an instant message.
+ *
+ * @author Valentin Martinet
+ */
+@SuppressWarnings("serial")
+public class AdHocChatRoomMessageDeliveryFailedEvent
+ extends EventObject
+{
+ /**
+ * The ad-hoc chat room participant that this message has been sent to.
+ */
+ private Contact to = null;
+
+ /**
+ * Set when no other error code can describe the exception that occurred.
+ */
+ public static final int UNKNOWN_ERROR = 1;
+
+ /**
+ * Set when delivery fails due to a failure in network communications or
+ * a transport error.
+ */
+ public static final int NETWORK_FAILURE = 2;
+
+ /**
+ * Set to indicate that delivery has failed because the provider was not
+ * registered.
+ */
+ public static final int PROVIDER_NOT_REGISTERED = 3;
+
+ /**
+ * Set when delivery fails for implementation specific reasons.
+ */
+ public static final int INTERNAL_ERROR = 4;
+
+ /**
+ * Set when delivery fails because we're trying to send a message to a
+ * contact that is currently offline and the server does not support
+ * offline messages.
+ */
+ public static final int OFFLINE_MESSAGES_NOT_SUPPORTED = 5;
+
+ /**
+ * An error code indicating the reason for the failure of this delivery.
+ */
+ private int errorCode = UNKNOWN_ERROR;
+
+ /**
+ * A timestamp indicating the exact date when the event occurred.
+ */
+ private Date timestamp = null;
+
+ /**
+ * The received<tt>Message</tt>.
+ */
+ private Message message = null;
+
+ /**
+ * Creates an<tt>AdHocChatRoomMessageDeliveryFailedEvent</tt> indicating
+ * failure of delivery of the<tt>source</tt> message to the specified
+ *<tt>to</tt> contact.
+ *
+ * @param source the<tt>Message</tt> whose delivery this event represents.
+ * @param to the<tt>Contact</tt> that this message was sent to.
+ * @param errorCode an errorCode indicating the reason of the failure.
+ * @param timestamp the exact Date when it was determined that delivery
+ * had failed.
+ * @param message the received<tt>Message</tt>.
+ */
+ public AdHocChatRoomMessageDeliveryFailedEvent(AdHocChatRoom source,
+ Contact to,
+ int errorCode,
+ Date timestamp,
+ Message message)
+ {
+ super(source);
+
+ this.to = to;
+ this.errorCode = errorCode;
+ this.timestamp = timestamp;
+ this.message = message;
+ }
+ /**
+ * Returns a reference to the<tt>Contact</tt> that the source
+ * (failed)<tt>Message</tt> was sent to.
+ *
+ * @return a reference to the<tt>Contact</tt> that the source failed
+ *<tt>Message</tt> was sent to.
+ */
+ public Contact getDestinationParticipant()
+ {
+ return to;
+ }
+
+ /**
+ * Returns the received message.
+ * @return the<tt>Message</tt> that triggered this event.
+ */
+ public Message getMessage()
+ {
+ return message;
+ }
+
+ /**
+ * Returns an error code descibing the reason for the failure of the
+ * message delivery.
+ * @return an error code descibing the reason for the failure of the
+ * message delivery.
+ */
+ public int getErrorCode()
+ {
+ return errorCode;
+ }
+
+ /**
+ * A timestamp indicating the exact date when the event ocurred (in this
+ * case it is the moment when it was determined that message delivery
+ * has failed).
+ * @return a Date indicating when the event ocurred.
+ */
+ public Date getTimestamp()
+ {
+ return timestamp;
+ }
+
+ /**
+ * Returns the<tt>AdHocChatRoom</tt> that triggered this event.
+ * @return the<tt>AdHocChatRoom</tt> that triggered this event.
+ */
+ public AdHocChatRoom getSourceChatRoom()
+ {
+ return (AdHocChatRoom) getSource();
+ }
+}

Added: trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageListener.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageListener.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageListener.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,46 @@
+/*
+ * 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.service.protocol.event;
+
+import java.util.*;
+
+/**
+ * A listener that registers for<tt>AdHocChatRoomMessageEvent</tt>s issued by a
+ * particular<tt>AdHocChatRoom</tt>.
+ *
+ * @author Valentin Martinet
+ */
+public interface AdHocChatRoomMessageListener
+ extends EventListener
+{
+ /**
+ * Called when a new incoming<tt>Message</tt> has been received.
+ * @param evt the<tt>AdHocChatRoomMessageReceivedEvent</tt> containing the
+ * newly received message, its sender and other details.
+ */
+ public void messageReceived(AdHocChatRoomMessageReceivedEvent evt);
+
+ /**
+ * Called when the underlying implementation has received an indication
+ * that a message, sent earlier has been successfully received by the
+ * destination.
+ * @param evt the<tt>AdHocChatRoomMessageDeliveredEvent</tt> containing the
+ * id of the message that has caused the event.
+ */
+ public void messageDelivered(AdHocChatRoomMessageDeliveredEvent evt);
+
+ /**
+ * Called to indicate that delivery of a message sent earlier to the chat
+ * room has failed. Reason code and phrase are contained by the
+ *<tt>MessageFailedEvent</tt>
+ * @param evt the<tt>AdHocChatroomMessageDeliveryFailedEvent</tt>
+ * containing the ID of the message whose delivery has failed.
+ */
+ public void messageDeliveryFailed(
+ AdHocChatRoomMessageDeliveryFailedEvent evt);
+}

Added: trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageReceivedEvent.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageReceivedEvent.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageReceivedEvent.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,144 @@
+/*
+ * 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.service.protocol.event;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ *<tt>MessageReceivedEvent</tt>s indicate reception of an instant message.
+ * (for an ad-hoc chat room; see<tt>AdHocChatRoom</tt>)
+ *
+ * @author Valentin Martinet
+ */
+@SuppressWarnings("serial")
+public class AdHocChatRoomMessageReceivedEvent
+ extends EventObject
+{
+ /**
+ * An event type indicating that the message being received is a standard
+ * conversation message sent by another member of the chatroom to all
+ * current participants.
+ */
+ public static final int CONVERSATION_MESSAGE_RECEIVED = 1;
+
+ /**
+ * An event type indicating that the message being received is a special
+ * message that sent by either another member or the server itself,
+ * indicating that some kind of action (other than the delivery of a
+ * conversation message) has occurred. Action messages are widely used
+ * in IRC through the /action and /me commands
+ */
+ public static final int ACTION_MESSAGE_RECEIVED = 2;
+
+ /**
+ * An event type indicting that the message being received is a system
+ * message being sent by the server or a system administrator, possibly
+ * notifying us of something important such as ongoing maintenance
+ * activities or server downtime.
+ */
+ public static final int SYSTEM_MESSAGE_RECEIVED = 3;
+
+ /**
+ * The ccontact that has sent this message.
+ */
+ private final Contact from;
+
+ /**
+ * A timestamp indicating the exact date when the event occurred.
+ */
+ private final long timestamp;
+
+ /**
+ * The received<tt>Message</tt>.
+ */
+ private final Message message;
+
+ /**
+ * The type of message event that this instance represents.
+ */
+ private final int eventType;
+
+ /**
+ * Creates a<tt>MessageReceivedEvent</tt> representing reception of the
+ *<tt>source</tt> message received from the specified<tt>from</tt>
+ * contact.
+ *
+ * @param source the<tt>AdHocChatRoom</tt> for which the message is
+ * received.
+ * @param from the<tt>Contact</tt> that has sent this message.
+ * @param timestamp the exact date when the event occurred.
+ * @param message the received<tt>Message</tt>.
+ * @param eventType the type of message event that this instance represents
+ * (one of the XXX_MESSAGE_RECEIVED static fields).
+ */
+ public AdHocChatRoomMessageReceivedEvent(AdHocChatRoom source,
+ Contact from,
+ long timestamp,
+ Message message,
+ int eventType)
+ {
+ super(source);
+
+ this.from = from;
+ this.timestamp = timestamp;
+ this.message = message;
+ this.eventType = eventType;
+ }
+
+ /**
+ * Returns a reference to the<tt>Contact</tt> that has send the
+ *<tt>Message</tt> whose reception this event represents.
+ *
+ * @return a reference to the<tt>Contact</tt> that has send the
+ *<tt>Message</tt> whose reception this event represents.
+ */
+ public Contact getSourceChatRoomParticipant()
+ {
+ return from;
+ }
+
+ /**
+ * Returns the received message.
+ * @return the<tt>Message</tt> that triggered this event.
+ */
+ public Message getMessage()
+ {
+ return message;
+ }
+
+ /**
+ * A timestamp indicating the exact date when the event occurred.
+ * @return a Date indicating when the event occurred.
+ */
+ public long getTimestamp()
+ {
+ return timestamp;
+ }
+
+ /**
+ * Returns the<tt>AdHocChatRoom</tt> that triggered this event.
+ * @return the<tt>AdHocChatRoom</tt> that triggered this event.
+ */
+ public AdHocChatRoom getSourceChatRoom()
+ {
+ return (AdHocChatRoom) getSource();
+ }
+
+ /**
+ * Returns the type of message event represented by this event instance.
+ * Message event type is one of the XXX_MESSAGE_RECEIVED fields of this
+ * class.
+ * @return one of the XXX_MESSAGE_RECEIVED fields of this
+ * class indicating the type of this event.
+ */
+ public int getEventType()
+ {
+ return eventType;
+ }
+}

Added: trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomParticipantPresenceChangeEvent.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomParticipantPresenceChangeEvent.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomParticipantPresenceChangeEvent.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,157 @@
+/*
+ * 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.service.protocol.event;
+
+import java.util.*;
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * Dispatched to notify interested parties that a change in the presence of an
+ * ad-hoc chat room participant has occurred. Changes may include the
+ * participant being join, left...
+ *
+ * @author Valentin Martinet
+ */
+@SuppressWarnings("serial")
+public class AdHocChatRoomParticipantPresenceChangeEvent
+ extends EventObject
+{
+ /**
+ * Indicates that this event was triggered as a result of the participant
+ * joining the source ad-hoc chat room.
+ */
+ public static final String CONTACT_JOINED = "ContactJoined";
+
+ /**
+ * Indicates that this event was triggered as a result of the participant
+ * leaving the source ad-hoc chat room.
+ */
+ public static final String CONTACT_LEFT = "ContactLeft";
+
+ /**
+ * Indicates that this event was triggered as a result of the participant
+ * being disconnected from the server brutally, or due to a ping timeout.
+ */
+ public static final String CONTACT_QUIT = "ContactQuit";
+
+ /**
+ * The well-known reason for a
+ *<code>AdHocChatRoomParticipantPresenceChangeEvent</code> to occur as part
+ * of an operation which lists all users in an<code>AdHocChatRoom</code>.
+ */
+ public static final String REASON_USER_LIST = "ReasonUserList";
+
+ /**
+ * The ad-hoc chat room participant that the event relates to.
+ */
+ private final Contact sourceParticipant;
+
+ /**
+ * The type of this event. Values can be any of the CONTACT_XXX fields.
+ */
+ private final String eventType;
+
+ /**
+ * An optional String indicating a possible reason as to why the event
+ * might have occurred.
+ */
+ private final String reason;
+
+ /**
+ * Creates an<tt>AdHocChatRoomParticipantPresenceChangeEvent</tt>
+ * representing that a change in the presence of an<tt>Contact</tt>
+ * has occurred. Changes may include the participant being join, left, etc.
+ *
+ * @param sourceAdHocRoom the<tt>AdHocChatRoom</tt> that produced this
+ * event
+ * @param sourceParticipant the<tt>Contact</tt> that this event is about
+ * @param eventType the event type; one of the CONTACT_XXX constants
+ * @param reason the reason explaining why this event might have occurred
+ */
+ public AdHocChatRoomParticipantPresenceChangeEvent(
+ AdHocChatRoom sourceAdHocRoom,
+ Contact sourceParticipant,
+ String eventType,
+ String reason )
+ {
+ super(sourceAdHocRoom);
+ this.sourceParticipant = sourceParticipant;
+ this.eventType = eventType;
+ this.reason = reason;
+ }
+
+ /**
+ * Returns the ad-hoc chat room that produced this event.
+ *
+ * @return the<tt>AdHocChatRoom</tt> that produced this event
+ */
+ public AdHocChatRoom getAdHocChatRoom()
+ {
+ return (AdHocChatRoom)getSource();
+ }
+
+ /**
+ * Returns the participant that this event is about.
+ *
+ * @return the<tt>Contact</tt> that this event is about.
+ */
+ public Contact getParticipant()
+ {
+ return this.sourceParticipant;
+ }
+
+ /**
+ * A reason String indicating a human readable reason for this event.
+ *
+ * @return a human readable String containing the reason for this event,
+ * or null if no particular reason was specified.
+ */
+ public String getReason()
+ {
+ return this.reason;
+ }
+
+ /**
+ * Gets the indicator which determines whether this event has occurred with
+ * the well-known reason of listing all users in a<code>ChatRoom</code>.
+ *
+ * @return<tt>true</tt> if this event has occurred with the well-known
+ * reason of listing all users in a<code>ChatRoom</code> i.e.
+ * {@link #getReason()} returns a value of {@link #REASON_USER_LIST};
+ * otherwise,<tt>false</tt>
+ */
+ public boolean isReasonUserList()
+ {
+ return REASON_USER_LIST.equals(getReason());
+ }
+
+ /**
+ * Returns the type of this event which could be one of the MEMBER_XXX
+ * member field values.
+ *
+ * @return one of the MEMBER_XXX member field values indicating the type
+ * of this event.
+ */
+ public String getEventType()
+ {
+ return eventType;
+ }
+
+ /**
+ * Returns a String representation of this event.
+ */
+ public String toString()
+ {
+ return "AdHocChatRoomParticipantPresenceChangeEvent[type="
+ + getEventType()
+ + " sourceAdHocRoom="
+ + getAdHocChatRoom().toString()
+ + " member="
+ + getParticipant().toString()
+ + "]";
+ }
+}

Added: trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomParticipantPresenceListener.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomParticipantPresenceListener.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomParticipantPresenceListener.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,32 @@
+/*
+ * 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.service.protocol.event;
+
+import java.util.*;
+
+/**
+ * A listener that will be notified of changes in the presence of a participant
+ * in a particular ad-hoc chat room. Changes may include member being join,
+ * left, etc.
+ *
+ * @author Valentin Martinet
+ */
+public interface AdHocChatRoomParticipantPresenceListener
+ extends EventListener
+{
+ /**
+ * Called to notify interested parties that a change in the presence of a
+ * participant in a particular ad-hoc chat room has occurred. Changes may
+ * include participant being join, left.
+ *
+ * @param evt the<tt>AdHocChatRoomParticipantPresenceChangeEvent</tt>
+ * instance containing the source chat room and type, and reason of the
+ * presence change
+ */
+ public void participantPresenceChanged(
+ AdHocChatRoomParticipantPresenceChangeEvent evt);
+}
\ No newline at end of file

Added: trunk/src/net/java/sip/communicator/service/protocol/event/LocalUserAdHocChatRoomPresenceChangeEvent.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/event/LocalUserAdHocChatRoomPresenceChangeEvent.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/event/LocalUserAdHocChatRoomPresenceChangeEvent.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,145 @@
+/*
+ * 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.service.protocol.event;
+
+import java.util.*;
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * Dispatched to notify interested parties that a change in our presence in
+ * the source ad-hoc chat room has occurred. Changes may include us being join,
+ * left, etc.
+ *
+ * @author Valentin Martinet
+ */
+@SuppressWarnings("serial")
+public class LocalUserAdHocChatRoomPresenceChangeEvent
+ extends EventObject
+{
+ /**
+ * Indicates that this event was triggered as a result of the local
+ * participant joining an ad-hoc chat room.
+ */
+ public static final String LOCAL_USER_JOINED = "LocalUserJoined";
+
+ /**
+ * Indicates that this event was triggered as a result of the local
+ * participant failed to join an ad-hoc chat room.
+ */
+ public static final String LOCAL_USER_JOIN_FAILED = "LocalUserJoinFailed";
+
+ /**
+ * Indicates that this event was triggered as a result of the local
+ * participant leaving an ad-hoc chat room.
+ */
+ public static final String LOCAL_USER_LEFT = "LocalUserLeft";
+
+ /**
+ * Indicates that this event was triggered as a result of the local
+ * participant being disconnected from the server brutally, or ping timeout.
+ */
+ public static final String LOCAL_USER_DROPPED = "LocalUserDropped";
+
+ /**
+ * The<tt>AdHocChatRoom</tt> to which the change is related.
+ */
+ private AdHocChatRoom adHocChatRoom = null;
+
+ /**
+ * The type of this event.
+ */
+ private String eventType = null;
+
+ /**
+ * An optional String indicating a possible reason as to why the event
+ * might have occurred.
+ */
+ private String reason = null;
+
+ /**
+ * Creates an<tt>AdHocChatRoomLocalUserPresenceChangeEvent</tt>
+ * representing that a change in local participant presence in the source
+ * ad-hoc chat room has occurred.
+ *
+ * @param _source the<tt>OperationSetAdHocMultiUserChat</tt>, which
+ * produced this event
+ * @param _adHocChatRoom the<tt>AdHocChatRoom</tt> that this event is about
+ * @param _eventType the type of this event.
+ * @param _reason the reason explaining why this event might have occurred
+ */
+ public LocalUserAdHocChatRoomPresenceChangeEvent(
+ OperationSetAdHocMultiUserChat source,
+ AdHocChatRoom adHocChatRoom,
+ String eventType,
+ String reason)
+ {
+ super(source);
+
+ this.adHocChatRoom = adHocChatRoom;
+ this.eventType = eventType;
+ this.reason = reason;
+ }
+
+ /**
+ * Returns the<tt>OperationSetAdHocMultiUserChat</tt>, where this event has
+ * occurred.
+ *
+ * @return the<tt>OperationSetAdHocMultiUserChat</tt>, where this event has
+ * occurred
+ */
+ public OperationSetAdHocMultiUserChat getAdHocMultiUserChatOpSet()
+ {
+ return (OperationSetAdHocMultiUserChat) getSource();
+ }
+
+ /**
+ * Returns the<tt>AdHocChatRoom</tt>, that this event is about.
+ *
+ * @return the<tt>AdHocChatRoom</tt>, that this event is about
+ */
+ public AdHocChatRoom getAdHocChatRoom()
+ {
+ return this.adHocChatRoom;
+ }
+
+ /**
+ * A reason string indicating a human readable reason for this event.
+ *
+ * @return a human readable String containing the reason for this event,
+ * or null if no particular reason was specified
+ */
+ public String getReason()
+ {
+ return this.reason;
+ }
+
+ /**
+ * Returns the type of this event which could be one of the LOCAL_USER_XXX
+ * member fields.
+ *
+ * @return one of the LOCAL_USER_XXX fields indicating the type of this
+ * event.
+ */
+ public String getEventType()
+ {
+ return this.eventType;
+ }
+
+ /**
+ * Returns a String representation of this event.
+ *
+ * @return a<tt>String</tt> for representing this event.
+ */
+ public String toString()
+ {
+ return "AdHocChatRoomLocalUserPresenceChangeEvent[type="
+ + getEventType()
+ + " \nsourceAdHocRoom="
+ + getAdHocChatRoom().toString()
+ + "]";
+ }
+}

Added: trunk/src/net/java/sip/communicator/service/protocol/event/LocalUserAdHocChatRoomPresenceListener.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/event/LocalUserAdHocChatRoomPresenceListener.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/event/LocalUserAdHocChatRoomPresenceListener.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,30 @@
+ /*
+ * 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.service.protocol.event;
+
+import java.util.*;
+
+/**
+ * A listener that will be notified of changes in our presence in the chat
+ * room such as us being kicked, join, left.
+ *
+ * @author Valentin Martinet
+ */
+public interface LocalUserAdHocChatRoomPresenceListener
+ extends EventListener
+{
+ /**
+ * Called to notify interested parties that a change in our presence in
+ * an ad-hoc chat room has occurred. Changes may include us being join,
+ * left.
+ * @param _evt the<tt>LocalUserAdHocChatRoomPresenceChangeEvent</tt>
+ * instance containing the ad-hoc chat room and the type, and reason of the
+ * change
+ */
+ public void localUserAdHocPresenceChanged(
+ LocalUserAdHocChatRoomPresenceChangeEvent evt);
+}

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@sip-communicator.dev.java.net
For additional commands, e-mail: dev-help@sip-communicator.dev.java.net


#2

Hi Lubo,

You're absolutely right. Thanks for taking care of this!

Cheers,
Yana

···

On Sep 15, 2009, at 10:26 AM, Lubomir Marinov wrote:

Hello Valentin and Yana,

Congratulations on the great work! I do mean not only the large amount of code written but also the continuous dedication which was expressed on this mailing list in the respective thread. You rock!

I hope you will not mind me sharing a few observations while reviewing r5964.

I still haven't finished the review so I'll just start with ChatAlerterActivator and its new method #messageReceived(AdHocChatRoomMessageReceivedEvent). The problem is that the implementation of this method is anything but new. This same implementation was already found in two separate methods in this same class and I replaced the duplication with #alertChatWindow(). I imagine the copy was made while there was still a duplication in trunk (which turns out to be called triplication) but it's still not a reason to do it. Please note that having three methods that do one and the same thing makes a class larger than necessary, hinders maintenance because changes to it has to be performed multiple times (you may notice that I've spared two null checks in #alertChatWindow()) and, most importantly, each of them needs to pass the JIT compiler invocation threshold before the decision is taken for them to be compiled into native code (in contrast replacing these three methods with #alertChatWindow() provides an optimization for all three regardless of which one is called the most often).

Best regards,
Lubomir

On 14.09.2009 18:51, yanas@dev.java.net wrote:

Author: yanas
Date: 2009-09-14 15:51:47+0000
New Revision: 5964

Added:
   trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocChatRoomProviderWrapper.java
   trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocChatRoomWrapper.java
   trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocConferenceChatContact.java
   trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocConferenceChatSession.java
   trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocConferenceChatTransport.java
   trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/AdHocChatRoomList.java
   trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/AdHocChatRoomListChangeEvent.java
   trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/AdHocChatRoomListChangeListener.java
   trunk/src/net/java/sip/communicator/impl/protocol/icq/AdHocChatRoomIcqImpl.java
   trunk/src/net/java/sip/communicator/impl/protocol/icq/AdHocChatRoomInvitationIcqImpl.java
   trunk/src/net/java/sip/communicator/impl/protocol/icq/OperationSetAdHocMultiUserChatIcqImpl.java
   trunk/src/net/java/sip/communicator/impl/protocol/msn/AdHocChatRoomInvitationMsnImpl.java (contents, props changed)
      - copied, changed from r5898, /trunk/src/net/java/sip/communicator/impl/protocol/msn/ChatRoomInvitationMsnImpl.java
   trunk/src/net/java/sip/communicator/impl/protocol/msn/AdHocChatRoomMsnImpl.java
   trunk/src/net/java/sip/communicator/impl/protocol/msn/OperationSetAdHocMultiUserChatMsnImpl.java
   trunk/src/net/java/sip/communicator/impl/protocol/yahoo/AdHocChatRoomInvitationYahooImpl.java
   trunk/src/net/java/sip/communicator/impl/protocol/yahoo/AdHocChatRoomYahooImpl.java
   trunk/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetAdHocMultiUserChatYahooImpl.java
   trunk/src/net/java/sip/communicator/service/protocol/AdHocChatRoom.java
   trunk/src/net/java/sip/communicator/service/protocol/AdHocChatRoomInvitation.java
   trunk/src/net/java/sip/communicator/service/protocol/OperationSetAdHocMultiUserChat.java
   trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomCreatedEvent.java
   trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomDestroyedEvent.java
   trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationListener.java
   trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationReceivedEvent.java
   trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationRejectedEvent.java
   trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationRejectionListener.java
   trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomListener.java
   trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageDeliveredEvent.java
   trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageDeliveryFailedEvent.java
   trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageListener.java
   trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageReceivedEvent.java
   trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomParticipantPresenceChangeEvent.java
   trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomParticipantPresenceListener.java
   trunk/src/net/java/sip/communicator/service/protocol/event/LocalUserAdHocChatRoomPresenceChangeEvent.java
   trunk/src/net/java/sip/communicator/service/protocol/event/LocalUserAdHocChatRoomPresenceListener.java
Removed:
   trunk/src/net/java/sip/communicator/impl/protocol/icq/ChatRoomIcqImpl.java
   trunk/src/net/java/sip/communicator/impl/protocol/icq/ChatRoomInvitationIcqImpl.java
   trunk/src/net/java/sip/communicator/impl/protocol/icq/ChatRoomMemberIcqImpl.java
   trunk/src/net/java/sip/communicator/impl/protocol/icq/OperationSetMultiUserChatIcqImpl.java
   trunk/src/net/java/sip/communicator/impl/protocol/msn/ChatRoomInvitationMsnImpl.java
   trunk/src/net/java/sip/communicator/impl/protocol/msn/ChatRoomMemberMsnImpl.java
   trunk/src/net/java/sip/communicator/impl/protocol/msn/ChatRoomMsnImpl.java
   trunk/src/net/java/sip/communicator/impl/protocol/msn/OperationSetMultiUserChatMsnImpl.java
   trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ChatRoomInvitationYahooImpl.java
   trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ChatRoomMemberYahooImpl.java
   trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ChatRoomYahooImpl.java
   trunk/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetMultiUserChatYahooImpl.java
Modified:
   trunk/src/net/java/sip/communicator/impl/gui/main/MainFrame.java
   trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java
   trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindow.java
   trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindowManager.java
   trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatContact.java
   trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatManager.java
   trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/InvitationReceivedDialog.java
   trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomList.java
   trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomListUI.java
   trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/createforms/CreateChatRoomDialog.java
   trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/createforms/CreateChatRoomWizard.java
   trunk/src/net/java/sip/communicator/impl/gui/main/login/LoginManager.java
   trunk/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java
   trunk/src/net/java/sip/communicator/impl/protocol/facebook/FacebookUser.java
   trunk/src/net/java/sip/communicator/impl/protocol/icq/ProtocolProviderServiceIcqImpl.java
   trunk/src/net/java/sip/communicator/impl/protocol/msn/OperationSetBasicInstantMessagingMsnImpl.java
   trunk/src/net/java/sip/communicator/impl/protocol/msn/ProtocolProviderServiceMsnImpl.java
   trunk/src/net/java/sip/communicator/impl/protocol/sip/SipLogger.java
   trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolProviderServiceYahooImpl.java
   trunk/src/net/java/sip/communicator/plugin/chatalerter/ChatAlerterActivator.java
   trunk/src/net/java/sip/communicator/plugin/contactinfo/resources/personPhoto.png
   trunk/src/net/java/sip/communicator/plugin/contactinfo/resources/userInfo16x16.png
   trunk/src/net/java/sip/communicator/plugin/facebookaccregwizz/FacebookAccountRegistrationWizard.java
   trunk/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java

Log:
Ongoing work on issue #725 ( Sepperate operation set for ad-hoc like chat rooms (Msn, Icq, Yahoo)) provided by Valentin Martinet. Introduces all the interfaces needed to represent an ad-hoc chat room and the corresponding implementations for Msn, Yahoo and Icq.

Also turns some tabs to spaces in the facebookaccregwizz and chatalerter plugins.

Modified: trunk/src/net/java/sip/communicator/impl/gui/main/MainFrame.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/MainFrame.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/gui/main/MainFrame.java&p2=trunk/src/net/java/sip/communicator/impl/gui/main/MainFrame.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/gui/main/MainFrame.java (original)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/MainFrame.java 2009-09-14 15:51:47+0000
@@ -386,6 +386,21 @@
             multiUserChat.addPresenceListener(conferenceManager);
         }

+ // Obtain the ad-hoc multi user chat operation set.
+ OperationSetAdHocMultiUserChat adHocMultiChatOpSet =
+ (OperationSetAdHocMultiUserChat) protocolProvider
+ .getOperationSet(OperationSetAdHocMultiUserChat.class);
+
+ if (adHocMultiChatOpSet != null)
+ {
+ ConferenceChatManager conferenceManager
+ = GuiActivator.getUIService().getConferenceChatManager();
+
+ adHocMultiChatOpSet.addInvitationListener(conferenceManager);
+ adHocMultiChatOpSet.addInvitationRejectionListener(conferenceManager);
+ adHocMultiChatOpSet.addPresenceListener(conferenceManager);
+ }
+
         // Obtain file transfer operation set.
         OperationSetFileTransfer fileTransferOpSet
             = (OperationSetFileTransfer) protocolProvider
@@ -586,6 +601,26 @@
      *
      * @param protocolProvider The protocol provider for which the multi user
      * chat operation set is about.
+ * @return OperationSetAdHocMultiUserChat The telephony operation
+ * set for the given protocol provider.
+ */
+ public OperationSetAdHocMultiUserChat getAdHocMultiUserChatOpSet(
+ ProtocolProviderService protocolProvider)
+ {
+ OperationSet opSet
+ = protocolProvider.getOperationSet(
+ OperationSetAdHocMultiUserChat.class);
+
+ return (opSet instanceof OperationSetAdHocMultiUserChat)
+ ? (OperationSetAdHocMultiUserChat) opSet
+ : null;
+ }
+
+ /**
+ * Returns the multi user chat operation set for the given protocol provider.
+ *
+ * @param protocolProvider The protocol provider for which the multi user
+ * chat operation set is about.
      * @return OperationSetMultiUserChat The telephony operation
      * set for the given protocol provider.
      */

Modified: trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java&p2=trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java (original)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java 2009-09-14 15:51:47+0000
@@ -780,7 +780,8 @@
     /**
      * Pastes the content of the clipboard to the write area.
      */
- public void paste(){
+ public void paste()
+ {
         JEditorPane editorPane = this.writeMessagePanel.getEditorPane();

         editorPane.paste();
@@ -1808,11 +1809,18 @@
         ChatTransport currentChatTransport
             = chatSession.getCurrentChatTransport();

- if (currentChatTransport.getProtocolProvider()
- .getOperationSet(OperationSetMultiUserChat.class) != null)
+ ProtocolProviderService protocolProvider
+ = currentChatTransport.getProtocolProvider();
+
+ // We choose between OpSets for multi user chat...
+ if (protocolProvider.getOperationSet(
+ OperationSetMultiUserChat.class) != null
+ || protocolProvider.getOperationSet(
+ OperationSetAdHocMultiUserChat.class) != null)
         {
             return chatSession.getCurrentChatTransport();
         }
+
         else
         {
             Iterator<ChatTransport> chatTransportsIter
@@ -1838,7 +1846,7 @@
                                 Collection<String> chatContacts,
                                 String reason)
     {
- ChatSession conferenceChatSession;
+ ChatSession conferenceChatSession = null;

         if (chatSession instanceof MetaContactChatSession)
         {
@@ -1849,14 +1857,31 @@
             ConferenceChatManager conferenceChatManager
                 = GuiActivator.getUIService().getConferenceChatManager();

- ChatRoomWrapper chatRoomWrapper
- = conferenceChatManager.createChatRoom(newChatName,
- inviteChatTransport.getProtocolProvider());
+ // the chat session is set regarding to which OpSet is used for MUC
+ if(inviteChatTransport.getProtocolProvider().
+ getOperationSet(OperationSetMultiUserChat.class) != null)
+ {
+ ChatRoomWrapper chatRoomWrapper
+ = conferenceChatManager.createChatRoom(newChatName,
+ inviteChatTransport.getProtocolProvider(), chatContacts);

- conferenceChatSession
- = new ConferenceChatSession(this, chatRoomWrapper);
+ conferenceChatSession
+ = new ConferenceChatSession(this, chatRoomWrapper);
+ }
+ else if (inviteChatTransport.getProtocolProvider().
+ getOperationSet(OperationSetAdHocMultiUserChat.class) != null)
+ {
+ AdHocChatRoomWrapper chatRoomWrapper
+ = conferenceChatManager.createAdHocChatRoom(newChatName,
+ inviteChatTransport.getProtocolProvider(),
+ chatContacts);
+
+ conferenceChatSession
+ = new AdHocConferenceChatSession(this, chatRoomWrapper);
+ }

- this.setChatSession(conferenceChatSession);
+ if (conferenceChatSession != null)
+ this.setChatSession(conferenceChatSession);
         }
         // We're already in a conference chat.
         else

Modified: trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindow.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindow.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindow.java&p2=trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindow.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindow.java (original)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindow.java 2009-09-14 15:51:47+0000
@@ -460,7 +460,7 @@
         mainToolBar.changeHistoryButtonsState(chatPanel);

         chatPanel.requestFocusInWriteArea();
-
+
         for (ChatChangeListener l : this.chatChangeListeners)
         {
             l.chatChanged(chatPanel);

Modified: trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindowManager.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindowManager.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindowManager.java&p2=trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindowManager.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindowManager.java (original)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindowManager.java 2009-09-14 15:51:47+0000
@@ -23,6 +23,7 @@
  * Manages chat windows and panels.
  *
  * @author Yana Stamcheva
+ * @author Valentin Martinet
  */
public class ChatWindowManager
{
@@ -123,6 +124,27 @@
                 && getChat(chatSession).isShown());
         }
     }
+
+ /**
+ * Returns TRUE if there is an opened<tt>ChatPanel</tt> for the given
+ *<tt>AdHocChatRoom</tt>.
+ * @param chatRoomWrapper the<tt>AdHocChatRoomWrapper</tt>, for which the
+ * ad-hoc chat is about
+ * @return TRUE if there is an opened<tt>ChatPanel</tt> for the given
+ *<tt>AdHocChatRoom</tt>
+ */
+ public boolean isChatOpenedForAdHocChatRoom(
+ AdHocChatRoomWrapper adHocChatRoomWrapper)
+ {
+ synchronized (syncChat)
+ {
+ ChatSession chatSession
+ = findChatSessionForDescriptor(adHocChatRoomWrapper);
+
+ return (chatSession != null
+&& getChat(chatSession).isShown());
+ }
+ }

     /**
      * Returns TRUE if there is an opened<tt>ChatPanel</tt> for the given
@@ -178,6 +200,43 @@
             return false;
         }
     }
+
+ /**
+ * Returns TRUE if there is an opened<tt>ChatPanel</tt> for the given
+ *<tt>AdHocChatRoom</tt>.
+ *
+ * @param adHocChatRoom the<tt>AdHocChatRoom</tt>, for which the ad-hoc
+ * chat is about
+ * @return TRUE if there is an opened<tt>ChatPanel</tt> for the given
+ *<tt>AdHocChatRoom</tt>
+ */
+ public boolean isChatOpenedForAdHocChatRoom(AdHocChatRoom adHocChatRoom)
+ {
+ synchronized (syncChat)
+ {
+ for (ChatPanel chatPanel : chatPanels)
+ {
+ ChatSession chatSession = chatPanel.getChatSession();
+
+ Object descriptor = chatSession.getDescriptor();
+
+ if(descriptor instanceof AdHocChatRoomWrapper)
+ {
+ AdHocChatRoomWrapper chatRoomWrapper
+ = (AdHocChatRoomWrapper) descriptor;
+
+ if(chatRoomWrapper.getAdHocChatRoomID()
+ .equals(adHocChatRoom.getIdentifier())
+&& getChat(chatSession).isShown())
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+ }

     /**
      * Closes the given chat panel.
@@ -252,6 +311,11 @@
                         closeChatPanel(chatPanel);
                     }
                 }
+ else if (chatPanel.getChatSession() instanceof
+ AdHocConferenceChatSession)
+ {
+ // TODO: close the chat room before closing the window!!!
+ }
                 else
                 {
                     closeChatPanel(chatPanel);
@@ -476,7 +540,7 @@
         synchronized (syncChat)
         {
             ChatSession chatSession
- = findChatSessionForDescriptor(chatRoomWrapper);
+ = findChatSessionForDescriptor(chatRoomWrapper);

             if(chatSession != null)
             {
@@ -484,8 +548,42 @@
             }
             else
                 return createChat(chatRoomWrapper);
+ }
+ }
+
+ /**
+ * Returns the chat panel corresponding to the given chat room wrapper.
+ *
+ * @param chatRoomWrapper the ad-hoc chat room wrapper, corresponding to the
+ * ad-hoc chat room for which the chat panel is about
+ * @return the chat panel corresponding to the given chat room
+ */
+ public ChatPanel getAdHocMultiChat(AdHocChatRoomWrapper chatRoomWrapper)
+ {
+ synchronized (syncChat)
+ {
+ ChatSession chatSession
+ = findChatSessionForDescriptor(chatRoomWrapper);
+
+ if(chatSession != null)
+ {
+ return getChat(chatSession);
             }
+ else
+ return createChat(chatRoomWrapper);
         }
+ }
+
+ /**
+ * Returns the chat panel corresponding to the given ad-hoc chat room.
+ *
+ * @param adHocChatRoom the chat room, for which the chat panel is about
+ * @return the chat panel corresponding to the given ad-hoc chat room
+ */
+ public ChatPanel getAdHocMultiChat(AdHocChatRoom adHocChatRoom)
+ {
+ return getAdHocMultiChat(adHocChatRoom, null);
+ }

     /**
      * Returns the chat panel corresponding to the given chat room.
@@ -543,6 +641,51 @@
     }

     /**
+ * Returns the chat panel corresponding to the given ad-hoc chat room.
+ *
+ * @param chatRoom the ad-hoc chat room, for which the chat panel is about
+ * @param escapedMessageID the message ID of the message that should be
+ * excluded from the history when the last one is loaded in the chat
+ * @return the chat panel corresponding to the given ad-hoc chat room
+ */
+ public ChatPanel getAdHocMultiChat( AdHocChatRoom chatRoom,
+ String escapedMessageID)
+ {
+ synchronized (syncChat)
+ {
+ AdHocChatRoomList chatRoomList = GuiActivator.getUIService()
+ .getConferenceChatManager().getAdHocChatRoomList();
+
+ // Search in the chat room's list for a chat room that correspond
+ // to the given one.
+ AdHocChatRoomWrapper chatRoomWrapper
+ = chatRoomList.findChatRoomWrapperFromAdHocChatRoom(chatRoom);
+
+ if (chatRoomWrapper == null)
+ {
+ AdHocChatRoomProviderWrapper parentProvider
+ = chatRoomList.findServerWrapperFromProvider(
+ chatRoom.getParentProvider());
+
+ chatRoomWrapper =
+ new AdHocChatRoomWrapper(parentProvider, chatRoom);
+
+ chatRoomList.addAdHocChatRoom(chatRoomWrapper);
+ }
+
+ ChatSession chatSession
+ = findChatSessionForDescriptor(chatRoomWrapper);
+
+ if (chatSession != null)
+ {
+ return getChat(chatSession);
+ }
+
+ return createChat(chatRoomWrapper, escapedMessageID);
+ }
+ }
+
+ /**
      * Returns all open<code>ChatPanel</code>s.
      *
      * @return A list of<code>ChatPanel</code>s
@@ -710,10 +853,24 @@
      * Creates a<tt>ChatPanel</tt> for the given<tt>ChatRoom</> and saves it
      * in the list of created<tt>ChatPanel</tt>s.
      *
- * @param chatRoomWrapper the<tt>ChatRoom</tt>, for which the chat will be created
+ * @param chatRoomWrapper the<tt>ChatRoom</tt>, for which the chat will be
+ * created
+ * @return The<code>ChatPanel</code> newly created.
+ */
+ private ChatPanel createChat(ChatRoomWrapper chatRoomWrapper)
+ {
+ return createChat(chatRoomWrapper, null);
+ }
+
+ /**
+ * Creates a<tt>ChatPanel</tt> for the given<tt>AdHocChatRoom</tt> and
+ * saves it in the list of created<tt>ChatPanel</tt>s.
+ *
+ * @param chatRoomWrapper the<tt>AdHocChatRoom</tt>, for which the chat
+ * will be created
      * @return The<code>ChatPanel</code> newly created.
      */
- private ChatPanel createChat( ChatRoomWrapper chatRoomWrapper)
+ private ChatPanel createChat(AdHocChatRoomWrapper chatRoomWrapper)
     {
         return createChat(chatRoomWrapper, null);
     }
@@ -722,7 +879,8 @@
      * Creates a<tt>ChatPanel</tt> for the given<tt>ChatRoom</> and saves it
      * in the list of created<tt>ChatPanel</tt>s.
      *
- * @param chatRoomWrapper the<tt>ChatRoom</tt>, for which the chat will be created
+ * @param chatRoomWrapper the<tt>ChatRoom</tt>, for which the chat will be
+ * created
      * @param escapedMessageID the message ID of the message that should be
      * excluded from the history when the last one is loaded in the chat.
      * @return The<code>ChatPanel</code> newly created.
@@ -780,6 +938,67 @@
     }

     /**
+ * Creates a<tt>ChatPanel</tt> for the given<tt>AdHocChatRoom</tt> and
+ * saves it in the list of created<tt>ChatPanel</tt>s.
+ *
+ * @param chatRoomWrapper the<tt>AdHocChatRoom</tt>, for which the chat
+ * will be created
+ * @param escapedMessageID the message ID of the message that should be
+ * excluded from the history when the last one is loaded in the chat.
+ * @return The<code>ChatPanel</code> newly created.
+ */
+ private ChatPanel createChat( AdHocChatRoomWrapper chatRoomWrapper,
+ String escapedMessageID)
+ {
+ ChatWindow chatWindow;
+
+ if(ConfigurationManager.isMultiChatWindowEnabled())
+ {
+ Iterator<ChatPanel> chatPanelsIter = chatPanels.iterator();
+
+ // If we're in a tabbed window we're looking for the chat window
+ // through one of the already created chats.
+ if(chatPanelsIter.hasNext())
+ {
+ chatWindow = chatPanelsIter.next().getChatWindow();
+ }
+ else
+ {
+ chatWindow = new ChatWindow();
+
+ GuiActivator.getUIService()
+ .registerExportedWindow(chatWindow);
+ }
+ }
+ else
+ {
+ chatWindow = new ChatWindow();
+ }
+
+ ChatPanel chatPanel = new ChatPanel(chatWindow);
+
+ AdHocConferenceChatSession chatSession
+ = new AdHocConferenceChatSession(chatPanel, chatRoomWrapper);
+
+ chatPanel.setChatSession(chatSession);
+
+ synchronized (chatPanels)
+ {
+ this.chatPanels.add(chatPanel);
+ }
+
+ if (ConfigurationManager.isHistoryShown())
+ {
+ if(escapedMessageID != null)
+ chatPanel.loadHistory(escapedMessageID);
+ else
+ chatPanel.loadHistory();
+ }
+
+ return chatPanel;
+ }
+
+ /**
      * Finds the chat session corresponding to the given chat descriptor.
      *
      * @param descriptor The chat descriptor.
@@ -790,7 +1009,6 @@
         for (ChatPanel chatPanel : chatPanels)
         {
             ChatSession chatSession = chatPanel.getChatSession();
-
             if (chatSession.getDescriptor().equals(descriptor))
                 return chatSession;
         }
@@ -817,9 +1035,9 @@
     /**
      * Returns the<tt>ChatPanel</tt> corresponding to the given meta contact.
      *
- * @param chatSession the key, which corresponds to the chat we are looking for. It
- * could be a<tt>MetaContact</tt> in the case of single user chat and
- * a<tt>ChatRoom</tt> in the case of a multi user chat
+ * @param chatSession the key, which corresponds to the chat we are looking
+ * for. It could be a<tt>MetaContact</tt> in the case of single user chat
+ * and a<tt>ChatRoom</tt> in the case of a multi user chat
      * @return the<tt>ChatPanel</tt> corresponding to the given meta contact
      */
     private ChatPanel getChat(ChatSession chatSession)

Added: trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocChatRoomProviderWrapper.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocChatRoomProviderWrapper.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocChatRoomProviderWrapper.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,234 @@
+/*
+ * 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.chat.conference;
+
+import java.util.*;
+
+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.*;
+
+/**
+ * @author Valentin Martinet
+ */
+public class AdHocChatRoomProviderWrapper
+{
+ private static final Logger logger
+ = Logger.getLogger(AdHocChatRoomProviderWrapper.class);
+
+ private final ProtocolProviderService protocolProvider;
+
+ private final List<AdHocChatRoomWrapper> chatRoomsOrderedCopy
+ = new LinkedList<AdHocChatRoomWrapper>();
+
+ /**
+ * Creates an instance of<tt>AdHocChatRoomProviderWrapper</> by
+ * specifying the protocol provider, corresponding to the ad-hoc multi user
+ * chat account.
+ *
+ * @param protocolProvider protocol provider, corresponding to the ad-hoc
+ * multi user chat account.
+ */
+ public AdHocChatRoomProviderWrapper(
+ ProtocolProviderService protocolProvider)
+ {
+ this.protocolProvider = protocolProvider;
+ }
+
+ /**
+ * Returns the name of this ad-hoc chat room provider.
+ * @return the name of this ad-hoc chat room provider.
+ */
+ public String getName()
+ {
+ return protocolProvider.getProtocolDisplayName();
+ }
+
+ public byte[] getIcon()
+ {
+ return protocolProvider.getProtocolIcon()
+ .getIcon(ProtocolIcon.ICON_SIZE_64x64);
+ }
+
+ public byte[] getImage()
+ {
+ byte[] logoImage = null;
+ ProtocolIcon protocolIcon = protocolProvider.getProtocolIcon();
+
+ if(protocolIcon.isSizeSupported(ProtocolIcon.ICON_SIZE_64x64))
+ logoImage = protocolIcon.getIcon(ProtocolIcon.ICON_SIZE_64x64);
+ else if(protocolIcon.isSizeSupported(ProtocolIcon.ICON_SIZE_48x48))
+ logoImage = protocolIcon.getIcon(ProtocolIcon.ICON_SIZE_48x48);
+
+ return logoImage;
+ }
+
+ /**
+ * Returns the protocol provider service corresponding to this server
+ * wrapper.
+ *
+ * @return the protocol provider service corresponding to this server
+ * wrapper.
+ */
+ public ProtocolProviderService getProtocolProvider()
+ {
+ return protocolProvider;
+ }
+
+ /**
+ * Adds the given ad-hoc chat room to this chat room provider.
+ *
+ * @param adHocChatRoom the ad-hoc chat room to add.
+ */
+ public void addAdHocChatRoom(AdHocChatRoomWrapper adHocChatRoom)
+ {
+ this.chatRoomsOrderedCopy.add(adHocChatRoom);
+ }
+
+ /**
+ * Removes the given ad-hoc chat room from this provider.
+ *
+ * @param adHocChatRoom the ad-hoc chat room to remove.
+ */
+ public void removeChatRoom(AdHocChatRoomWrapper adHocChatRoom)
+ {
+ this.chatRoomsOrderedCopy.remove(adHocChatRoom);
+ }
+
+ /**
+ * Returns<code>true</code> if the given ad-hoc chat room is contained in
+ * this provider, otherwise - returns<code>false</code>.
+ *
+ * @param adHocChatRoom the ad-hoc chat room to search for.
+ * @return<code>true</code> if the given ad-hoc chat room is contained in
+ * this provider, otherwise - returns<code>false</code>.
+ */
+ public boolean containsAdHocChatRoom(AdHocChatRoomWrapper adHocChatRoom)
+ {
+ synchronized (chatRoomsOrderedCopy)
+ {
+ return chatRoomsOrderedCopy.contains(adHocChatRoom);
+ }
+ }
+
+ /**
+ * Returns the ad-hoc chat room wrapper contained in this provider that
+ * corresponds to the given ad-hoc chat room.
+ *
+ * @param adHocChatRoom the ad-hoc chat room we're looking for.
+ * @return the ad-hoc chat room wrapper contained in this provider that
+ * corresponds to the given ad-hoc chat room.
+ */
+ public AdHocChatRoomWrapper findChatRoomWrapperForAdHocChatRoom(
+ AdHocChatRoom adHocChatRoom)
+ {
+ // compare ids, cause saved ad-hoc chatrooms don't have AdHocChatRoom
+ // object but Id's are the same
+ for (AdHocChatRoomWrapper chatRoomWrapper : chatRoomsOrderedCopy)
+ {
+ if (chatRoomWrapper.getAdHocChatRoomID().equals(
+ adHocChatRoom.getIdentifier()))
+ {
+ return chatRoomWrapper;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the number of ad-hoc chat rooms contained in this provider.
+ *
+ * @return the number of ad-hoc chat rooms contained in this provider.
+ */
+ public int countAdHocChatRooms()
+ {
+ return chatRoomsOrderedCopy.size();
+ }
+
+ public AdHocChatRoomWrapper getAdHocChatRoom(int index)
+ {
+ return chatRoomsOrderedCopy.get(index);
+ }
+
+ /**
+ * Returns the index of the given chat room in this provider.
+ *
+ * @param chatRoomWrapper the chat room to search for.
+ *
+ * @return the index of the given chat room in this provider.
+ */
+ public int indexOf(AdHocChatRoomWrapper chatRoomWrapper)
+ {
+ return chatRoomsOrderedCopy.indexOf(chatRoomWrapper);
+ }
+
+ /**
+ * Goes through the locally stored chat rooms list and for each
+ * {@link ChatRoomWrapper} tries to find the corresponding server stored
+ * {@link ChatRoom} in the specified operation set. Joins automatically all
+ * found chat rooms.
+ *
+ * @param protocolProvider the protocol provider for the account to
+ * synchronize
+ * @param opSet the ad-hoc multi-user chat operation set, which give us
+ * access to chat room server
+ */
+ public void synchronizeProvider()
+ {
+ final OperationSetAdHocMultiUserChat groupChatOpSet
+ = (OperationSetAdHocMultiUserChat) protocolProvider
+ .getOperationSet(OperationSetAdHocMultiUserChat.class);
+
+ for(final AdHocChatRoomWrapper chatRoomWrapper : chatRoomsOrderedCopy)
+ {
+ new Thread()
+ {
+ public void run()
+ {
+ AdHocChatRoom chatRoom = null;
+
+ try
+ {
+ chatRoom = groupChatOpSet.findRoom(
+ chatRoomWrapper.getAdHocChatRoomName());
+ }
+ catch (OperationFailedException e1)
+ {
+ logger.error("Failed to find chat room with name:"
+ + chatRoomWrapper.getAdHocChatRoomName(), e1);
+ }
+ catch (OperationNotSupportedException e1)
+ {
+ logger.error("Failed to find chat room with name:"
+ + chatRoomWrapper.getAdHocChatRoomName(), e1);
+ }
+
+ if(chatRoom != null)
+ {
+ chatRoomWrapper.setAdHocChatRoom(chatRoom);
+
+ String lastChatRoomStatus
+ = ConfigurationManager.getChatRoomStatus(
+ protocolProvider,
+ chatRoomWrapper.getAdHocChatRoomID());
+
+ if(lastChatRoomStatus == null
+ || lastChatRoomStatus.equals(
+ Constants.ONLINE_STATUS))
+ {
+ GuiActivator.getUIService()
+ .getConferenceChatManager()
+ .joinChatRoom(chatRoomWrapper);
+ }
+ }
+ }
+ }.start();
+ }
+ }
+}

Added: trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocChatRoomWrapper.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocChatRoomWrapper.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocChatRoomWrapper.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,132 @@
+/*
+ * 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.chat.conference;
+
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * The<tt>AdHocChatRoomWrapper</tt> is the representation of the
+ *<tt>AdHocChatRoom</tt> in the GUI. It stores the information for the ad-hoc
+ * chat room even when the corresponding protocol provider is not connected.
+ *
+ * @author Valentin Martinet
+ */
+public class AdHocChatRoomWrapper
+{
+ private AdHocChatRoomProviderWrapper parentProvider;
+
+ private AdHocChatRoom adHocChatRoom;
+
+ private String adHocChatRoomName;
+
+ private String adHocChatRoomID;
+
+ /**
+ * Creates a<tt>AdHocChatRoomWrapper</tt> by specifying the protocol
+ * provider, the identifier and the name of the ad-hoc chat room.
+ *
+ * @param parentProvider the protocol provider to which the corresponding
+ * ad-hoc chat room belongs
+ * @param adHocChatRoomID the identifier of the corresponding ad-hoc chat
+ * room
+ * @param adHocChatRoomName the name of the corresponding ad-hoc chat room
+ */
+ public AdHocChatRoomWrapper(AdHocChatRoomProviderWrapper parentProvider,
+ String adHocChatRoomID,
+ String adHocChatRoomName)
+ {
+ this.parentProvider = parentProvider;
+ this.adHocChatRoomID = adHocChatRoomID;
+ this.adHocChatRoomName = adHocChatRoomName;
+ }
+
+ /**
+ * Creates a<tt>ChatRoomWrapper</tt> by specifying the corresponding chat
+ * room.
+ *
+ * @param chatRoom the chat room to which this wrapper corresponds.
+ */
+ public AdHocChatRoomWrapper( AdHocChatRoomProviderWrapper parentProvider,
+ AdHocChatRoom adHocChatRoom)
+ {
+ this( parentProvider,
+ adHocChatRoom.getIdentifier(),
+ adHocChatRoom.getName());
+
+ this.adHocChatRoom = adHocChatRoom;
+ }
+
+ /**
+ * Returns the<tt>AdHocChatRoom</tt> that this wrapper represents.
+ *
+ * @return the<tt>AdHocChatRoom</tt> that this wrapper represents.
+ */
+ public AdHocChatRoom getAdHocChatRoom()
+ {
+ return adHocChatRoom;
+ }
+
+ /**
+ * Sets the<tt>AdHocChatRoom</tt> that this wrapper represents.
+ *
+ * @param adHocChatRoom the ad-hoc chat room
+ */
+ public void setAdHocChatRoom(AdHocChatRoom adHocChatRoom)
+ {
+ this.adHocChatRoom = adHocChatRoom;
+ }
+
+ /**
+ * Returns the ad-hoc chat room name.
+ *
+ * @return the ad-hoc chat room name
+ */
+ public String getAdHocChatRoomName()
+ {
+ return adHocChatRoomName;
+ }
+
+ /**
+ * Sets the ad-hoc chat room name.
+ *
+ * @param adHocChatRoomName the name of the ad-hoc chat room
+ */
+ public void setAdHocChatRoomName(String adHocChatRoomName)
+ {
+ this.adHocChatRoomName = adHocChatRoomName;
+ }
+
+ /**
+ * Returns the identifier of the ad-hoc chat room.
+ *
+ * @return the identifier of the ad-hoc chat room
+ */
+ public String getAdHocChatRoomID()
+ {
+ return adHocChatRoomID;
+ }
+
+ /**
+ * Sets the identifier of the ad-hoc chat room.
+ *
+ * @param adHocChatRoomID the identifier of the ad-hoc chat room
+ */
+ public void setAdHocChatRoomID(String adHocChatRoomID)
+ {
+ this.adHocChatRoomID = adHocChatRoomID;
+ }
+
+ /**
+ * Returns the parent protocol provider.
+ *
+ * @return the parent protocol provider
+ */
+ public AdHocChatRoomProviderWrapper getParentProvider()
+ {
+ return this.parentProvider;
+ }
+}

Added: trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocConferenceChatContact.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocConferenceChatContact.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocConferenceChatContact.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,105 @@
+/*
+ * 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.chat.conference;
+
+import javax.swing.*;
+
+import net.java.sip.communicator.impl.gui.*;
+import net.java.sip.communicator.impl.gui.main.chat.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * The<tt>AdHocConferenceChatContact</tt> represents a<tt>ChatContact</tt> in
+ * an ad-hoc conference chat.
+ *
+ * @author Valentin Martinet
+ */
+public class AdHocConferenceChatContact extends ChatContact
+{
+ /**
+ * The contact associated with this<tt>AdHocConferenceChatContact</tt>.
+ */
+ private Contact participant;
+
+ /**
+ * Creates an instance of<tt>AdHocConferenceChatContact</tt> by passing to
+ * it the<tt>Contact</tt> for which it is created.
+ *
+ * @param participant the<tt>Contact</tt> for which this
+ *<tt>AdHocConferenceChatContact</tt> is created.
+ */
+ public AdHocConferenceChatContact(Contact participant)
+ {
+ OperationSetPersistentPresence opSet =
+ (OperationSetPersistentPresence) participant.getProtocolProvider().
+ getOperationSet(OperationSetPersistentPresence.class);
+ this.participant = opSet.findContactByID(participant.getAddress());
+ }
+
+ /**
+ * Returns the descriptor object corresponding to this chat contact.
+ *
+ * @return the descriptor object corresponding to this chat contact.
+ */
+ public Object getDescriptor()
+ {
+ return participant;
+ }
+
+ /**
+ * Returns the contact name.
+ *
+ * @return the contact name
+ */
+ public String getName()
+ {
+ String name = participant.getDisplayName();
+
+ if (name == null || name.length()< 1)
+ name = GuiActivator.getResources().getI18NString(
+ "service.gui.UNKNOWN");
+
+ return name;
+ }
+
+ /**
+ * Returns the current presence status for single user chat contacts and
+ * null for multi user chat contacts.
+ *
+ * @return the current presence status for single user chat contacts and
+ * null for multi user chat contacts
+ */
+ public ImageIcon getAvatar()
+ {
+ byte[] avatarBytes = participant.getImage();
+
+ if (avatarBytes != null&& avatarBytes.length> 0)
+ {
+ return ImageUtils.getScaledRoundedIcon(avatarBytes,
+ AVATAR_ICON_WIDTH,
+ AVATAR_ICON_HEIGHT
+ );
+ }
+ else
+ return null;
+ }
+
+ /*
+ * Implements ChatContact#getUID(). Delegates to
+ * Contact#getAddress() because it's supposed to be unique.
+ */
+ public String getUID()
+ {
+ return participant.getAddress();
+ }
+
+ @Override
+ protected byte[] getAvatarBytes() {
+ return this.participant.getImage();
+ }
+}

Added: trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocConferenceChatSession.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocConferenceChatSession.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocConferenceChatSession.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,530 @@
+/*
+ * 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.chat.conference;
+
+import java.util.*;
+
+import javax.swing.*;
+
+import net.java.sip.communicator.impl.gui.*;
+import net.java.sip.communicator.impl.gui.main.chat.*;
+import net.java.sip.communicator.impl.gui.utils.*;
+import net.java.sip.communicator.service.metahistory.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.event.*;
+
+/**
+ * An implementation of<tt>ChatSession</tt> for ad-hoc conference chatting.
+ *
+ * @author Valentin Martinet
+ */
+public class AdHocConferenceChatSession
+ implements ChatSession,
+ AdHocChatRoomParticipantPresenceListener
+{
+ private final List<ChatContact> chatParticipants
+ = new ArrayList<ChatContact>();
+
+ private final List<ChatTransport> chatTransports
+ = new ArrayList<ChatTransport>();
+
+ private ChatTransport currentChatTransport;
+
+ private final AdHocChatRoomWrapper chatRoomWrapper;
+
+ private final ChatSessionRenderer sessionRenderer;
+
+ /**
+ * Creates an instance of<tt>AdHocConferenceChatSession</tt>, by specifying
+ * the sessionRenderer to be used for communication with the UI and the
+ * ad-hoc chat room corresponding to this conference session.
+ *
+ * @param sessionRenderer the renderer to be used for communication with the
+ * UI.
+ * @param chatRoomWrapper the ad-hoc chat room corresponding to this
+ * conference session.
+ */
+ public AdHocConferenceChatSession( ChatSessionRenderer sessionRenderer,
+ AdHocChatRoomWrapper chatRoomWrapper)
+ {
+ this.sessionRenderer = sessionRenderer;
+ this.chatRoomWrapper = chatRoomWrapper;
+
+ this.currentChatTransport = new AdHocConferenceChatTransport(
+ this, chatRoomWrapper.getAdHocChatRoom());
+
+ chatTransports.add(currentChatTransport);
+
+ this.initChatParticipants();
+
+ AdHocChatRoom chatRoom = chatRoomWrapper.getAdHocChatRoom();
+ chatRoom.addParticipantPresenceListener(this);
+ }
+
+ /**
+ * Returns the descriptor of this chat session.
+ *
+ * @return the descriptor of this chat session.
+ */
+ public Object getDescriptor()
+ {
+ return chatRoomWrapper;
+ }
+
+ /**
+ * Disposes this chat session.
+ */
+ public void dispose()
+ {
+ AdHocChatRoom chatRoom = chatRoomWrapper.getAdHocChatRoom();
+ chatRoom.removeParticipantPresenceListener(this);
+ }
+
+ /**
+ * Returns the name of the ad-hoc chat room.
+ *
+ * @return the name of the ad-hoc chat room.
+ */
+ public String getChatName()
+ {
+ return chatRoomWrapper.getAdHocChatRoomName();
+ }
+
+ /**
+ * Returns the configuration form corresponding to the chat room.
+ *
+ * @return the configuration form corresponding to the chat room.
+ * @throws OperationFailedException if no configuration form is available
+ * for the chat room.
+ */
+ public ChatRoomConfigurationForm getChatConfigurationForm()
+ throws OperationFailedException
+ {
+ return null;
+ }
+
+ /**
+ * Returns an iterator to the list of all participants contained in this
+ * chat session.
+ *
+ * @return an iterator to the list of all participants contained in this
+ * chat session.
+ */
+ public Iterator<ChatContact> getParticipants()
+ {
+ return chatParticipants.iterator();
+ }
+
+ /**
+ * Returns all available chat transports for this chat session.
+ *
+ * @return all available chat transports for this chat session.
+ */
+ public Iterator<ChatTransport> getChatTransports()
+ {
+ return chatTransports.iterator();
+ }
+
+ /**
+ * Returns the currently used transport for all operation within this chat
+ * session.
+ *
+ * @return the currently used transport for all operation within this chat
+ * session.
+ */
+ public ChatTransport getCurrentChatTransport()
+ {
+ return currentChatTransport;
+ }
+
+ /**
+ * Returns the default mobile number used to send sms-es in this session. In
+ * the case of conference this is for now null.
+ *
+ * @return the default mobile number used to send sms-es in this session.
+ */
+ public String getDefaultSmsNumber()
+ {
+ return null;
+ }
+
+ /**
+ * Returns a collection of the last N number of messages given by count.
+ *
+ * @param count The number of messages from history to return.
+ * @return a collection of the last N number of messages given by count.
+ */
+ public Collection<Object> getHistory(int count)
+ {
+ final MetaHistoryService metaHistory
+ = GuiActivator.getMetaHistoryService();
+
+ // If the MetaHistoryService is not registered we have nothing to do
+ // here. The history could be "disabled" from the user
+ // through one of the configuration forms.
+ if (metaHistory == null)
+ return null;
+
+ return metaHistory.findLast(
+ chatHistoryFilter,
+ chatRoomWrapper.getAdHocChatRoom(),
+ ConfigurationManager.getChatHistorySize());
+ }
+
+ /**
+ * Returns a collection of the last N number of messages given by count.
+ *
+ * @param date The date up to which we're looking for messages.
+ * @param count The number of messages from history to return.
+ * @return a collection of the last N number of messages given by count.
+ */
+ public Collection<Object> getHistoryBeforeDate(Date date, int count)
+ {
+ final MetaHistoryService metaHistory
+ = GuiActivator.getMetaHistoryService();
+
+ // If the MetaHistoryService is not registered we have nothing to do
+ // here. The history could be "disabled" from the user
+ // through one of the configuration forms.
+ if (metaHistory == null)
+ return null;
+
+ return metaHistory.findLastMessagesBefore(
+ chatHistoryFilter,
+ chatRoomWrapper.getAdHocChatRoom(),
+ date,
+ ConfigurationManager.getChatHistorySize());
+ }
+
+ /**
+ * Returns a collection of the last N number of messages given by count.
+ *
+ * @param date The date from which we're looking for messages.
+ * @param count The number of messages from history to return.
+ * @return a collection of the last N number of messages given by count.
+ */
+ public Collection<Object> getHistoryAfterDate(Date date, int count)
+ {
+ final MetaHistoryService metaHistory
+ = GuiActivator.getMetaHistoryService();
+
+ // If the MetaHistoryService is not registered we have nothing to do
+ // here. The history could be "disabled" from the user
+ // through one of the configuration forms.
+ if (metaHistory == null)
+ return null;
+
+ return metaHistory.findFirstMessagesAfter(
+ chatHistoryFilter,
+ chatRoomWrapper.getAdHocChatRoom(),
+ date,
+ ConfigurationManager.getChatHistorySize());
+ }
+
+ /**
+ * Returns the start date of the history of this chat session.
+ *
+ * @return the start date of the history of this chat session.
+ */
+ public long getHistoryStartDate()
+ {
+ MetaHistoryService metaHistory
+ = GuiActivator.getMetaHistoryService();
+
+ // If the MetaHistoryService is not registered we have nothing to do
+ // here. The history could be "disabled" from the user
+ // through one of the configuration forms.
+ if (metaHistory == null)
+ return 0;
+
+ long startHistoryDate = 0;
+
+ Collection<Object> firstMessage = metaHistory
+ .findFirstMessagesAfter(
+ chatHistoryFilter,
+ chatRoomWrapper.getAdHocChatRoom(),
+ new Date(0),
+ 1);
+
+ if(firstMessage.size()> 0)
+ {
+ Iterator<Object> i = firstMessage.iterator();
+
+ Object o = i.next();
+
+ if(o instanceof MessageDeliveredEvent)
+ {
+ MessageDeliveredEvent evt
+ = (MessageDeliveredEvent)o;
+
+ startHistoryDate = evt.getTimestamp();
+ }
+ else if(o instanceof MessageReceivedEvent)
+ {
+ MessageReceivedEvent evt = (MessageReceivedEvent)o;
+
+ startHistoryDate = evt.getTimestamp();
+ }
+ }
+
+ return startHistoryDate;
+ }
+
+ /**
+ * Returns the end date of the history of this chat session.
+ *
+ * @return the end date of the history of this chat session.
+ */
+ public long getHistoryEndDate()
+ {
+ MetaHistoryService metaHistory
+ = GuiActivator.getMetaHistoryService();
+
+ // If the MetaHistoryService is not registered we have nothing to do
+ // here. The history could be "disabled" from the user
+ // through one of the configuration forms.
+ if (metaHistory == null)
+ return 0;
+
+ long endHistoryDate = 0;
+
+ Collection<Object> lastMessage = metaHistory
+ .findLastMessagesBefore(
+ chatHistoryFilter,
+ chatRoomWrapper.getAdHocChatRoom(),
+ new Date(Long.MAX_VALUE), 1);
+
+ if(lastMessage.size()> 0)
+ {
+ Iterator<Object> i1 = lastMessage.iterator();
+
+ Object o1 = i1.next();
+
+ if(o1 instanceof MessageDeliveredEvent)
+ {
+ MessageDeliveredEvent evt
+ = (MessageDeliveredEvent)o1;
+
+ endHistoryDate = evt.getTimestamp();
+ }
+ else if(o1 instanceof MessageReceivedEvent)
+ {
+ MessageReceivedEvent evt = (MessageReceivedEvent)o1;
+
+ endHistoryDate = evt.getTimestamp();
+ }
+ }
+
+ return endHistoryDate;
+ }
+
+ /**
+ * Sets the transport that will be used for all operations within this chat
+ * session.
+ *
+ * @param chatTransport The transport to set as a default transport for this
+ * session.
+ */
+ public void setCurrentChatTransport(ChatTransport chatTransport)
+ {
+ this.currentChatTransport = chatTransport;
+ }
+
+ /**
+ * Sets the default mobile number used to send sms-es in this session.
+ *
+ * @param smsPhoneNumber The default mobile number used to send sms-es in
+ * this session.
+ */
+ public void setDefaultSmsNumber(String smsPhoneNumber)
+ {}
+
+ /**
+ * Returns the<tt>ChatSessionRenderer</tt> that provides the connection
+ * between this chat session and its UI.
+ *
+ * @return The<tt>ChatSessionRenderer</tt>.
+ */
+ public ChatSessionRenderer getChatSessionRenderer()
+ {
+ return sessionRenderer;
+ }
+
+ /**
+ * Returns<code>true</code> if this contact is persistent, otherwise
+ * returns<code>false</code>.
+ * @return<code>true</code> if this contact is persistent, otherwise
+ * returns<code>false</code>.
+ */
+ public boolean isDescriptorPersistent()
+ {
+ return false;
+ }
+
+ public ChatTransport findChatTransportForDescriptor(Object descriptor)
+ {
+ return MetaContactChatSession.findChatTransportForDescriptor(
+ chatTransports,
+ descriptor);
+ }
+
+ /**
+ * Loads the given chat room in the this chat conference panel. Loads all
+ * members and adds all corresponding listeners.
+ *
+ * @param chatRoom the<tt>ChatRoom</tt> to load
+ */
+ public void loadChatRoom(AdHocChatRoom chatRoom)
+ {
+ for (Contact contact : chatRoom.getParticipants())
+ {
+ sessionRenderer.addChatContact(
+ new AdHocConferenceChatContact(contact));
+
+ }
+
+ chatRoom.addParticipantPresenceListener(this);
+
+ }
+
+ /**
+ * Implements the<tt>ChatPanel.getChatStatusIcon</tt> method.
+ *
+ * @return the status icon corresponding to this ad-hoc chat room
+ */
+ public ImageIcon getChatStatusIcon()
+ {
+ String status = Constants.OFFLINE_STATUS;
+
+ if(chatRoomWrapper.getAdHocChatRoom() != null)
+ status = Constants.ONLINE_STATUS;
+
+ return new ImageIcon(Constants.getStatusIcon(status));
+ }
+
+ /**
+ * Returns the avatar icon of this chat session.
+ *
+ * @return the avatar icon of this chat session.
+ */
+ public byte[] getChatAvatar()
+ {
+ return null;
+ }
+
+ /**
+ * Initializes the list of participants.
+ */
+ private void initChatParticipants()
+ {
+ AdHocChatRoom chatRoom = chatRoomWrapper.getAdHocChatRoom();
+
+ if (chatRoom != null)
+ {
+ for (Contact contact : chatRoom.getParticipants())
+ {
+ chatParticipants.add(new AdHocConferenceChatContact(contact));
+ }
+ }
+ }
+
+ /* Implements ChatSession#isContactListSupported(). */
+ public boolean isContactListSupported()
+ {
+ return true;
+ }
+
+ /**
+ * Invoked when<tt>AdHocChatRoomParticipantPresenceChangeEvent</tt> are
+ * received. When a new participant (<tt>Contact</tt>) has joined the chat
+ * adds it to the list of chat participants on the right of the chat window.
+ * When a participant has left or quit it's removed from the chat window.
+ */
+ public void participantPresenceChanged(
+ AdHocChatRoomParticipantPresenceChangeEvent evt) {
+ AdHocChatRoom sourceChatRoom = evt.getAdHocChatRoom();
+
+ if(!sourceChatRoom.equals(chatRoomWrapper.getAdHocChatRoom()))
+ return;
+
+ String eventType = evt.getEventType();
+ Contact participant = evt.getParticipant();
+
+ String statusMessage = null;
+
+ if (eventType.equals(
+ AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_JOINED))
+ {
+ AdHocConferenceChatContact chatContact
+ = new AdHocConferenceChatContact(participant);
+
+ chatParticipants.add(chatContact);
+
+ sessionRenderer.addChatContact(chatContact);
+
+ /*
+ * When the whole list of members of a given chat room is reported,
+ * it doesn't make sense to see "ChatContact has joined #ChatRoom"
+ * for all of them one after the other. Such an event occurs not
+ * because the ChatContact has joined after us but rather she was
+ * there before us.
+ */
+ if (!evt.isReasonUserList())
+ {
+ statusMessage = GuiActivator.getResources().getI18NString(
+ "service.gui.CHAT_ROOM_USER_JOINED",
+ new String[] {sourceChatRoom.getName()});
+
+ sessionRenderer.updateChatContactStatus(
+ chatContact,
+ statusMessage);
+ }
+ }
+ else if (eventType.equals(
+ AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_LEFT)
+ ||
+ eventType.equals(
+ AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_QUIT))
+ {
+ if(eventType.equals(
+ AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_LEFT))
+ {
+ statusMessage = GuiActivator.getResources().getI18NString(
+ "service.gui.CHAT_ROOM_USER_LEFT",
+ new String[] {sourceChatRoom.getName()});
+ }
+ else if(eventType.equals(
+ AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_QUIT))
+ {
+ statusMessage = GuiActivator.getResources().getI18NString(
+ "service.gui.CHAT_ROOM_USER_QUIT",
+ new String[] {sourceChatRoom.getName()});
+ }
+
+ for (ChatContact chatContact : chatParticipants)
+ {
+ if(chatContact.getDescriptor().equals(participant))
+ {
+ sessionRenderer.updateChatContactStatus(
+ chatContact, statusMessage);
+
+ sessionRenderer.removeChatContact(chatContact);
+ break;
+ }
+ }
+ }
+ }
+
+ public void addChatTransportChangeListener(ChatSessionChangeListener l)
+ {
+ }
+
+ public void removeChatTransportChangeListener(ChatSessionChangeListener l)
+ {
+ }
+}

Added: trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocConferenceChatTransport.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocConferenceChatTransport.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocConferenceChatTransport.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,302 @@
+/*
+ * 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.chat.conference;
+
+import java.io.*;
+
+import net.java.sip.communicator.impl.gui.main.chat.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.event.*;
+
+/**
+ * The conference implementation of the<tt>ChatTransport</tt> interface that
+ * provides abstraction to access to protocol providers.
+ *
+ * @author Valentin Martinet
+ */
+public class AdHocConferenceChatTransport
+ implements ChatTransport
+{
+ private ChatSession chatSession;
+
+ private AdHocChatRoom adHocChatRoom;
+
+ /**
+ * Creates an instance of<tt>ConferenceChatTransport</tt> by specifying the
+ * parent chat session and the ad-hoc chat room associated with this
+ * transport.
+ *
+ * @param chatSession the parent chat session.
+ * @param chatRoom the ad-hoc chat room associated with this conference
+ * transport.
+ */
+ public AdHocConferenceChatTransport(ChatSession chatSession,
+ AdHocChatRoom chatRoom)
+ {
+ this.chatSession = chatSession;
+ this.adHocChatRoom = chatRoom;
+ }
+
+ /**
+ * Returns the contact address corresponding to this chat transport.
+ *
+ * @return The contact address corresponding to this chat transport.
+ */
+ public String getName()
+ {
+ return adHocChatRoom.getName();
+ }
+
+ /**
+ * Returns the display name corresponding to this chat transport.
+ *
+ * @return The display name corresponding to this chat transport.
+ */
+ public String getDisplayName()
+ {
+ return adHocChatRoom.getName();
+ }
+
+ /**
+ * Returns the presence status of this transport.
+ *
+ * @return the presence status of this transport.
+ */
+ public PresenceStatus getStatus()
+ {
+ return null;
+ }
+
+ /**
+ * Returns the<tt>ProtocolProviderService</tt>, corresponding to this chat
+ * transport.
+ *
+ * @return the<tt>ProtocolProviderService</tt>, corresponding to this chat
+ * transport.
+ */
+ public ProtocolProviderService getProtocolProvider()
+ {
+ return adHocChatRoom.getParentProvider();
+ }
+
+ /**
+ * Returns<code>true</code> if this chat transport supports instant
+ * messaging, otherwise returns<code>false</code>.
+ *
+ * @return<code>true</code> if this chat transport supports instant
+ * messaging, otherwise returns<code>false</code>.
+ */
+ public boolean allowsInstantMessage()
+ {
+ return true;
+ }
+
+ /**
+ * Returns<code>true</code> if this chat transport supports sms
+ * messaging, otherwise returns<code>false</code>.
+ *
+ * @return<code>true</code> if this chat transport supports sms
+ * messaging, otherwise returns<code>false</code>.
+ */
+ public boolean allowsSmsMessage()
+ {
+ Object smsOpSet = adHocChatRoom.getParentProvider()
+ .getOperationSet(OperationSetSmsMessaging.class);
+
+ if (smsOpSet != null)
+ return true;
+ else
+ return false;
+ }
+
+ /**
+ * Returns<code>true</code> if this chat transport supports typing
+ * notifications, otherwise returns<code>false</code>.
+ *
+ * @return<code>true</code> if this chat transport supports typing
+ * notifications, otherwise returns<code>false</code>.
+ */
+ public boolean allowsTypingNotifications()
+ {
+ Object tnOpSet = adHocChatRoom.getParentProvider()
+ .getOperationSet(OperationSetTypingNotifications.class);
+
+ if (tnOpSet != null)
+ return true;
+ else
+ return false;
+ }
+
+ /**
+ * Sends the given instant message trough this chat transport, by specifying
+ * the mime type (html or plain text).
+ *
+ * @param message The message to send.
+ * @param mimeType The mime type of the message to send: text/html or
+ * text/plain.
+ */
+ public void sendInstantMessage(String messageText, String mimeType)
+ throws Exception
+ {
+ // If this chat transport does not support instant messaging we do
+ // nothing here.
+ if (!allowsInstantMessage())
+ return;
+
+ Message message = adHocChatRoom.createMessage(messageText);
+
+ adHocChatRoom.sendMessage(message);
+ }
+
+ /**
+ * Sending sms messages is not supported by this chat transport
+ * implementation.
+ */
+ public void sendSmsMessage(String phoneNumber, String message)
+ throws Exception
+ {}
+
+ /**
+ * Sending typing notifications is not supported by this chat transport
+ * implementation.
+ */
+ public int sendTypingNotification(int typingState)
+ {
+ return 0;
+ }
+
+ /**
+ * Sending files through a chat room is not yet supported by this chat
+ * transport implementation.
+ */
+ public FileTransfer sendFile(File file)
+ throws Exception
+ {
+ return null;
+ }
+
+ /**
+ * Invites the given contact in this chat conference.
+ *
+ * @param contactAddress the address of the contact to invite
+ * @param reason the reason for the invitation
+ */
+ public void inviteChatContact(String contactAddress, String reason)
+ {
+ if(adHocChatRoom != null)
+ adHocChatRoom.invite(contactAddress, reason);
+ }
+
+ /**
+ * Returns the parent session of this chat transport. A<tt>ChatSession</tt>
+ * could contain more than one transports.
+ *
+ * @return the parent session of this chat transport
+ */
+ public ChatSession getParentChatSession()
+ {
+ return chatSession;
+ }
+
+ /**
+ * Adds an sms message listener to this chat transport.
+ *
+ * @param l The message listener to add.
+ */
+ public void addSmsMessageListener(MessageListener l)
+ {
+ // If this chat transport does not support sms messaging we do
+ // nothing here.
+ if (!allowsSmsMessage())
+ return;
+
+ OperationSetSmsMessaging smsOpSet
+ = (OperationSetSmsMessaging) adHocChatRoom.getParentProvider()
+ .getOperationSet(OperationSetSmsMessaging.class);
+
+ smsOpSet.addMessageListener(l);
+ }
+
+ /**
+ * Adds an instant message listener to this chat transport.
+ *
+ * @param l The message listener to add.
+ */
+ public void addInstantMessageListener(MessageListener l)
+ {
+ // If this chat transport does not support instant messaging we do
+ // nothing here.
+ if (!allowsInstantMessage())
+ return;
+
+ OperationSetBasicInstantMessaging imOpSet
+ = (OperationSetBasicInstantMessaging)
+ adHocChatRoom.getParentProvider()
+ .getOperationSet(OperationSetBasicInstantMessaging.class);
+
+ imOpSet.addMessageListener(l);
+ }
+
+ /**
+ * Removes the given sms message listener from this chat transport.
+ *
+ * @param l The message listener to remove.
+ */
+ public void removeSmsMessageListener(MessageListener l)
+ {
+ // If this chat transport does not support sms messaging we do
+ // nothing here.
+ if (!allowsSmsMessage())
+ return;
+
+ OperationSetSmsMessaging smsOpSet
+ = (OperationSetSmsMessaging) adHocChatRoom.getParentProvider()
+ .getOperationSet(OperationSetSmsMessaging.class);
+
+ smsOpSet.removeMessageListener(l);
+ }
+
+ /**
+ * Removes the instant message listener from this chat transport.
+ *
+ * @param l The message listener to remove.
+ */
+ public void removeInstantMessageListener(MessageListener l)
+ {
+ // If this chat transport does not support instant messaging we do
+ // nothing here.
+ if (!allowsInstantMessage())
+ return;
+
+ OperationSetBasicInstantMessaging imOpSet
+ = (OperationSetBasicInstantMessaging)
+ adHocChatRoom.getParentProvider()
+ .getOperationSet(OperationSetBasicInstantMessaging.class);
+
+ imOpSet.removeMessageListener(l);
+ }
+
+ public void dispose()
+ {}
+
+ /**
+ * Returns the descriptor of this chat transport.
+ *
+ * @return the descriptor of this chat transport
+ */
+ public Object getDescriptor()
+ {
+ return adHocChatRoom;
+ }
+
+ public long getMaximumFileLength()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+}
\ No newline at end of file

Modified: trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatContact.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatContact.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatContact.java&p2=trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatContact.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatContact.java (original)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatContact.java 2009-09-14 15:51:47+0000
@@ -53,12 +53,13 @@
         String name = chatRoomMember.getName();

         if (name == null || name.length()< 1)
- name = GuiActivator.getResources().getI18NString("service.gui.UNKNOWN");
+ name = GuiActivator.getResources()
+ .getI18NString("service.gui.UNKNOWN");

         return name;
     }

- /*
+ /**
      * Implements ChatContact#getAvatarBytes(). Delegates to chatRoomMember.
      */
     public byte[] getAvatarBytes()
@@ -71,7 +72,7 @@
         return chatRoomMember.getRole();
     }

- /*
+ /**
      * Implements ChatContact#getUID(). Delegates to
      * ChatRoomMember#getContactAddress() because it's supposed to be unique.
      */

Modified: trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatManager.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatManager.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatManager.java&p2=trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatManager.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatManager.java (original)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatManager.java 2009-09-14 15:51:47+0000
@@ -29,17 +29,22 @@
import org.osgi.framework.*;

/**
- * The<tt>ConferenceChatManager</tt> is the one that manages chat room
- * invitations.
+ * The<tt>ConferenceChatManager</tt> is the one that manages both chat room and
+ * ad-hoc chat rooms invitations.
  *
  * @author Yana Stamcheva
  * @author Lubomir Marinov
+ * @author Valentin Martinet
  */
public class ConferenceChatManager
     implements ChatRoomMessageListener,
                 ChatRoomInvitationListener,
                 ChatRoomInvitationRejectionListener,
+ AdHocChatRoomMessageListener,
+ AdHocChatRoomInvitationListener,
+ AdHocChatRoomInvitationRejectionListener,
                 LocalUserChatRoomPresenceListener,
+ LocalUserAdHocChatRoomPresenceListener,
                 ServiceListener
{
     private static final Logger logger
@@ -49,10 +54,15 @@
         new Hashtable<ChatRoomWrapper, HistoryWindow>();

     private final ChatRoomList chatRoomList = new ChatRoomList();
+
+ private final AdHocChatRoomList adHocChatRoomList = new AdHocChatRoomList();

     private final Vector<ChatRoomListChangeListener> listChangeListeners
         = new Vector<ChatRoomListChangeListener>();

+ private final Vector<AdHocChatRoomListChangeListener>
+ adHoclistChangeListeners = new Vector<AdHocChatRoomListChangeListener>();
+
     /**
      * Creates an instance of<tt>ConferenceChatManager</tt>.
      */
@@ -64,6 +74,7 @@
             public void run()
             {
                 chatRoomList.loadList();
+ adHocChatRoomList.loadList();
             }
         }.start();

@@ -80,6 +91,18 @@
     {
         return chatRoomList;
     }
+
+ /**
+ * Returns all chat room providers currently contained in the ad-hoc chat
+ * room list.
+ *
+ * @return all chat room providers currently contained in the ad-hoc chat
+ * room list.
+ */
+ public AdHocChatRoomList getAdHocChatRoomList()
+ {
+ return adHocChatRoomList;
+ }

     /**
      * Handles<tt>ChatRoomInvitationReceivedEvent</tt>-s.
@@ -175,6 +198,9 @@
             break;
         }

+ logger.setLevelInfo();
+ logger.info("MESSAGE RECEIVED from "+sourceMember.getContactAddress());
+
         logger.trace("MESSAGE RECEIVED from contact: "
             + sourceMember.getContactAddress());

@@ -297,30 +323,31 @@
         ChatRoomMember destMember = evt.getDestinationChatRoomMember();

         if (evt.getErrorCode()
- == MessageDeliveryFailedEvent.OFFLINE_MESSAGES_NOT_SUPPORTED) {
-
+ == MessageDeliveryFailedEvent.OFFLINE_MESSAGES_NOT_SUPPORTED)
+ {
             errorMsg = GuiActivator.getResources().getI18NString(
                     "service.gui.MSG_DELIVERY_NOT_SUPPORTED");
         }
         else if (evt.getErrorCode()
- == MessageDeliveryFailedEvent.NETWORK_FAILURE) {
-
+ == MessageDeliveryFailedEvent.NETWORK_FAILURE)
+ {
             errorMsg = GuiActivator.getResources()
                 .getI18NString("service.gui.MSG_NOT_DELIVERED");
         }
         else if (evt.getErrorCode()
- == MessageDeliveryFailedEvent.PROVIDER_NOT_REGISTERED) {
-
+ == MessageDeliveryFailedEvent.PROVIDER_NOT_REGISTERED)
+ {
             errorMsg = GuiActivator.getResources().getI18NString(
                     "service.gui.MSG_SEND_CONNECTION_PROBLEM");
         }
         else if (evt.getErrorCode()
- == MessageDeliveryFailedEvent.INTERNAL_ERROR) {
-
+ == MessageDeliveryFailedEvent.INTERNAL_ERROR)
+ {
             errorMsg = GuiActivator.getResources().getI18NString(
                     "service.gui.MSG_DELIVERY_INTERNAL_ERROR");
         }
- else {
+ else
+ {
             errorMsg = GuiActivator.getResources().getI18NString(
                     "service.gui.MSG_DELIVERY_UNKNOWN_ERROR");
         }
@@ -347,6 +374,94 @@

     /**
      * Implements the
+ *<>LocalUserAdHocChatRoomPresenceListener.localUserPresenceChanged</>
+ * method
+ *
+ * @param evt
+ */
+ public void localUserAdHocPresenceChanged(
+ LocalUserAdHocChatRoomPresenceChangeEvent evt)
+ {
+ AdHocChatRoom sourceAdHocChatRoom = evt.getAdHocChatRoom();
+
+ AdHocChatRoomWrapper adHocChatRoomWrapper =
+ adHocChatRoomList.findChatRoomWrapperFromAdHocChatRoom(
+ sourceAdHocChatRoom);
+
+ if (evt.getEventType().equals(
+ LocalUserAdHocChatRoomPresenceChangeEvent.LOCAL_USER_JOINED))
+ {
+ if(adHocChatRoomWrapper != null)
+ {
+ this.fireAdHocChatRoomListChangedEvent(
+ adHocChatRoomWrapper,
+ AdHocChatRoomListChangeEvent.AD_HOC_CHAT_ROOM_CHANGED);
+
+ ChatWindowManager chatWindowManager
+ = GuiActivator.getUIService().getChatWindowManager();
+
+ ChatPanel chatPanel
+ = chatWindowManager.getAdHocMultiChat(adHocChatRoomWrapper);
+
+ // Check if we have already opened a chat window for this chat
+ // wrapper and load the real chat room corresponding to the
+ // wrapper.
+ if(chatWindowManager
+ .isChatOpenedForAdHocChatRoom(adHocChatRoomWrapper))
+ {
+ ((AdHocConferenceChatSession) chatPanel.getChatSession())
+ .loadChatRoom(sourceAdHocChatRoom);
+ }
+ else
+ {
+ chatWindowManager.openChat(chatPanel, true);
+ }
+ }
+
+ sourceAdHocChatRoom.addMessageListener(this);
+ }
+ else if (evt.getEventType().equals(
+ LocalUserAdHocChatRoomPresenceChangeEvent.LOCAL_USER_JOIN_FAILED))
+ {
+ new ErrorDialog(
+ GuiActivator.getUIService().getMainFrame(),
+ GuiActivator.getResources().getI18NString("service.gui.ERROR"),
+ GuiActivator.getResources().getI18NString(
+ "service.gui.FAILED_TO_JOIN_CHAT_ROOM",
+ new String[]{sourceAdHocChatRoom.getName()})
+ + evt.getReason())
+ .showDialog();
+ }
+ else if (evt.getEventType().equals(
+ LocalUserAdHocChatRoomPresenceChangeEvent.LOCAL_USER_LEFT))
+ {
+ this.closeAdHocChatRoom(adHocChatRoomWrapper);
+
+ // Need to refresh the chat room's list in order to change
+ // the state of the chat room to offline.
+ fireAdHocChatRoomListChangedEvent(
+ adHocChatRoomWrapper,
+ AdHocChatRoomListChangeEvent.AD_HOC_CHAT_ROOM_CHANGED);
+
+ sourceAdHocChatRoom.removeMessageListener(this);
+ }
+ else if (evt.getEventType().equals(
+ LocalUserAdHocChatRoomPresenceChangeEvent.LOCAL_USER_DROPPED))
+ {
+ this.closeAdHocChatRoom(adHocChatRoomWrapper);
+
+ // Need to refresh the ad-hoc chat room's list in order to change
+ // the state of the ad-hoc chat room to offline.
+ fireAdHocChatRoomListChangedEvent(
+ adHocChatRoomWrapper,
+ AdHocChatRoomListChangeEvent.AD_HOC_CHAT_ROOM_CHANGED);
+
+ sourceAdHocChatRoom.removeMessageListener(this);
+ }
+ }
+
+ /**
+ * Implements the
      *<tt>LocalUserChatRoomPresenceListener.localUserPresenceChanged</tt>
      * method.
      */
@@ -469,6 +584,24 @@
     }

     /**
+ * Called to accept an incoming invitation. Adds the invitation chat room
+ * to the list of chat rooms and joins it.
+ *
+ * @param invitation the invitation to accept.
+ *
+ * @throws OperationFailedException
+ */
+ public void acceptInvitation(
+ AdHocChatRoomInvitation invitation,
+ OperationSetAdHocMultiUserChat multiUserChatOpSet)
+ throws OperationFailedException
+ {
+ AdHocChatRoom chatRoom = invitation.getTargetAdHocChatRoom();
+
+ chatRoom.join();
+ }
+
+ /**
      * Rejects the given invitation with the specified reason.
      *
      * @param multiUserChatOpSet the operation set to use for rejecting the
@@ -476,14 +609,30 @@
      * @param invitation the invitation to reject
      * @param reason the reason for the rejection
      */
- public void rejectInvitation( OperationSetMultiUserChat multiUserChatOpSet,
- ChatRoomInvitation invitation,
- String reason)
+ public void rejectInvitation( OperationSetMultiUserChat multiUserChatOpSet,
+ ChatRoomInvitation invitation,
+ String reason)
     {
         multiUserChatOpSet.rejectInvitation(invitation, reason);
     }

     /**
+ * Rejects the given invitation with the specified reason.
+ *
+ * @param multiUserChatOpSet the operation set to use for rejecting the
+ * invitation
+ * @param invitation the invitation to reject
+ * @param reason the reason for the rejection
+ */
+ public void rejectInvitation(
+ OperationSetAdHocMultiUserChat multiUserChatAdHocOpSet,
+ AdHocChatRoomInvitation invitation,
+ String reason)
+ {
+ multiUserChatAdHocOpSet.rejectInvitation(invitation, reason);
+ }
+
+ /**
      * Joins the given chat room with the given password and manages all the
      * exceptions that could occur during the join process.
      *
@@ -500,9 +649,9 @@
         if(chatRoom == null)
         {
             new ErrorDialog(
- GuiActivator.getUIService().getMainFrame(),
- GuiActivator.getResources().getI18NString("service.gui.WARNING"),
- GuiActivator.getResources().getI18NString(
+ GuiActivator.getUIService().getMainFrame(),
+ GuiActivator.getResources().getI18NString("service.gui.WARNING"),
+ GuiActivator.getResources().getI18NString(
                     "service.gui.CHAT_ROOM_NOT_CONNECTED",
                     new String[]{chatRoomWrapper.getChatRoomName()}))
                     .showDialog();
@@ -514,14 +663,18 @@
     }

     /**
- * Creates a chatroom, by specifying the chat room name and the parent
- * protocol provider.
+ * Creates a chat room, by specifying the chat room name, the parent
+ * protocol provider and eventually, the contacts invited to participate in
+ * this chat room.
+ *
      * @param chatRoomName the name of the chat room to create.
      * @param protocolProvider the parent protocol provider.
+ * @param contacts the contacts invited when creating the chat room.
      */
     public ChatRoomWrapper createChatRoom(
         String chatRoomName,
- ProtocolProviderService protocolProvider)
+ ProtocolProviderService protocolProvider,
+ Collection<String> contacts)
     {
         ChatRoomWrapper chatRoomWrapper = null;

@@ -536,7 +689,18 @@
         ChatRoom chatRoom = null;
         try
         {
- chatRoom = groupChatOpSet.createChatRoom(chatRoomName, null);
+ Map<String, Object> members = new Hashtable<String, >();
+ OperationSetPersistentPresence opSet =
+ (OperationSetPersistentPresence)
+ protocolProvider.getOperationSet(
+ OperationSetPersistentPresence.class);
+
+ for(String contact : contacts)
+ {
+ members.put(contact, opSet.findContactByID(contact));
+ }
+
+ chatRoom = groupChatOpSet.createChatRoom(chatRoomName, members);
         }
         catch (OperationFailedException ex)
         {
@@ -582,6 +746,90 @@
     }

     /**
+ * Creates an ad-hoc chat room, by specifying the ad-hoc chat room name, the
+ * parent protocol provider and eventually, the contacts invited to
+ * participate in this ad-hoc chat room.
+ *
+ * @param chatRoomName the name of the chat room to create.
+ * @param protocolProvider the parent protocol provider.
+ * @param contacts the contacts invited when creating the chat room.
+ */
+ public AdHocChatRoomWrapper createAdHocChatRoom(
+ String chatRoomName,
+ ProtocolProviderService protocolProvider,
+ Collection<String> contacts)
+ {
+ AdHocChatRoomWrapper chatRoomWrapper = null;
+
+ OperationSetAdHocMultiUserChat groupChatOpSet
+ = (OperationSetAdHocMultiUserChat) protocolProvider
+ .getOperationSet(OperationSetAdHocMultiUserChat.class);
+
+ // If there's no group chat operation set we have nothing to do here.
+ if (groupChatOpSet == null)
+ return null;
+
+ AdHocChatRoom chatRoom = null;
+
+ try
+ {
+ List<Contact> members = new LinkedList<Contact>();
+ OperationSetPersistentPresence opSet =
+ (OperationSetPersistentPresence)
+ protocolProvider.getOperationSet(
+ OperationSetPersistentPresence.class);
+
+ for(String contact : contacts)
+ {
+ members.add(opSet.findContactByID(contact));
+ }
+
+ chatRoom = groupChatOpSet.createAdHocChatRoom(
+ chatRoomName, members);
+ }
+ catch (OperationFailedException ex)
+ {
+ new ErrorDialog(
+ GuiActivator.getUIService().getMainFrame(),
+ GuiActivator.getResources().getI18NString("service.gui.ERROR"),
+ GuiActivator.getResources().getI18NString(
+ "service.gui.CREATE_CHAT_ROOM_ERROR",
+ new String[]{chatRoomName}),
+ ex)
+ .showDialog();
+ }
+ catch (OperationNotSupportedException ex)
+ {
+ new ErrorDialog(
+ GuiActivator.getUIService().getMainFrame(),
+ GuiActivator.getResources().getI18NString("service.gui.ERROR"),
+ GuiActivator.getResources().getI18NString(
+ "service.gui.CREATE_CHAT_ROOM_ERROR",
+ new String[]{chatRoomName}),
+ ex)
+ .showDialog();
+ }
+
+ if(chatRoom != null)
+ {
+ AdHocChatRoomProviderWrapper parentProvider
+ = adHocChatRoomList.findServerWrapperFromProvider(
+ protocolProvider);
+
+ chatRoomWrapper = new AdHocChatRoomWrapper(
+ parentProvider, chatRoom);
+ parentProvider.addAdHocChatRoom(chatRoomWrapper);
+ adHocChatRoomList.addAdHocChatRoom(chatRoomWrapper);
+
+ fireAdHocChatRoomListChangedEvent(
+ chatRoomWrapper,
+ AdHocChatRoomListChangeEvent.AD_HOC_CHAT_ROOM_ADDED);
+ }
+
+ return chatRoomWrapper;
+ }
+
+ /**
      * Join chat room.
      * @param chatRoomWrapper
      */
@@ -592,9 +840,9 @@
         if(chatRoom == null)
         {
             new ErrorDialog(
- GuiActivator.getUIService().getMainFrame(),
- GuiActivator.getResources().getI18NString("service.gui.WARNING"),
- GuiActivator.getResources().getI18NString(
+ GuiActivator.getUIService().getMainFrame(),
+ GuiActivator.getResources().getI18NString("service.gui.WARNING"),
+ GuiActivator.getResources().getI18NString(
                         "service.gui.CHAT_ROOM_NOT_CONNECTED",
                         new String[]{chatRoomWrapper.getChatRoomName()}))
                     .showDialog();
@@ -606,6 +854,31 @@
     }

     /**
+ * Joins the given ad-hoc chat room
+ *
+ * @param chatRoomWrapper
+ */
+ public void joinChatRoom(AdHocChatRoomWrapper chatRoomWrapper)
+ {
+ AdHocChatRoom chatRoom = chatRoomWrapper.getAdHocChatRoom();
+
+ if(chatRoom == null)
+ {
+ new ErrorDialog(
+ GuiActivator.getUIService().getMainFrame(),
+ GuiActivator.getResources().getI18NString("service.gui.WARNING"),
+ GuiActivator.getResources().getI18NString(
+ "service.gui.CHAT_ROOM_NOT_CONNECTED",
+ new String[]{chatRoomWrapper.getAdHocChatRoomName()}))
+ .showDialog();
+
+ return;
+ }
+
+ new JoinAdHocChatRoomTask(chatRoomWrapper).execute();
+ }
+
+ /**
      * Removes the given chat room from the UI.
      *
      * @param chatRoomWrapper the chat room to remove.
@@ -655,7 +928,41 @@
         chatWindowManager.openChat(
             chatWindowManager.getMultiChat(chatRoomWrapper), true);
     }
+
+ /**
+ * Joins the given chat room and manages all the exceptions that could
+ * occur during the join process.
+ *
+ * @param chatRoom the chat room to join
+ */
+ public void joinChatRoom(AdHocChatRoom chatRoom)
+ {
+ AdHocChatRoomWrapper chatRoomWrapper
+ = adHocChatRoomList.findChatRoomWrapperFromAdHocChatRoom(chatRoom);
+
+ if(chatRoomWrapper == null)
+ {
+ AdHocChatRoomProviderWrapper parentProvider
+ = adHocChatRoomList.findServerWrapperFromProvider(
+ chatRoom.getParentProvider());
+
+ chatRoomWrapper =
+ new AdHocChatRoomWrapper(parentProvider, chatRoom);
+
+ adHocChatRoomList.addAdHocChatRoom(chatRoomWrapper);

+ fireAdHocChatRoomListChangedEvent(
+ chatRoomWrapper,
+ AdHocChatRoomListChangeEvent.AD_HOC_CHAT_ROOM_ADDED);
+ }
+
+ this.joinChatRoom(chatRoomWrapper);
+ ChatWindowManager chatWindowManager
+ = GuiActivator.getUIService().getChatWindowManager();
+ chatWindowManager.openChat(
+ chatWindowManager.getAdHocMultiChat(chatRoomWrapper), true);
+ }
+
     /**
      * Joins the given chat room and manages all the exceptions that could
      * occur during the join process.
@@ -741,11 +1048,11 @@
         if (chatRoom == null)
         {
             new ErrorDialog(
- GuiActivator.getUIService().getMainFrame(),
- GuiActivator.getResources().getI18NString("service.gui.WARNING"),
- GuiActivator.getResources().getI18NString(
- "service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED"))
- .showDialog();
+ GuiActivator.getUIService().getMainFrame(),
+ GuiActivator.getResources().getI18NString("service.gui.WARNING"),
+ GuiActivator.getResources().getI18NString(
+ "service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED"))
+ .showDialog();

             return;
         }
@@ -869,10 +1176,39 @@
     }

     /**
+ * Adds the given<tt>AdHocChatRoomListChangeListener</tt> that will listen
+ * for all changes of the chat room list data model.
+ *
+ * @param l the listener to add.
+ */
+ public void addAdHocChatRoomListChangeListener(
+ AdHocChatRoomListChangeListener l)
+ {
+ synchronized (adHoclistChangeListeners)
+ {
+ adHoclistChangeListeners.add(l);
+ }
+ }
+
+ /**
+ * Removes the given<tt>AdHocChatRoomListChangeListener</tt>.
+ *
+ * @param l the listener to remove.
+ */
+ public void removeAdHocChatRoomListChangeListener(
+ AdHocChatRoomListChangeListener l)
+ {
+ synchronized (adHoclistChangeListeners)
+ {
+ adHoclistChangeListeners.remove(l);
+ }
+ }
+
+ /**
      * Notifies all interested listeners that a change in the chat room list
      * model has occurred.
      */
- private void fireChatRoomListChangedEvent( ChatRoomWrapper chatRoomWrapper,
+ private void fireChatRoomListChangedEvent( ChatRoomWrapper chatRoomWrapper,
                                                 int eventID)
     {
         ChatRoomListChangeEvent evt
@@ -883,6 +1219,23 @@
             l.contentChanged(evt);
         }
     }
+
+ /**
+ * Notifies all interested listeners that a change in the chat room list
+ * model has occurred.
+ */
+ private void fireAdHocChatRoomListChangedEvent(
+ AdHocChatRoomWrapper adHocChatRoomWrapper,
+ int eventID)
+ {
+ AdHocChatRoomListChangeEvent evt
+ = new AdHocChatRoomListChangeEvent(adHocChatRoomWrapper, eventID);
+
+ for (AdHocChatRoomListChangeListener l : adHoclistChangeListeners)
+ {
+ l.contentChanged(evt);
+ }
+ }

     /**
      * Closes the chat corresponding to the given chat room wrapper, if such
@@ -913,6 +1266,34 @@
     }

     /**
+ * Closes the chat corresponding to the given ad-hoc chat room wrapper, if
+ * such exists.
+ *
+ * @param chatRoomWrapper the ad-hoc chat room wrapper for which we search a
+ * chat to close.
+ */
+ private void closeAdHocChatRoom(AdHocChatRoomWrapper chatRoomWrapper)
+ {
+ final ChatWindowManager chatWindowManager
+ = GuiActivator.getUIService().getChatWindowManager();
+
+ if(chatWindowManager.isChatOpenedForAdHocChatRoom(chatRoomWrapper))
+ {
+ final ChatPanel chatPanel
+ = chatWindowManager.getAdHocMultiChat(chatRoomWrapper);
+
+ // We have to be sure that we close the chat in the swing thread
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ public void run()
+ {
+ chatWindowManager.closeChat(chatPanel);
+ }
+ });
+ }
+ }
+
+ /**
      * Handles<tt>ServiceEvent</tt>s triggered by adding or removing a
      * ProtocolProviderService. Updates the list of available chat rooms and
      * chat room servers.
@@ -944,21 +1325,39 @@
         Object multiUserChatOpSet
             = protocolProvider
                 .getOperationSet(OperationSetMultiUserChat.class);
+
+ Object multiUserChatAdHocOpSet
+ = protocolProvider
+ .getOperationSet(OperationSetAdHocMultiUserChat.class);

- // We don't care if there's no group chat operation set.
- if (multiUserChatOpSet == null)
- {
- return;
- }
-
- if (event.getType() == ServiceEvent.REGISTERED)
+ if (multiUserChatOpSet == null&& multiUserChatAdHocOpSet != null)
         {
- chatRoomList.addChatProvider(protocolProvider);
+ if (event.getType() == ServiceEvent.REGISTERED)
+ {
+ adHocChatRoomList.addChatProvider(protocolProvider);
+ }
+ else if (event.getType() == ServiceEvent.UNREGISTERING)
+ {
+ adHocChatRoomList.removeChatProvider(protocolProvider);
+ }
+ }
+ else if (multiUserChatAdHocOpSet == null&& multiUserChatOpSet != null)
+ {
+ if (event.getType() == ServiceEvent.REGISTERED)
+ {
+ chatRoomList.addChatProvider(protocolProvider);
+ }
+ else if (event.getType() == ServiceEvent.UNREGISTERING)
+ {
+ chatRoomList.removeChatProvider(protocolProvider);
+ }
         }
- else if (event.getType() == ServiceEvent.UNREGISTERING)
+ else
         {
- chatRoomList.removeChatProvider(protocolProvider);
+ return;
         }
+
     }

     /**
@@ -1103,12 +1502,135 @@
             {
                 new ErrorDialog(
                     GuiActivator.getUIService().getMainFrame(),
- GuiActivator.getResources().getI18NString("service.gui.ERROR"),
- errorMessage).showDialog();
+ GuiActivator.getResources().getI18NString(
+ "service.gui.ERROR"), errorMessage).showDialog();
             }
         }
     }
+
+ /**
+ * Joins an ad-hoc chat room in an asynchronous way.
+ */
+ private static class JoinAdHocChatRoomTask
+ extends SwingWorker<String, Object>
+ {
+ private static final String SUCCESS = "Success";
+
+ private static final String AUTHENTICATION_FAILED
+ = "AuthenticationFailed";
+
+ private static final String REGISTRATION_REQUIRED
+ = "RegistrationRequired";
+
+ private static final String PROVIDER_NOT_REGISTERED
+ = "ProviderNotRegistered";
+
+ private static final String SUBSCRIPTION_ALREADY_EXISTS
+ = "SubscriptionAlreadyExists";
+
+ private static final String UNKNOWN_ERROR
+ = "UnknownError";
+
+ private final AdHocChatRoomWrapper adHocChatRoomWrapper;
+
+ JoinAdHocChatRoomTask(AdHocChatRoomWrapper chatRoomWrapper)
+ {
+ this.adHocChatRoomWrapper = chatRoomWrapper;
+ }
+
+ /**
+ * @override {@link SwingWorker}{@link #doInBackground()} to perform
+ * all asynchronous tasks.
+ */
+ public String doInBackground()
+ {
+ AdHocChatRoom chatRoom = adHocChatRoomWrapper.getAdHocChatRoom();
+
+ try
+ {
+ chatRoom.join();
+
+ return SUCCESS;
+ }
+ catch (OperationFailedException e)
+ {
+ logger.trace("Failed to join ad-hoc chat room: "
+ + chatRoom.getName(), e);
+
+ switch (e.getErrorCode())
+ {
+ case OperationFailedException.AUTHENTICATION_FAILED:
+ return AUTHENTICATION_FAILED;
+ case OperationFailedException.REGISTRATION_REQUIRED:
+ return REGISTRATION_REQUIRED;
+ case OperationFailedException.PROVIDER_NOT_REGISTERED:
+ return PROVIDER_NOT_REGISTERED;
+ case OperationFailedException.SUBSCRIPTION_ALREADY_EXISTS:
+ return SUBSCRIPTION_ALREADY_EXISTS;
+ default:
+ return UNKNOWN_ERROR;
+ }
+ }
+ }
+
+ /**
+ * @override {@link SwingWorker}{@link #done()} to perform UI changes
+ * after the ad-hoc chat room join task has finished.
+ */
+ protected void done()
+ {
+ String returnCode = null;
+ try
+ {
+ returnCode = get();
+ }
+ catch (InterruptedException ignore)
+ {}
+ catch (ExecutionException ignore)
+ {}
+
+ ConfigurationManager.updateChatRoomStatus(
+ adHocChatRoomWrapper.getParentProvider().getProtocolProvider(),
+ adHocChatRoomWrapper.getAdHocChatRoomID(),
+ Constants.ONLINE_STATUS);
+
+ String errorMessage = null;
+ if(PROVIDER_NOT_REGISTERED.equals(returnCode))
+ {
+ errorMessage
+ = GuiActivator.getResources()
+ .getI18NString("service.gui.CHAT_ROOM_NOT_CONNECTED",
+ new String[]{
+ adHocChatRoomWrapper.getAdHocChatRoomName()});
+ }
+ else if(SUBSCRIPTION_ALREADY_EXISTS.equals(returnCode))
+ {
+ errorMessage
+ = GuiActivator.getResources()
+ .getI18NString("service.gui.CHAT_ROOM_ALREADY_JOINED",
+ new String[]{
+ adHocChatRoomWrapper.getAdHocChatRoomName()});
+ }
+ else
+ {
+ errorMessage
+ = GuiActivator.getResources()
+ .getI18NString("service.gui.FAILED_TO_JOIN_CHAT_ROOM",
+ new String[]{
+ adHocChatRoomWrapper.getAdHocChatRoomName()});
+ }

+ if (!SUCCESS.equals(returnCode)
+&& !AUTHENTICATION_FAILED.equals(returnCode))
+ {
+ new ErrorDialog(
+ GuiActivator.getUIService().getMainFrame(),
+ GuiActivator.getResources().getI18NString(
+ "service.gui.ERROR"), errorMessage).showDialog();
+ }
+ }
+ }
+
     /**
      * Finds a chat room in asynchronous way.
      */
@@ -1199,4 +1721,218 @@
             return null;
         }
     }
+
+ public void invitationReceived(AdHocChatRoomInvitationReceivedEvent evt) {
+ logger.setLevelInfo();
+ logger.info("Invitation received: "+evt.toString());
+ OperationSetAdHocMultiUserChat multiUserChatOpSet
+ = evt.getSourceOperationSet();
+
+ InvitationReceivedDialog dialog = new InvitationReceivedDialog(
+ this, multiUserChatOpSet, evt.getInvitation());
+
+ dialog.setVisible(true);
+ }
+
+ /**
+ * Implements the<tt>AdHocChatRoomMessageListener.messageDelivered</tt>
+ * method.
+ *<br>
+ * Shows the message in the conversation area and clears the write message
+ * area.
+ */
+ public void messageDelivered(AdHocChatRoomMessageDeliveredEvent evt) {
+ AdHocChatRoom sourceChatRoom = (AdHocChatRoom) evt.getSource();
+
+ logger.setLevelInfo();
+ logger.info("MESSAGE DELIVERED to ad-hoc chat room: "
+ + sourceChatRoom.getName());
+
+ Message msg = evt.getMessage();
+
+ ChatPanel chatPanel = null;
+
+ ChatWindowManager chatWindowManager
+ = GuiActivator.getUIService().getChatWindowManager();
+
+ if(chatWindowManager.isChatOpenedForAdHocChatRoom(sourceChatRoom))
+ {
+ chatPanel = chatWindowManager.getAdHocMultiChat(sourceChatRoom);
+ }
+
+ String messageType = null;
+
+ if (evt.getEventType() ==
+ AdHocChatRoomMessageDeliveredEvent.CONVERSATION_MESSAGE_DELIVERED)
+ {
+ messageType = Chat.OUTGOING_MESSAGE;
+ }
+ else if (evt.getEventType()
+ == AdHocChatRoomMessageDeliveredEvent.ACTION_MESSAGE_DELIVERED)
+ {
+ messageType = Chat.ACTION_MESSAGE;
+ }
+
+ if(chatPanel != null)
+ {
+ chatPanel.addMessage(sourceChatRoom.getParentProvider()
+ .getAccountID().getUserID(),
+ evt.getTimestamp(),
+ messageType,
+ msg.getContent(),
+ msg.getContentType());
+ }
+ else
+ {
+ logger.setLevelError();
+ logger.error("chat panel is null, message NOT DELIVERED !");
+ }
+ }
+
+ /**
+ * Implements<tt>AdHocChatRoomMessageListener.messageDeliveryFailed</tt>
+ * method.
+ *<br>
+ * In the conversation area shows an error message, explaining the problem.
+ */
+ public void messageDeliveryFailed(
+ AdHocChatRoomMessageDeliveryFailedEvent evt) {
+ AdHocChatRoom sourceChatRoom = (AdHocChatRoom) evt.getSource();
+
+ String errorMsg = null;
+
+ Message sourceMessage = (Message) evt.getSource();
+
+ Contact destParticipant = evt.getDestinationParticipant();
+
+ if (evt.getErrorCode()
+ == MessageDeliveryFailedEvent.OFFLINE_MESSAGES_NOT_SUPPORTED)
+ {
+ errorMsg = GuiActivator.getResources().getI18NString(
+ "service.gui.MSG_DELIVERY_NOT_SUPPORTED");
+ }
+ else if (evt.getErrorCode()
+ == MessageDeliveryFailedEvent.NETWORK_FAILURE)
+ {
+ errorMsg = GuiActivator.getResources()
+ .getI18NString("service.gui.MSG_NOT_DELIVERED");
+ }
+ else if (evt.getErrorCode()
+ == MessageDeliveryFailedEvent.PROVIDER_NOT_REGISTERED)
+ {
+ errorMsg = GuiActivator.getResources().getI18NString(
+ "service.gui.MSG_SEND_CONNECTION_PROBLEM");
+ }
+ else if (evt.getErrorCode()
+ == MessageDeliveryFailedEvent.INTERNAL_ERROR)
+ {
+ errorMsg = GuiActivator.getResources().getI18NString(
+ "service.gui.MSG_DELIVERY_INTERNAL_ERROR");
+ }
+ else
+ {
+ errorMsg = GuiActivator.getResources().getI18NString(
+ "service.gui.MSG_DELIVERY_UNKNOWN_ERROR");
+ }
+
+ ChatWindowManager chatWindowManager
+ = GuiActivator.getUIService().getChatWindowManager();
+
+ ChatPanel chatPanel
+ = chatWindowManager.getAdHocMultiChat(sourceChatRoom);
+
+ chatPanel.addMessage(
+ destParticipant.getDisplayName(),
+ System.currentTimeMillis(),
+ Chat.OUTGOING_MESSAGE,
+ sourceMessage.getContent(),
+ sourceMessage.getContentType());
+
+ chatPanel.addErrorMessage(
+ destParticipant.getDisplayName(),
+ errorMsg);
+
+ chatWindowManager.openChat(chatPanel, false);
+ }
+
+ /**
+ * Implements the<tt>AdHocChatRoomMessageListener.messageReceived</tt>
+ * method.
+ *<br>
+ * Obtains the corresponding<tt>ChatPanel</tt> and process the message
+ * there.
+ */
+ public void messageReceived(AdHocChatRoomMessageReceivedEvent evt)
+ {
+ AdHocChatRoom sourceChatRoom = (AdHocChatRoom) evt.getSource();
+ Contact sourceParticipant = evt.getSourceChatRoomParticipant();
+
+ String messageType = null;
+
+ switch (evt.getEventType())
+ {
+ case AdHocChatRoomMessageReceivedEvent.CONVERSATION_MESSAGE_RECEIVED:
+ messageType = Chat.INCOMING_MESSAGE;
+ break;
+ case AdHocChatRoomMessageReceivedEvent.SYSTEM_MESSAGE_RECEIVED:
+ messageType = Chat.SYSTEM_MESSAGE;
+ break;
+ case AdHocChatRoomMessageReceivedEvent.ACTION_MESSAGE_RECEIVED:
+ messageType = Chat.ACTION_MESSAGE;
+ break;
+ }
+
+ logger.info("MESSAGE RECEIVED from contact: "
+ + sourceParticipant.getAddress());
+
+ Message message = evt.getMessage();
+
+ ChatPanel chatPanel = null;
+
+ ChatWindowManager chatWindowManager
+ = GuiActivator.getUIService().getChatWindowManager();
+
+ chatPanel = chatWindowManager
+ .getAdHocMultiChat(sourceChatRoom, message.getMessageUID());
+
+ String messageContent = message.getContent();
+
+ chatPanel.addMessage(
+ sourceParticipant.getDisplayName(),
+ evt.getTimestamp(),
+ messageType,
+ messageContent,
+ message.getContentType());
+
+ chatWindowManager.openChat(chatPanel, false);
+
+ // Fire notification
+ boolean fireChatNotification;
+
+ String nickname = sourceChatRoom.getName();
+
+ fireChatNotification =
+ (nickname == null)
+ || messageContent.toLowerCase().contains(
+ nickname.toLowerCase());
+
+ if (fireChatNotification)
+ {
+ String title
+ = GuiActivator.getResources().getI18NString(
+ "service.gui.MSG_RECEIVED",
+ new String[] { sourceParticipant.getDisplayName() });
+
+ NotificationManager.fireChatNotification(
+ sourceChatRoom,
+ NotificationManager.INCOMING_MESSAGE,
+ title,
+ messageContent);
+ }
+
+ }
+
+ public void invitationRejected(AdHocChatRoomInvitationRejectedEvent evt)
+ {
+ }
}

Modified: trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/InvitationReceivedDialog.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/InvitationReceivedDialog.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/InvitationReceivedDialog.java&p2=trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/InvitationReceivedDialog.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/InvitationReceivedDialog.java (original)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/InvitationReceivedDialog.java 2009-09-14 15:51:47+0000
@@ -20,62 +20,76 @@
  * The dialog that pops up when a chat room invitation is received.
  *
  * @author Yana Stamcheva
+ * @author Valentin Martinet
  */
public class InvitationReceivedDialog
     extends SIPCommDialog
     implements ActionListener
-{
+{
     private final JTextArea infoTextArea = new JTextArea();
-
+
     private final JTextArea invitationReasonTextArea = new JTextArea();
-
+
     private final JPanel reasonPanel = new JPanel(new BorderLayout());
-
+
     private final JLabel reasonLabel = new JLabel(
         GuiActivator.getResources().getI18NString("service.gui.REASON") + ": ");
-
+
     private final JTextField reasonField = new JTextField();

     private final JPanel dataPanel = new JPanel(new BorderLayout(10, 10));
-
- private final JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
-
+
+ private final JPanel buttonsPanel
+ = new JPanel(new FlowLayout(FlowLayout.RIGHT));
+
     private final JButton acceptButton = new JButton(
         GuiActivator.getResources().getI18NString("service.gui.ACCEPT"));
-
+
     private final JButton rejectButton = new JButton(
         GuiActivator.getResources().getI18NString("service.gui.REJECT"));
-
+
     private final JButton ignoreButton = new JButton(
         GuiActivator.getResources().getI18NString("service.gui.IGNORE"));
-
+
     private final JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
-
+
     private final JPanel northPanel = new JPanel(new BorderLayout(10, 10));
-
+
     private final JLabel iconLabel = new JLabel(new ImageIcon(
             ImageLoader.getImage(ImageLoader.INVITE_DIALOG_ICON)));
-
+
     private final String title = GuiActivator.getResources()
         .getI18NString("service.gui.INVITATION_RECEIVED");
-
+
     /**
      * The<tt>ChatRoomInvitation</tt> for which this dialog is.
      */
- private final ChatRoomInvitation invitation;
-
+ private ChatRoomInvitation invitation = null;;
+
+ /**
+ * The<tt>AdHocChatRoomInvitation</tt> for which this dialog is, in case of
+ * an<tt>AdHocChatRoom</tt>.
+ */
+ private AdHocChatRoomInvitation invitationAdHoc = null;
+
     /**
      * The<tt>MultiUserChatManager</tt> is the one that deals with invitation
      * events.
      */
     private final ConferenceChatManager multiUserChatManager;
-
+
     /**
      * The operation set that would handle the rejection if the user choose to
      * reject the invitation.
      */
- private final OperationSetMultiUserChat multiUserChatOpSet;
-
+ private OperationSetMultiUserChat multiUserChatOpSet = null;;
+
+ /**
+ * The operation set that would handle the rejection if the user choose to
+ * reject the invitation, in case of an<tt>AdHocChatRoom</tt>.
+ */
+ private OperationSetAdHocMultiUserChat multiUserChatAdHocOpSet = null;;
+
     /**
      * Constructs the<tt>ChatInviteDialog</tt>.
      *
@@ -122,32 +136,92 @@
             this.dataPanel.add(invitationReasonTextArea, BorderLayout.CENTER);
         }

+ this.initGUI();
+ }
+
+ /**
+ * Constructs the<tt>ChatInviteDialog</tt>, in case of an
+ *<tt>AdHocChatRoom</tt>.
+ *
+ * @param multiUserChatManager the<tt>MultiUserChatManager</> is the one
+ * that deals with invitation events
+ * @param multiUserChatAdHocOpSet the operation set that would handle the
+ * rejection if the user choose to reject the invitation
+ * @param invitationAdHoc the invitation that this dialog represents
+ */
+ public InvitationReceivedDialog (ConferenceChatManager multiUserChatManager,
+ OperationSetAdHocMultiUserChat multiUserChatAdHocOpSet,
+ AdHocChatRoomInvitation invitationAdHoc)
+ {
+ super(GuiActivator.getUIService().getMainFrame());
+
+ this.multiUserChatManager = multiUserChatManager;
+
+ this.multiUserChatAdHocOpSet = multiUserChatAdHocOpSet;
+
+ this.invitationAdHoc = invitationAdHoc;
+
+ this.setModal(false);
+
+ this.setTitle(title);
+
+ this.mainPanel.setPreferredSize(new Dimension(400, 230));
+
+// this.mainPanel.setOpaque(false);
+
+ infoTextArea.setText(
+ GuiActivator.getResources().getI18NString(
+ "service.gui.INVITATION_RECEIVED_MSG",
+ new String[] {
+ invitationAdHoc.getInviter(),
+ invitationAdHoc.getTargetAdHocChatRoom().getName()}));
+
+ if(invitationAdHoc.getReason() != null
+&& !invitationAdHoc.getReason().equals(""))
+ {
+ invitationReasonTextArea.setText(invitationAdHoc.getReason());
+ invitationReasonTextArea.setBorder(
+ BorderFactory.createTitledBorder(
+ GuiActivator.getResources()
+ .getI18NString("service.gui.INVITATION")));
+
+ this.dataPanel.add(invitationReasonTextArea, BorderLayout.CENTER);
+ }
+
+ this.initGUI();
+ }
+
+ /**
+ * Initializes and builds the GUI.
+ */
+ public void initGUI()
+ {
         this.infoTextArea.setFont(infoTextArea.getFont().deriveFont(Font.BOLD));
         this.infoTextArea.setLineWrap(true);
         this.infoTextArea.setOpaque(false);
         this.infoTextArea.setWrapStyleWord(true);
         this.infoTextArea.setEditable(false);
-
+
         this.northPanel.add(iconLabel, BorderLayout.WEST);
         this.northPanel.add(infoTextArea, BorderLayout.CENTER);
         this.northPanel.setOpaque(false);
-
+
         this.reasonPanel.add(reasonLabel, BorderLayout.WEST);
         this.reasonPanel.add(reasonField, BorderLayout.CENTER);
         this.reasonPanel.setOpaque(false);

         this.dataPanel.add(reasonPanel, BorderLayout.SOUTH);
         this.dataPanel.setOpaque(false);
-
+
         this.acceptButton.addActionListener(this);
         this.rejectButton.addActionListener(this);
         this.ignoreButton.addActionListener(this);
-
+
         this.buttonsPanel.add(acceptButton);
         this.buttonsPanel.add(rejectButton);
         this.buttonsPanel.add(ignoreButton);
         this.buttonsPanel.setOpaque(false);
-
+
         this.getRootPane().setDefaultButton(acceptButton);
         this.acceptButton.setMnemonic(
             GuiActivator.getResources().getI18nMnemonic("service.gui.ACCEPT"));
@@ -155,18 +229,18 @@
             GuiActivator.getResources().getI18nMnemonic("service.gui.REJECT"));
         this.ignoreButton.setMnemonic(
             GuiActivator.getResources().getI18nMnemonic("service.gui.IGNORE"));
-
+
         this.mainPanel.setBorder(
             BorderFactory.createEmptyBorder(15, 15, 15, 15));
-
+
         this.mainPanel.add(northPanel, BorderLayout.NORTH);
         this.mainPanel.add(dataPanel, BorderLayout.CENTER);
         this.mainPanel.add(buttonsPanel, BorderLayout.SOUTH);
         this.mainPanel.setOpaque(false);
-
+
         this.getContentPane().add(mainPanel);
     }
-
+
     /**
      * Handles the<tt>ActionEvent</tt> triggered when one user clicks
      * on one of the buttons.
@@ -174,17 +248,31 @@
     public void actionPerformed(ActionEvent e)
     {
         JButton button = (JButton)e.getSource();
-
+
         if (button.equals(acceptButton))
         {
- multiUserChatManager.acceptInvitation(invitation);
+ if(invitationAdHoc == null)
+ multiUserChatManager.acceptInvitation(invitation);
+ else
+ try
+ {
+ multiUserChatManager.acceptInvitation(
+ invitationAdHoc, multiUserChatAdHocOpSet);
+ } catch (OperationFailedException e1)
+ {
+ e1.printStackTrace();
+ }
         }
         else if (button.equals(rejectButton))
         {
- multiUserChatManager.rejectInvitation(multiUserChatOpSet,
- invitation, reasonField.getText());
+ if(multiUserChatAdHocOpSet == null&& invitationAdHoc == null)
+ multiUserChatManager.rejectInvitation(multiUserChatOpSet,
+ invitation, reasonField.getText());
+ else
+ multiUserChatManager.rejectInvitation(multiUserChatAdHocOpSet,
+ invitationAdHoc, reasonField.getText());
         }
-
+
         this.dispose();
     }

Added: trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/AdHocChatRoomList.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/AdHocChatRoomList.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/AdHocChatRoomList.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,308 @@
+/*
+ * 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.chatroomslist;
+
+import java.util.*;
+
+import net.java.sip.communicator.impl.gui.*;
+import net.java.sip.communicator.impl.gui.main.chat.conference.*;
+import net.java.sip.communicator.service.configuration.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.util.*;
+
+import org.osgi.framework.*;
+
+/**
+ * The<tt>AdHocChatRoomsList</tt> is the list containing all ad-hoc chat rooms.
+ *
+ * @author Valentin Martinet
+ */
+public class AdHocChatRoomList
+{
+ private static final Logger logger
+ = Logger.getLogger(AdHocChatRoomList.class);
+
+ /**
+ * The list containing all chat servers and ad-hoc rooms.
+ */
+ private final List<AdHocChatRoomProviderWrapper> providersList
+ = new Vector<AdHocChatRoomProviderWrapper>();
+
+ /**
+ * Initializes the list of ad-hoc chat rooms.
+ */
+ public void loadList()
+ {
+ try
+ {
+ ServiceReference[] serRefs
+ = GuiActivator.bundleContext.getServiceReferences(
+ ProtocolProviderService.class.getName(),
+ null);
+
+ // If we don't have providers at this stage we just return.
+ if (serRefs == null)
+ return;
+ logger.setLevelDebug();
+ for (ServiceReference serRef : serRefs)
+ {
+ ProtocolProviderService protocolProvider
+ = (ProtocolProviderService)
+ GuiActivator.bundleContext.getService(serRef);
+
+ Object adHocMultiUserChatOpSet
+ = protocolProvider
+ .getOperationSet(OperationSetAdHocMultiUserChat.class);
+
+ if (adHocMultiUserChatOpSet != null)
+ {
+ this.addChatProvider(protocolProvider);
+ }
+ }
+ }
+ catch (InvalidSyntaxException e)
+ {
+ logger.error("Failed to obtain service references.", e);
+ }
+ }
+
+ /**
+ * Adds a chat server and all its existing ad-hoc chat rooms.
+ *
+ * @param pps the<tt>ProtocolProviderService</tt> corresponding to the chat
+ * server
+ * @param adHocMultiUserChatOperationSet the
+ *<tt>OperationSetAdHocMultiUserChat</tt> from which we manage ad-hoc chat
+ * rooms
+ */
+ public void addChatProvider(ProtocolProviderService pps)
+ {
+ AdHocChatRoomProviderWrapper chatRoomProvider
+ = new AdHocChatRoomProviderWrapper(pps);
+
+ providersList.add(chatRoomProvider);
+
+ ConfigurationService configService
+ = GuiActivator.getConfigurationService();
+
+ String prefix = "net.java.sip.communicator.impl.gui.accounts";
+
+ List<String> accounts =
+ configService.getPropertyNamesByPrefix(prefix, true);
+
+ for (String accountRootPropName : accounts) {
+ String accountUID
+ = configService.getString(accountRootPropName);
+
+ if(accountUID.equals(pps
+ .getAccountID().getAccountUniqueID()))
+ {
+ List<String> chatRooms = configService
+ .getPropertyNamesByPrefix(
+ accountRootPropName + ".chatRooms", true);
+
+ for (String chatRoomPropName : chatRooms)
+ {
+ String chatRoomID
+ = configService.getString(chatRoomPropName);
+
+ String chatRoomName = configService.getString(
+ chatRoomPropName + ".chatRoomName");
+
+ AdHocChatRoomWrapper chatRoomWrapper
+ = new AdHocChatRoomWrapper( chatRoomProvider,
+ chatRoomID,
+ chatRoomName);
+
+ chatRoomProvider.addAdHocChatRoom(chatRoomWrapper);
+ }
+ }
+ }
+ }
+
+ /**
+ * Removes the corresponding server and all related ad-hoc chat rooms from
+ * this list.
+ *
+ * @param pps the<tt>ProtocolProviderService</tt> corresponding to the
+ * server to remove
+ */
+ public void removeChatProvider(ProtocolProviderService pps)
+ {
+ AdHocChatRoomProviderWrapper wrapper =
+ findServerWrapperFromProvider(pps);
+
+ if (wrapper != null)
+ removeChatProvider(wrapper);
+ }
+
+ /**
+ * Removes the corresponding server and all related ad-hoc chat rooms from
+ * this list.
+ *
+ * @param adHocChatRoomProvider the<tt>AdHocChatRoomProviderWrapper</tt>
+ * corresponding to the server to remove
+ */
+ private void removeChatProvider(
+ AdHocChatRoomProviderWrapper adHocChatRoomProvider)
+ {
+ providersList.remove(adHocChatRoomProvider);
+
+ ConfigurationService configService
+ = GuiActivator.getConfigurationService();
+ String prefix = "net.java.sip.communicator.impl.gui.accounts";
+ String providerAccountUID
+ = adHocChatRoomProvider
+ .getProtocolProvider().getAccountID().getAccountUniqueID();
+
+ for (String accountRootPropName
+ : configService.getPropertyNamesByPrefix(prefix, true))
+ {
+ String accountUID
+ = configService.getString(accountRootPropName);
+
+ if(accountUID.equals(providerAccountUID))
+ {
+ List<String> chatRooms
+ = configService.getPropertyNamesByPrefix(
+ accountRootPropName + ".chatRooms",
+ true);
+
+ for (String chatRoomPropName : chatRooms)
+ {
+ configService.setProperty(
+ chatRoomPropName + ".chatRoomName",
+ null);
+ }
+
+ configService.setProperty(accountRootPropName, null);
+ }
+ }
+ }
+
+ /**
+ * Adds a chat room to this list.
+ *
+ * @param adHocChatRoomWrapper the<tt>AdHocChatRoom</tt> to add
+ */
+ public void addAdHocChatRoom(AdHocChatRoomWrapper adHocChatRoomWrapper)
+ {
+ AdHocChatRoomProviderWrapper adHocChatRoomProvider
+ = adHocChatRoomWrapper.getParentProvider();
+
+ if (!adHocChatRoomProvider.containsAdHocChatRoom(adHocChatRoomWrapper))
+ adHocChatRoomProvider.addAdHocChatRoom(adHocChatRoomWrapper);
+ }
+
+ /**
+ * Removes the given<tt>AdHocChatRoom</tt> from the list of all ad-hoc
+ * chat rooms.
+ *
+ * @param adHocChatRoomWrapper the<tt>AdHocChatRoomWrapper</> to remove
+ */
+ public void removeChatRoom(AdHocChatRoomWrapper adHocChatRoomWrapper)
+ {
+ AdHocChatRoomProviderWrapper adHocChatRoomProvider
+ = adHocChatRoomWrapper.getParentProvider();
+
+ if (providersList.contains(adHocChatRoomProvider))
+ {
+ adHocChatRoomProvider.removeChatRoom(adHocChatRoomWrapper);
+ }
+ }
+
+ /**
+ * Returns the<tt>AdHocChatRoomWrapper</tt> that correspond to the given
+ *<tt>AdHocChatRoom</tt>. If the list of ad-hoc chat rooms doesn't contain
+ * a corresponding wrapper - returns null.
+ *
+ * @param adHocChatRoom the<tt>ChatRoom</tt> that we're looking for
+ * @return the<tt>ChatRoomWrapper</tt> object corresponding to the given
+ *<tt>ChatRoom</tt>
+ */
+ public AdHocChatRoomWrapper findChatRoomWrapperFromAdHocChatRoom(
+ AdHocChatRoom adHocChatRoom)
+ {
+ for (AdHocChatRoomProviderWrapper provider : providersList)
+ {
+ AdHocChatRoomWrapper chatRoomWrapper
+ = provider.findChatRoomWrapperForAdHocChatRoom(
+ adHocChatRoom);
+
+ if (chatRoomWrapper != null)
+ {
+ // stored chatrooms has no chatroom, but their
+ // id is the same as the chatroom we are searching wrapper
+ // for
+ if(chatRoomWrapper.getAdHocChatRoom() == null)
+ {
+ chatRoomWrapper.setAdHocChatRoom(adHocChatRoom);
+ }
+
+ return chatRoomWrapper;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the<tt>AdHocChatRoomProviderWrapper</tt> that correspond to the
+ * given<tt>ProtocolProviderService</tt>. If the list doesn't contain a
+ * corresponding wrapper - returns null.
+ *
+ * @param protocolProvider the protocol provider that we're looking for
+ * @return the<tt>AdHocChatRoomProvider</tt> object corresponding to
+ * the given<tt>ProtocolProviderService</tt>
+ */
+ public AdHocChatRoomProviderWrapper findServerWrapperFromProvider(
+ ProtocolProviderService protocolProvider)
+ {
+ for(AdHocChatRoomProviderWrapper chatRoomProvider : providersList)
+ {
+ if(chatRoomProvider.getProtocolProvider().equals(protocolProvider))
+ {
+ return chatRoomProvider;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Goes through the locally stored chat rooms list and for each
+ * {@link AdHocChatRoomWrapper} tries to find the corresponding server
+ * stored {@link AdHocChatRoom} in the specified operation set. Joins
+ * automatically all found ad-hoc chat rooms.
+ *
+ * @param protocolProvider the protocol provider for the account to
+ * synchronize
+ * @param opSet the ad-hoc multi user chat operation set, which give us
+ * access to chat room server
+ */
+ public void synchronizeOpSetWithLocalContactList(
+ ProtocolProviderService protocolProvider,
+ final OperationSetAdHocMultiUserChat opSet)
+ {
+ AdHocChatRoomProviderWrapper chatRoomProvider
+ = findServerWrapperFromProvider(protocolProvider);
+
+ if (chatRoomProvider != null)
+ {
+ chatRoomProvider.synchronizeProvider();
+ }
+ }
+
+ /**
+ * Returns an iterator to the list of ad-hoc chat room providers.
+ *
+ * @return an iterator to the list of ad-hoc chat room providers.
+ */
+ public Iterator<AdHocChatRoomProviderWrapper> getAdHocChatRoomProviders()
+ {
+ return providersList.iterator();
+ }
+}

Added: trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/AdHocChatRoomListChangeEvent.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/AdHocChatRoomListChangeEvent.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/AdHocChatRoomListChangeEvent.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,92 @@
+/*
+ * 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.chatroomslist;
+
+import java.util.*;
+
+import net.java.sip.communicator.impl.gui.main.chat.conference.*;
+
+/**
+ * Parent class for gui ad-hoc chat room events indicating addition and removal
+ * of ad-hoc chat rooms in the gui ad-hoc chat rooms list.
+ *
+ * @author Valentin Martinet
+ */
+public class AdHocChatRoomListChangeEvent
+ extends EventObject
+{
+ private int eventID = -1;
+
+ /**
+ * Indicates that the AdHocChatRoomListChangeEvent instance was triggered by
+ * adding a AdHocChatRoom in the gui.
+ */
+ public static final int AD_HOC_CHAT_ROOM_ADDED = 1;
+
+ /**
+ * Indicates that the AdHocChatRoomListChangeEvent instance was triggered by
+ * removing a AdHocChatRoom from the gui.
+ */
+ public static final int AD_HOC_CHAT_ROOM_REMOVED = 2;
+
+ /**
+ * Indicates that the AdHocChatRoomListChangeEvent instance was triggered by
+ * changing a AdHocChatRoom in the gui (like changing its status, etc.).
+ */
+ public static final int AD_HOC_CHAT_ROOM_CHANGED = 3;
+
+ /**
+ * Creates a new<tt>AdHocChatRoom</tt> event according to the specified
+ * parameters.
+ *
+ * @param source the<tt>AdHocChatRoom</tt> instance that is added to the
+ * AdHocChatRoomsList
+ * @param eventID one of the AD_HOC_CHAT_ROOM_XXX static fields indicating
+ * the nature of the event.
+ */
+ public AdHocChatRoomListChangeEvent(AdHocChatRoomWrapper source,
+ int eventID)
+ {
+ super(source);
+ this.eventID = eventID;
+ }
+
+ /**
+ * Returns the source<tt>AdHocChatRoom</tt>.
+ * @return the source<tt>AdHocChatRoom</tt>.
+ */
+ public AdHocChatRoomWrapper getSourceAdHocChatRoom()
+ {
+ return (AdHocChatRoomWrapper) getSource();
+ }
+
+ /**
+ * Returns a String representation of this<tt>GuiAdHocChatRoomEvent</tt>.
+ *
+ * @return A String representation of this<tt>GuiAdHocChatRoomEvent</tt>.
+ */
+ public String toString()
+ {
+ StringBuffer buff
+ = new StringBuffer("GuiAdHocChatRoomEvent-[ AdHocChatRoomID=");
+ buff.append(getSourceAdHocChatRoom().getAdHocChatRoomName());
+ buff.append(", eventID=").append(getEventID());
+ buff.append(", ProtocolProvider=");
+
+ return buff.toString();
+ }
+
+ /**
+ * Returns an event id specifying whether the type of this event (e.g.
+ * CHAT_ROOM_ADDED or CHAT_ROOM_REMOVED)
+ * @return one of the CHAT_ROOM_XXX int fields of this class.
+ */
+ public int getEventID()
+ {
+ return eventID;
+ }
+}

Added: trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/AdHocChatRoomListChangeListener.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/AdHocChatRoomListChangeListener.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/AdHocChatRoomListChangeListener.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,20 @@
+/*
+ * 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.chatroomslist;
+
+/**
+ * Listener that dispatches events coming from the ad-hoc chat room list.
+ *
+ * @author Valentin Martinet
+ */
+public interface AdHocChatRoomListChangeListener
+{
+ /**
+ * Indicates that a change has occurred in the ad-hoc chat room data list.
+ */
+ public void contentChanged(AdHocChatRoomListChangeEvent evt);
+}

Modified: trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomList.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomList.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomList.java&p2=trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomList.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomList.java (original)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomList.java 2009-09-14 15:51:47+0000
@@ -82,7 +82,9 @@
             = new ChatRoomProviderWrapper(pps);

         providersList.add(chatRoomProvider);
-
+
         ConfigurationService configService
             = GuiActivator.getConfigurationService();

Modified: trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomListUI.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomListUI.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomListUI.java&p2=trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomListUI.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomListUI.java (original)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomListUI.java 2009-09-14 15:51:47+0000
@@ -26,7 +26,8 @@
public class ChatRoomListUI
     extends SCScrollPane
     implements MouseListener,
- ChatRoomListChangeListener
+ ChatRoomListChangeListener,
+ AdHocChatRoomListChangeListener
{
     private final JList chatRoomList = new JList();

@@ -41,8 +42,11 @@
      */
     public ChatRoomListUI(ChatRoomListDialog parentDialog)
     {
- GuiActivator.getUIService().getConferenceChatManager()
- .addChatRoomListChangeListener(this);
+ ConferenceChatManager confChatManager
+ = GuiActivator.getUIService().getConferenceChatManager();
+
+ confChatManager.addChatRoomListChangeListener(this);
+ confChatManager.addAdHocChatRoomListChangeListener(this);

         this.treePanel.add(chatRoomList, BorderLayout.NORTH);

@@ -249,4 +253,43 @@
             chatRoomsListModel.contentChanged(index, index);
         }
     }
+
+ /**
+ * Updates the chat room list model when notified of a change in the chat
+ * room list.
+ */
+ public void contentChanged(AdHocChatRoomListChangeEvent evt)
+ {
+ AdHocChatRoomWrapper chatRoomWrapper = evt.getSourceAdHocChatRoom();
+
+ if (evt.getEventID()
+ == AdHocChatRoomListChangeEvent.AD_HOC_CHAT_ROOM_ADDED)
+ {
+ int index = chatRoomsListModel.indexOf(chatRoomWrapper);
+
+ if (index != -1)
+ chatRoomsListModel.contentAdded(index, index);
+ }
+ else if (evt.getEventID()
+ == AdHocChatRoomListChangeEvent.AD_HOC_CHAT_ROOM_REMOVED)
+ {
+ int groupIndex = chatRoomsListModel.indexOf(
+ chatRoomWrapper.getParentProvider());
+
+ int listSize = chatRoomsListModel.getSize();
+
+ if (groupIndex != -1&& listSize> 0)
+ {
+ chatRoomsListModel.contentChanged(groupIndex, listSize - 1);
+ chatRoomsListModel.contentRemoved(listSize, listSize);
+ }
+ }
+ else if (evt.getEventID()
+ == AdHocChatRoomListChangeEvent.AD_HOC_CHAT_ROOM_CHANGED)
+ {
+ int index = chatRoomsListModel.indexOf(chatRoomWrapper);
+
+ chatRoomsListModel.contentChanged(index, index);
+ }
+ }
}

Modified: trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/createforms/CreateChatRoomDialog.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/createforms/CreateChatRoomDialog.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/createforms/CreateChatRoomDialog.java&p2=trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/createforms/CreateChatRoomDialog.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/createforms/CreateChatRoomDialog.java (original)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/createforms/CreateChatRoomDialog.java 2009-09-14 15:51:47+0000
@@ -17,8 +17,8 @@
import net.java.sip.communicator.util.swing.*;

/**
- * The<tt>CreateChatRoomDialog</tt> is the dialog containing the form for adding
- * a chat room. It is different from the "Create chat room" wizard. The
+ * The<tt>CreateChatRoomDialog</tt> is the dialog containing the form for
+ * adding a chat room. It is different from the "Create chat room" wizard. The
  *<tt>CreateChatRoomDialog</tt> is used when a new chat room
  * is added to an already existing server in the list.
  *
@@ -44,8 +44,8 @@
     private ChatRoomProviderWrapper chatRoomProvider;

     /**
- * Creates an instance of<tt>CreateChatRoomDialog</tt> that represents a dialog
- * that adds a new chat room to an already existing server.
+ * Creates an instance of<tt>CreateChatRoomDialog</tt> that represents a
+ * dialog that adds a new chat room to an already existing server.
      *
      * @param provider The<tt>ChatRoomProviderWrapper</tt>.
      */
@@ -63,31 +63,31 @@
     {
         this.setTitle(GuiActivator.getResources()
                 .getI18NString("service.gui.CREATE_CHAT_ROOM"));
-
+
         this.setSize(620, 450);
         this.setPreferredSize(new Dimension(620, 450));
-
+
         this.getRootPane().setDefaultButton(addButton);
         this.addButton.setName("create");
         this.cancelButton.setName("cancel");
-
+
         this.addButton.setMnemonic(
             GuiActivator.getResources().getI18nMnemonic("service.gui.CREATE"));
-
+
         this.cancelButton.setMnemonic(
             GuiActivator.getResources().getI18nMnemonic("service.gui.CANCEL"));
-
+
         this.addButton.addActionListener(this);
         this.cancelButton.addActionListener(this);
-
+
         this.buttonsPanel.add(addButton);
         this.buttonsPanel.add(cancelButton);
-
+
         this.mainPanel.setBorder(BorderFactory.createEmptyBorder(5, 10, 0, 10));
-
+
         this.mainPanel.add(chatRoomPanel, BorderLayout.CENTER);
         this.mainPanel.add(buttonsPanel, BorderLayout.SOUTH);
-
+
         this.getContentPane().add(mainPanel);
     }

@@ -105,7 +105,7 @@

             GuiActivator.getUIService().getConferenceChatManager()
                 .createChatRoom(chatRoomName,
- chatRoomProvider.getProtocolProvider());
+ chatRoomProvider.getProtocolProvider(), null);
         }
         this.dispose();
     }

Modified: trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/createforms/CreateChatRoomWizard.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/createforms/CreateChatRoomWizard.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/createforms/CreateChatRoomWizard.java&p2=trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/createforms/CreateChatRoomWizard.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/createforms/CreateChatRoomWizard.java (original)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/createforms/CreateChatRoomWizard.java 2009-09-14 15:51:47+0000
@@ -21,11 +21,11 @@
     implements WizardListener
{
     private NewChatRoom newChatRoom = new NewChatRoom();
-
+
     private CreateChatRoomWizardPage1 page1;
-
+
     private CreateChatRoomWizardPage2 page2;
-
+
     /**
      * Creates an instance of<tt>CreateChatRoomWizard</tt>.
      *
@@ -64,7 +64,8 @@
         {
             GuiActivator.getUIService().getConferenceChatManager()
                 .createChatRoom(newChatRoom.getChatRoomName(),
- newChatRoom.getProtocolProvider());
+ newChatRoom.getProtocolProvider(),
+ null);
         }
     }
}

Modified: trunk/src/net/java/sip/communicator/impl/gui/main/login/LoginManager.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/login/LoginManager.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/gui/main/login/LoginManager.java&p2=trunk/src/net/java/sip/communicator/impl/gui/main/login/LoginManager.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/gui/main/login/LoginManager.java (original)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/login/LoginManager.java 2009-09-14 15:51:47+0000
@@ -108,7 +108,8 @@

                 if (status == null
                     >> status.equals(Constants.ONLINE_STATUS)
- || ((status instanceof PresenceStatus)&& (((PresenceStatus) status)
+ || ((status instanceof PresenceStatus)
+&& (((PresenceStatus) status)
                         .getStatus()>= PresenceStatus.ONLINE_THRESHOLD)))
                 {
                     this.login(protocolProvider);
@@ -138,8 +139,9 @@
         {
             OperationSetPresence presence = mainFrame
                 .getProtocolPresenceOpSet(protocolProvider);
- OperationSetMultiUserChat multiUserChat = mainFrame
- .getMultiUserChatOpSet(protocolProvider);
+
+ OperationSetMultiUserChat multiUserChat =
+ mainFrame.getMultiUserChatOpSet(protocolProvider);

             if (presence != null)
             {
@@ -153,6 +155,7 @@
                     .getChatRoomList().synchronizeOpSetWithLocalContactList(
                         protocolProvider, multiUserChat);
             }
+
         }
         else if (newState.equals(RegistrationState.AUTHENTICATION_FAILED))
         {

Modified: trunk/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java&p2=trunk/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java (original)
+++ trunk/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java 2009-09-14 15:51:47+0000
@@ -25,20 +25,24 @@
import net.java.sip.communicator.util.*;

/**
- * The Message History Service stores messages exchanged through the various protocols
+ * The Message History Service stores messages exchanged through the various
+ * protocols
  * Logs messages for all protocol providers that support basic instant messaging
  * (i.e. those that implement OperationSetBasicInstantMessaging).
  *
  * @author Alexander Pelov
  * @author Damian Minkov
  * @author Lubomir Marinov
+ * @author Valentin Martinet
  */
public class MessageHistoryServiceImpl
     implements MessageHistoryService,
                 MessageListener,
                 ChatRoomMessageListener,
+ AdHocChatRoomMessageListener,
                 ServiceListener,
- LocalUserChatRoomPresenceListener
+ LocalUserChatRoomPresenceListener,
+ LocalUserAdHocChatRoomPresenceListener
{
     /**
      * The logger for this class.
@@ -47,7 +51,8 @@
             .getLogger(MessageHistoryServiceImpl.class);

     private static String[] STRUCTURE_NAMES =
- new String[] { "dir", "msg_CDATA", "msgTyp", "enc", "uid", "sub", "receivedTimestamp" };
+ new String[] { "dir", "msg_CDATA", "msgTyp", "enc", "uid", "sub",
+ "receivedTimestamp" };

     private static HistoryRecordStructure recordStructure =
         new HistoryRecordStructure(STRUCTURE_NAMES);
@@ -89,7 +94,8 @@
      * @return Collection of MessageReceivedEvents or MessageDeliveredEvents
      * @throws RuntimeException
      */
- public Collection<EventObject> findByStartDate(MetaContact contact, Date startDate)
+ public Collection<EventObject> findByStartDate( MetaContact contact,
+ Date startDate)
         throws RuntimeException
     {
         TreeSet<EventObject> result =
@@ -109,7 +115,8 @@
             Iterator<HistoryRecord> recs = reader.findByStartDate(startDate);
             while (recs.hasNext())
             {
- result.add(convertHistoryRecordToMessageEvent(recs.next(), item));
+ result.add(
+ convertHistoryRecordToMessageEvent(recs.next(), item));
             }
         }

@@ -119,7 +126,8 @@
         return result;
     }

- private void removeHistorySearchProgressListeners(Map<?, > readers)
+ private void removeHistorySearchProgressListeners(
+ Map<?, HistoryReader> readers)
     {
         for (HistoryReader item : readers.values())
             removeHistorySearchProgressListeners(item);
@@ -134,10 +142,12 @@
      * @return Collection of MessageReceivedEvents or MessageDeliveredEvents
      * @throws RuntimeException
      */
- public Collection<EventObject> findByEndDate(MetaContact contact, Date endDate)
+ public Collection<EventObject> findByEndDate( MetaContact contact,
+ Date endDate)
         throws RuntimeException
     {
- TreeSet<EventObject> result = new TreeSet<EventObject>(new MessageEventComparator<EventObject>());
+ TreeSet<EventObject> result = new TreeSet<EventObject>(
+ new MessageEventComparator<EventObject>());

         // get the readers for this contact
         Map<Contact, HistoryReader> readers = getHistoryReaders(contact);
@@ -154,7 +164,8 @@
             Iterator<HistoryRecord> recs = reader.findByEndDate(endDate);
             while (recs.hasNext())
             {
- result.add(convertHistoryRecordToMessageEvent(recs.next(), item));
+ result
+ .add(convertHistoryRecordToMessageEvent(recs.next(), item));
             }
         }

@@ -174,10 +185,14 @@
      * @return Collection of MessageReceivedEvents or MessageDeliveredEvents
      * @throws RuntimeException
      */
- public Collection<EventObject> findByPeriod(MetaContact contact, Date startDate, Date endDate)
+ public Collection<EventObject> findByPeriod(MetaContact contact,
+ Date startDate,
+ Date endDate)
         throws RuntimeException
     {
- TreeSet<EventObject> result = new TreeSet<EventObject>(new MessageEventComparator<EventObject>());
+ TreeSet<EventObject> result
+ = new TreeSet<EventObject>(new MessageEventComparator<EventObject>());
+
         // get the readers for this contact
         Map<Contact, HistoryReader> readers = getHistoryReaders(contact);

@@ -191,10 +206,12 @@
             // add the progress listeners
             addHistorySearchProgressListeners(reader, recordsCount);

- Iterator<HistoryRecord> recs = reader.findByPeriod(startDate, endDate);
+ Iterator<HistoryRecord> recs
+ = reader.findByPeriod(startDate, endDate);
             while (recs.hasNext())
             {
- result.add(convertHistoryRecordToMessageEvent(recs.next(), item));
+ result
+ .add(convertHistoryRecordToMessageEvent(recs.next(), item));
             }
         }

@@ -233,7 +250,8 @@
      * @return Collection of MessageReceivedEvents or MessageDeliveredEvents
      * @throws RuntimeException
      */
- public Collection<EventObject> findByKeyword(MetaContact contact, String keyword)
+ public Collection<EventObject> findByKeyword( MetaContact contact,
+ String keyword)
         throws RuntimeException
     {
         return findByKeyword(contact, keyword, false);
@@ -248,15 +266,16 @@
      * @return Collection of MessageReceivedEvents or MessageDeliveredEvents
      * @throws RuntimeException
      */
- public Collection<EventObject> findByKeywords(MetaContact contact, String[] keywords)
+ public Collection<EventObject> findByKeywords( MetaContact contact,
+ String[] keywords)
         throws RuntimeException
     {
         return findByKeywords(contact, keywords, false);
     }

     /**
- * Returns the supplied number of recent messages exchanged by all the contacts
- * in the supplied metacontact
+ * Returns the supplied number of recent messages exchanged by all the
+ * contacts in the supplied metacontact
      *
      * @param contact MetaContact
      * @param count messages count
@@ -266,7 +285,9 @@
     public Collection<EventObject> findLast(MetaContact contact, int count)
         throws RuntimeException
     {
- TreeSet<EventObject> result = new TreeSet<EventObject>(new MessageEventComparator<EventObject>());
+ TreeSet<EventObject> result
+ = new TreeSet<EventObject>(
+ new MessageEventComparator<EventObject>());

         Iterator<Contact> iter = contact.getContacts();
         while (iter.hasNext())
@@ -292,7 +313,8 @@
             }
         }

- LinkedList<EventObject> resultAsList = new LinkedList<EventObject>(result);
+ LinkedList<EventObject> resultAsList
+ = new LinkedList<EventObject>(result);
         int startIndex = resultAsList.size() - count;

         if(startIndex< 0)
@@ -311,10 +333,13 @@
      * @return Collection of MessageReceivedEvents or MessageDeliveredEvents
      * @throws RuntimeException
      */
- public Collection<EventObject> findFirstMessagesAfter(MetaContact contact, Date date,
- int count) throws RuntimeException
+ public Collection<EventObject> findFirstMessagesAfter( MetaContact contact,
+ Date date,
+ int count)
+ throws RuntimeException
     {
- TreeSet<EventObject> result = new TreeSet<EventObject>(new MessageEventComparator<EventObject>());
+ TreeSet<EventObject> result = new TreeSet<EventObject>(
+ new MessageEventComparator<EventObject>());

         Iterator<Contact> iter = contact.getContacts();
         while (iter.hasNext())
@@ -329,10 +354,11 @@
                 // date param of method is the one saved in receivedTimestamp
                 // the method findFirstRecordsAfter compares to the
                 // attribute timestamp. Most of the times there is 1 or 2 mills
- // difference between the two dates. So we will request more records
- // from the reader and than will get the needed count according
- // to the correct field comparsion (receivedTimestamp)
- Iterator<HistoryRecord> recs = reader.findFirstRecordsAfter(date, count + 4);
+ // difference between the two dates. So we will request more
+ // records from the reader and than will get the needed count
+ // according to the correct field comparsion (receivedTimestamp)
+ Iterator<HistoryRecord> recs
+ = reader.findFirstRecordsAfter(date, count + 4);
                 while (recs.hasNext())
                 {
                     result.add(
@@ -356,19 +382,22 @@
             if(object instanceof MessageDeliveredEvent)
             {
                 isRecordOK =
- (((MessageDeliveredEvent)object).getTimestamp()> date.getTime());
+ (((MessageDeliveredEvent)object).getTimestamp()
+> date.getTime());
             }
             else if(object instanceof MessageReceivedEvent)
             {
                 isRecordOK =
- (((MessageReceivedEvent)object).getTimestamp()> date.getTime());
+ (((MessageReceivedEvent)object).getTimestamp()
+> date.getTime());
             }

             if(!isRecordOK)
                 startIx++;
         }

- LinkedList<EventObject> resultAsList = new LinkedList<EventObject>(result);
+ LinkedList<EventObject> resultAsList
+ = new LinkedList<EventObject>(result);

         int toIndex = startIx + count;
         if(toIndex> resultAsList.size())
@@ -387,10 +416,13 @@
      * @return Collection of MessageReceivedEvents or MessageDeliveredEvents
      * @throws RuntimeException
      */
- public Collection<EventObject> findLastMessagesBefore(MetaContact contact, Date date,
- int count) throws RuntimeException
+ public Collection<EventObject> findLastMessagesBefore( MetaContact contact,
+ Date date,
+ int count)
+ throws RuntimeException
     {
- TreeSet<EventObject> result = new TreeSet<EventObject>(new MessageEventComparator<EventObject>());
+ TreeSet<EventObject> result = new TreeSet<EventObject>(
+ new MessageEventComparator<EventObject>());

         Iterator<Contact> iter = contact.getContacts();
         while (iter.hasNext())
@@ -402,7 +434,8 @@
                 History history = this.getHistory(null, item);

                 HistoryReader reader = history.getReader();
- Iterator<HistoryRecord> recs = reader.findLastRecordsBefore(date, count);
+ Iterator<HistoryRecord> recs
+ = reader.findLastRecordsBefore(date, count);
                 while (recs.hasNext())
                 {
                     result.add(
@@ -416,7 +449,8 @@
             }
         }

- LinkedList<EventObject> resultAsList = new LinkedList<EventObject>(result);
+ LinkedList<EventObject> resultAsList
+ = new LinkedList<EventObject>(result);
         int startIndex = resultAsList.size() - count;

         if(startIndex< 0)
@@ -445,7 +479,8 @@

         String account = "unkown";
         if (remoteContact != null)
- account = remoteContact.getProtocolProvider().getAccountID().getAccountUniqueID();
+ account = remoteContact.getProtocolProvider()
+ .getAccountID().getAccountUniqueID();

         HistoryID historyId = HistoryID.createFromRawID(
             new String[] { "messages",
@@ -513,6 +548,28 @@
             account.getService(),
             room.getName());
     }
+
+ /**
+ * Returns the history by specified local contact
+ * (if is null the default is used)
+ * and by the ad-hoc chat room
+ *
+ * @param room The ad-hoc chat room
+ * @return History the history - created if not existing
+ * @throws IOException
+ */
+ private History getHistoryForAdHocMultiChat(
+ AdHocChatRoom room)
+ throws IOException
+ {
+ AccountID account = room.getParentProvider().getAccountID();
+
+ return this.getHistoryForMultiChat(
+ null,
+ account.getAccountUniqueID(),
+ account.getService(),
+ room.getName());
+ }

     /**
      * Returns the history by specified local contact
@@ -557,21 +614,24 @@
     }

     /**
- * Used to convert HistoryRecord in MessageDeliveredEvent or MessageReceivedEvent
- * which are returned by the finder methods
+ * Used to convert HistoryRecord in MessageDeliveredEvent or
+ * MessageReceivedEvent which are returned by the finder methods
      *
      * @param hr HistoryRecord
      * @param contact Contact
      * @return Object
      */
- private EventObject convertHistoryRecordToMessageEvent(HistoryRecord hr, Contact contact)
+ private EventObject convertHistoryRecordToMessageEvent( HistoryRecord hr,
+ Contact contact)
     {
         MessageImpl msg = createMessageFromHistoryRecord(hr);
         long timestamp;

         // if there is value for date of receiving the message
- // this is the event timestamp (this is the date that had came from protocol)
- // the HistoryRecord timestamp is the timestamp when the record was written
+ // this is the event timestamp (this is the date that had came
+ // from protocol)
+ // the HistoryRecord timestamp is the timestamp when the record
+ // was written
         long messageReceivedDate = msg.getMessageReceivedDate();
         long hrTimestamp = hr.getTimeInMillis();
         if (messageReceivedDate != 0)
@@ -614,8 +674,10 @@
         long timestamp;

         // if there is value for date of receiving the message
- // this is the event timestamp (this is the date that had came from protocol)
- // the HistoryRecord timestamp is the timestamp when the record was written
+ // this is the event timestamp (this is the date that had came
+ // from protocol)
+ // the HistoryRecord timestamp is the timestamp when the record
+ // was written
         long messageReceivedDate = msg.getMessageReceivedDate();
         long hrTimestamp = hr.getTimeInMillis();
         if(messageReceivedDate != 0)
@@ -892,6 +954,32 @@
             logger.error("Could not add message to history", e);
         }
     }
+
+ /**
+ * Writes a message to the history.
+ * @param history The history to which will write the message
+ * @param message Message
+ * @param messageTimestamp Date this is the timestamp when was message received
+ * that came from the protocol provider
+ */
+ private void writeMessage(History history, String direction,
+ Contact from,
+ Message message, long messageTimestamp)
+ {
+ try
+ {
+ HistoryWriter historyWriter = history.getWriter();
+ historyWriter.addRecord(new String[] { direction,
+ message.getContent(), message.getContentType(),
+ message.getEncoding(), message.getMessageUID(),
+ from.getAddress(),
+ String.valueOf(messageTimestamp) },
+ new Date()); // this date is when the history record is written
+ } catch (IOException e)
+ {
+ logger.error("Could not add message to history", e);
+ }
+ }

     // //////////////////////////////////////////////////////////////////////////

@@ -1453,11 +1541,12 @@
      * @return Collection of MessageReceivedEvents or MessageDeliveredEvents
      * @throws RuntimeException
      */
- public Collection<EventObject> findByPeriod(ChatRoom room, Date startDate, Date endDate,
- String[] keywords, boolean caseSensitive)
+ public Collection<EventObject> findByPeriod(ChatRoom room, Date startDate,
+ Date endDate, String[] keywords, boolean caseSensitive)
         throws RuntimeException
     {
- TreeSet<EventObject> result = new TreeSet<EventObject>(new ChatRoomMessageEventComparator<EventObject>());
+ TreeSet<EventObject> result = new TreeSet<EventObject>(
+ new ChatRoomMessageEventComparator<EventObject>());
         try
         {
             // get the readers for this room
@@ -1467,8 +1556,9 @@
             // add the progress listeners
             addHistorySearchProgressListeners(reader, 1);

- Iterator<HistoryRecord> recs = reader.findByPeriod(startDate, endDate, keywords,
- SEARCH_FIELD, caseSensitive);
+ Iterator<HistoryRecord> recs
+ = reader.findByPeriod(startDate, endDate, keywords,
+ SEARCH_FIELD, caseSensitive);
             while (recs.hasNext())
             {
                 result.add(convertHistoryRecordToMessageEvent(recs.next(), room));
@@ -1512,7 +1602,8 @@
             boolean caseSensitive)
         throws RuntimeException
     {
- TreeSet<EventObject> result = new TreeSet<EventObject>(new ChatRoomMessageEventComparator<EventObject>());
+ TreeSet<EventObject> result = new TreeSet<EventObject>(
+ new ChatRoomMessageEventComparator<EventObject>());
         try
         {
             // get the readers for this room
@@ -1526,7 +1617,8 @@
                 findByKeyword(keyword, SEARCH_FIELD, caseSensitive);
             while (recs.hasNext())
             {
- result.add(convertHistoryRecordToMessageEvent(recs.next(), room));
+ result
+ .add(convertHistoryRecordToMessageEvent(recs.next(), room));
             }

             removeHistorySearchProgressListeners(reader);
@@ -1547,7 +1639,8 @@
      * @return Collection of MessageReceivedEvents or MessageDeliveredEvents
      * @throws RuntimeException
      */
- public Collection<EventObject> findByKeywords(ChatRoom room, String[] keywords)
+ public Collection<EventObject> findByKeywords( ChatRoom room,
+ String[] keywords)
         throws RuntimeException
     {
         return findByKeywords(room, keywords, false);
@@ -1563,11 +1656,13 @@
      * @return Collection of MessageReceivedEvents or MessageDeliveredEvents
      * @throws RuntimeException
      */
- public Collection<EventObject> findByKeywords(ChatRoom room, String[] keywords,
- boolean caseSensitive)
+ public Collection<EventObject> findByKeywords( ChatRoom room,
+ String[] keywords,
+ boolean caseSensitive)
         throws RuntimeException
     {
- TreeSet<EventObject> result = new TreeSet<EventObject>(new ChatRoomMessageEventComparator<EventObject>());
+ TreeSet<EventObject> result = new TreeSet<EventObject>(
+ new ChatRoomMessageEventComparator<EventObject>());
         try
         {
             // get the readers for this room
@@ -1581,7 +1676,8 @@
                 findByKeywords(keywords, SEARCH_FIELD, caseSensitive);
             while (recs.hasNext())
             {
- result.add(convertHistoryRecordToMessageEvent(recs.next(), room));
+ result
+ .add(convertHistoryRecordToMessageEvent(recs.next(), room));
             }

             removeHistorySearchProgressListeners(reader);
@@ -1605,7 +1701,8 @@
     public Collection<EventObject> findLast(ChatRoom room, int count)
         throws RuntimeException
     {
- TreeSet<EventObject> result = new TreeSet<EventObject>(new ChatRoomMessageEventComparator<EventObject>());
+ TreeSet<EventObject> result = new TreeSet<EventObject>(
+ new ChatRoomMessageEventComparator<EventObject>());

         try
         {
@@ -1625,7 +1722,8 @@
             logger.error("Could not read history", e);
         }

- LinkedList<EventObject> resultAsList = new LinkedList<EventObject>(result);
+ LinkedList<EventObject> resultAsList
+ = new LinkedList<EventObject>(result);
         int startIndex = resultAsList.size() - count;

         if(startIndex< 0)
@@ -1644,16 +1742,20 @@
      * @return Collection of MessageReceivedEvents or MessageDeliveredEvents
      * @throws RuntimeException
      */
- public Collection<EventObject> findFirstMessagesAfter(ChatRoom room, Date date, int count)
+ public Collection<EventObject> findFirstMessagesAfter( ChatRoom room,
+ Date date,
+ int count)
         throws RuntimeException
     {
- TreeSet<EventObject> result = new TreeSet<EventObject>(new ChatRoomMessageEventComparator<EventObject>());
+ TreeSet<EventObject> result = new TreeSet<EventObject>(
+ new ChatRoomMessageEventComparator<EventObject>());

         try
         {
- HistoryReader reader =
- this.getHistoryForMultiChat(room).getReader();
- Iterator<HistoryRecord> recs = reader.findFirstRecordsAfter(date, count);
+ HistoryReader reader
+ = this.getHistoryForMultiChat(room).getReader();
+ Iterator<HistoryRecord> recs
+ = reader.findFirstRecordsAfter(date, count);
             while (recs.hasNext())
             {
                 result.add(
@@ -1666,7 +1768,8 @@
             logger.error("Could not read history", e);
         }

- LinkedList<EventObject> resultAsList = new LinkedList<EventObject>(result);
+ LinkedList<EventObject> resultAsList
+ = new LinkedList<EventObject>(result);

         int toIndex = count;
         if(toIndex> resultAsList.size())
@@ -1685,16 +1788,20 @@
      * @return Collection of MessageReceivedEvents or MessageDeliveredEvents
      * @throws RuntimeException
      */
- public Collection<EventObject> findLastMessagesBefore(ChatRoom room, Date date, int count)
+ public Collection<EventObject> findLastMessagesBefore( ChatRoom room,
+ Date date,
+ int count)
         throws RuntimeException
     {
- TreeSet<EventObject> result = new TreeSet<EventObject>(new ChatRoomMessageEventComparator<EventObject>());
+ TreeSet<EventObject> result = new TreeSet<EventObject>(
+ new ChatRoomMessageEventComparator<EventObject>());

         try
         {
             HistoryReader reader =
                 this.getHistoryForMultiChat(room).getReader();
- Iterator<HistoryRecord> recs = reader.findLastRecordsBefore(date, count);
+ Iterator<HistoryRecord> recs
+ = reader.findLastRecordsBefore(date, count);
             while (recs.hasNext())
             {
                 result.add(
@@ -1707,7 +1814,8 @@
             logger.error("Could not read history", e);
         }

- LinkedList<EventObject> resultAsList = new LinkedList<EventObject>(result);
+ LinkedList<EventObject> resultAsList
+ = new LinkedList<EventObject>(result);
         int startIndex = resultAsList.size() - count;

         if(startIndex< 0)
@@ -1720,7 +1828,8 @@
     {
         if (resourcesService == null)
         {
- ServiceReference serviceReference = MessageHistoryActivator.bundleContext
+ ServiceReference serviceReference
+ = MessageHistoryActivator.bundleContext
                 .getServiceReference(ResourceManagementService.class.getName());

             if(serviceReference == null)
@@ -1757,7 +1866,8 @@
             this.listener = listener;
         }

- private void setCurrentValues(HistoryReader currentReader, int allRecords)
+ private void setCurrentValues( HistoryReader currentReader,
+ int allRecords)
         {
             this.allRecords = allRecords;
             this.reader = currentReader;
@@ -1790,7 +1900,8 @@

             currentProgress += tmpHistoryProgress - lastHistoryProgress;

- if(evt.getProgress() == HistorySearchProgressListener.PROGRESS_MAXIMUM_VALUE)
+ if(evt.getProgress()
+ == HistorySearchProgressListener.PROGRESS_MAXIMUM_VALUE)
             {
                 lastHistoryProgress = 0;

@@ -1798,7 +1909,8 @@
                 // there will be looses in currentProgress due to the devision
                 if((int)accumulatedRatio == raiser)
                     currentProgress = raiser *
- MessageHistorySearchProgressListener.PROGRESS_MAXIMUM_VALUE;
+ MessageHistorySearchProgressListener
+ .PROGRESS_MAXIMUM_VALUE;
             }
             else
                 lastHistoryProgress = tmpHistoryProgress;
@@ -2060,4 +2172,63 @@
             }
         }
     }
+
+ public void messageDelivered(AdHocChatRoomMessageDeliveredEvent evt)
+ {
+ try
+ {
+ History history = this.
+ getHistoryForAdHocMultiChat(
+ evt.getSourceAdHocChatRoom());
+
+ writeMessage(history, "out", evt.getMessage(), evt.getTimestamp());
+ }
+ catch (IOException e)
+ {
+ logger.error("Could not add message to history", e);
+ }
+ }
+
+ public void messageDeliveryFailed(
+ AdHocChatRoomMessageDeliveryFailedEvent evt)
+ {
+ // TODO Auto-generated method stub
+ }
+
+ public void messageReceived(AdHocChatRoomMessageReceivedEvent evt)
+ {
+ try
+ {
+ History history = this.getHistoryForAdHocMultiChat(
+ evt.getSourceChatRoom());
+
+ writeMessage(history, "in", evt.getSourceChatRoomParticipant(),
+ evt.getMessage(), evt.getTimestamp());
+ } catch (IOException e)
+ {
+ logger.error("Could not add message to history", e);
+ }
+ }
+
+ /**
+ * Called to notify interested parties that a change in our presence in
+ * an ad-hoc chat room has occurred. Changes may include us being join,
+ * left.
+ * @param evt the<tt>LocalUserAdHocChatRoomPresenceChangeEvent</tt>
+ * instance containing the ad-hoc chat room and the type, and reason of the
+ * change
+ */
+ public void localUserAdHocPresenceChanged(
+ LocalUserAdHocChatRoomPresenceChangeEvent evt)
+ {
+ if(evt.getEventType()
+ == LocalUserAdHocChatRoomPresenceChangeEvent.LOCAL_USER_JOINED)
+ {
+ evt.getAdHocChatRoom().addMessageListener(this);
+ }
+ else
+ {
+ evt.getAdHocChatRoom().removeMessageListener(this);
+ }
+ }
}

Modified: trunk/src/net/java/sip/communicator/impl/protocol/facebook/FacebookUser.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/facebook/FacebookUser.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/protocol/facebook/FacebookUser.java&p2=trunk/src/net/java/sip/communicator/impl/protocol/facebook/FacebookUser.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/protocol/facebook/FacebookUser.java (original)
+++ trunk/src/net/java/sip/communicator/impl/protocol/facebook/FacebookUser.java 2009-09-14 15:51:47+0000
@@ -16,48 +16,48 @@
  */
public class FacebookUser
{
- /*{"listChanged":true,
- "availableCount":2,
-
- "nowAvailableList":
- {"1355527894":{"i":false},
- "1386786477":{"i":false}},
-
- "wasAvailableIDs":[],
-
- "userInfos":{
- "1355527894":
- {"name":"Dai Zhiwei",
- "firstName":"Dai",
- "thumbSrc":"http:\/\/profile.ak.facebook.com\/v225\/1132\/119\/q1355527894_6497.jpg",
- "status":null,
- "statusTime":0,
- "statusTimeRel":""},
- "1386786477":
- {"name":"\u5341\u4e00",
- "firstName":"\u4e00",
- "thumbSrc":"http:\/\/static.ak.fbcdn.net\/pics\/q_silhouette.gif",
- "status":null,
- "statusTime":0,
- "statusTimeRel":""},
- "1190346972":
- {"name":"David Willer",
- "firstName":"David",
- "thumbSrc":"http:\/\/profile.ak.facebook.com\/profile5\/54\/96\/q1190346972_3586.jpg",
- "status":null,
- "statusTime":0,
- "statusTimeRel":""}},
-
- "forcedRender":true,
- "flMode":false,
- "flData":{}}*/
+ /*{"listChanged":true,
+ "availableCount":2,
+
+ "nowAvailableList":
+ {"1355527894":{"i":false},
+ "1386786477":{"i":false}},
+
+ "wasAvailableIDs":[],
+
+ "userInfos":{
+ "1355527894":
+ {"name":"Dai Zhiwei",
+ "firstName":"Dai",
+ "thumbSrc":"http:\/\/profile.ak.facebook.com\/v225\/1132\/119\/q1355527894_6497.jpg",
+ "status":null,
+ "statusTime":0,
+ "statusTimeRel":""},
+ "1386786477":
+ {"name":"\u5341\u4e00",
+ "firstName":"\u4e00",
+ "thumbSrc":"http:\/\/static.ak.fbcdn.net\/pics\/q_silhouette.gif",
+ "status":null,
+ "statusTime":0,
+ "statusTimeRel":""},
+ "1190346972":
+ {"name":"David Willer",
+ "firstName":"David",
+ "thumbSrc":"http:\/\/profile.ak.facebook.com\/profile5\/54\/96\/q1190346972_3586.jpg",
+ "status":null,
+ "statusTime":0,
+ "statusTimeRel":""}},
+
+ "forcedRender":true,
+ "flMode":false,
+ "flData":{}}*/
     public static String defaultThumbSrc = "http://static.ak.fbcdn.net/pics/q_silhouette.gif";

     public static String defaultAvatarSrc = "http://static.ak.fbcdn.net/pics/d_silhouette.gif";

- public String uid;
-
- public boolean isIdle;
+ public String uid;
+
+ public boolean isIdle;

     public String name;

@@ -91,9 +91,9 @@
         thumbSrc = (String) user.get("thumbSrc");
         Object temp = user.get("status");
         if(!temp.equals(org.json.JSONObject.NULL))
- status = (String)temp;
- else
- status = "";
+ status = (String)temp;
+ else
+ status = "";
         statusTime = (Number) user.get("statusTime");
         statusTimeRel = (String) user.get("statusTimeRel");

Added: trunk/src/net/java/sip/communicator/impl/protocol/icq/AdHocChatRoomIcqImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/icq/AdHocChatRoomIcqImpl.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/protocol/icq/AdHocChatRoomIcqImpl.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,735 @@
+/*
+ * 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.icq;
+
+import java.util.*;
+import java.util.Map.*;
+
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.event.*;
+import net.java.sip.communicator.util.*;
+import net.kano.joustsim.*;
+import net.kano.joustsim.oscar.oscar.service.chatrooms.*;
+
+/**
+ * Represents an ad-hoc chat room, where multiple chat users could communicate
+ * in a many-to-many fashion.
+ *
+ * @author Valentin Martinet
+ */
+public class AdHocChatRoomIcqImpl implements AdHocChatRoom
+{
+ private static final Logger logger = Logger
+ .getLogger(AdHocChatRoomIcqImpl.class);
+
+ /**
+ * Listeners that will be notified of changes in member status in the
+ * room such as member joined, left or being kicked or dropped.
+ */
+ private Vector<AdHocChatRoomParticipantPresenceListener> memberListeners
+ = new Vector<AdHocChatRoomParticipantPresenceListener>();
+
+ /**
+ * Listeners that will be notified every time
+ * a new message is received on this chat room.
+ */
+ private Vector<AdHocChatRoomMessageListener> messageListeners
+ = new Vector<AdHocChatRoomMessageListener>();
+
+ /**
+ * Chat room invitation from the icq provider, needed for joining a
+ * chat room.
+ */
+ private ChatInvitation chatInvitation = null;
+
+ /**
+ * Chat room session from the icq provider, we get this after joining a
+ * chat room.
+ * Provides most of the function we need for multi user chatting.
+ */
+ private ChatRoomSession chatRoomSession = null;
+
+ /**
+ * The list of participants of this ad-hoc chat room.
+ */
+ private Hashtable<String, Contact> participants
+ = new Hashtable<String, Contact>();
+
+ /**
+ * The operation set that created us.
+ */
+ private OperationSetAdHocMultiUserChatIcqImpl opSetMuc = null;
+
+ /**
+ * The protocol provider that created us
+ */
+ private ProtocolProviderServiceIcqImpl provider = null;
+
+ /**
+ * List with invitations.
+ */
+ private Hashtable<String, String> inviteUserList
+ = new Hashtable<String, String>();
+
+ /**
+ * HTML mime type
+ */
+ private static final String HTML_MIME_TYPE = "text/html";
+
+ private final String defaultHtmlStartTag = "<HTML>";
+
+ private final String defaultHtmlEndTag = "</HTML>";
+
+ /**
+ * Chat room name.
+ */
+
+ private String chatRoomName = "";
+
+ /**
+ * The nick name of the user.
+ */
+ private String nickName = "";
+
+ /**
+ * Chat room subject. Note: ICQ does not support chat room subjects.
+ */
+ private String chatSubject = "";
+
+ /**
+ * Constructor for chat room instances, with a given chat room invitation.
+ * If this constructor is used the user was invited to a chat room.
+ * @param chatInvitation Chat room invitation that the user received from
+ * the ICQ network
+ * @param icqProvider The ICQ provider
+ */
+ public AdHocChatRoomIcqImpl(ChatInvitation chatInvitation,
+ ProtocolProviderServiceIcqImpl icqProvider)
+ {
+
+ chatRoomName = chatInvitation.getRoomName();
+ this.chatInvitation = chatInvitation;
+ this.provider = icqProvider;
+
+ this.opSetMuc = (OperationSetAdHocMultiUserChatIcqImpl) provider
+ .getOperationSet(OperationSetAdHocMultiUserChat.class);
+ }
+
+ /**
+ * Constructor for chat room instances.
+ * @param roomName The name of the chat room.
+ * @param chatRoomSession Chat room session from the icq network
+ * @param icqProvider The icq provider
+ */
+
+ public AdHocChatRoomIcqImpl(String roomName, ChatRoomSession chatRoomSession,
+ ProtocolProviderServiceIcqImpl icqProvider)
+ {
+ this.chatRoomSession = chatRoomSession;
+ chatRoomName = roomName;
+ this.provider = icqProvider;
+
+ this.opSetMuc = (OperationSetAdHocMultiUserChatIcqImpl) provider
+ .getOperationSet(OperationSetAdHocMultiUserChat.class);
+
+ this.chatRoomSession.addListener(
+ new AdHocChatRoomSessionListenerImpl(this));
+
+ }
+
+ /**
+ * Adds a listener that will be notified of changes in our status in the
+ * room such as us being kicked, banned, or granted admin permissions.
+ *
+ * @param listener a participant status listener.
+ */
+ public void addParticipantPresenceListener(
+ AdHocChatRoomParticipantPresenceListener listener)
+ {
+ synchronized (memberListeners)
+ {
+ if (!memberListeners.contains(listener))
+ memberListeners.add(listener);
+ }
+ }
+
+ /**
+ * Registers<tt>listener</tt> so that it would receive events every time
+ * a new message is received on this chat room.
+ *
+ * @param listener a<tt>MessageListener</tt> that would be notified
+ * every time a new message is received on this chat room.
+ */
+ public void addMessageListener(AdHocChatRoomMessageListener listener)
+ {
+ synchronized (messageListeners)
+ {
+ if (!messageListeners.contains(listener))
+ messageListeners.add(listener);
+ }
+ }
+
+ /**
+ * Create a Message instance for sending arbitrary MIME-encoding content.
+ *
+ * @param content content value
+ * @param contentType the MIME-type for<tt>content</tt>
+ * @param contentEncoding encoding used for<tt>content</tt>
+ * @param subject a<tt>String</tt> subject or<tt>null</tt> for now
+ * subject.
+ * @return the newly created message.
+ */
+ public Message createMessage(byte[] content, String contentType,
+ String contentEncoding, String subject)
+ {
+ return new MessageIcqImpl(new String(content), contentType,
+ contentEncoding, subject);
+ }
+
+ /**
+ * Create a Message instance for sending a simple text messages with
+ * default (text/plain) content type and encoding.
+ *
+ * @param messageText the string content of the message.
+ * @return Message the newly created message
+ */
+ public Message createMessage(String messageText)
+ {
+ Message msg = new MessageIcqImpl(messageText,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_ENCODING, null);
+
+ return msg;
+ }
+
+ /**
+ * Returns the identifier of this<tt>AdHocChatRoom</tt>.
+ *
+ * @return a<tt>String</tt> containing the identifier of this
+ *<tt>AdHocChatRoom</tt>.
+ */
+ public String getIdentifier()
+ {
+ return chatRoomName;
+ }
+
+ /**
+ * Returns a<tt>List</tt> of<tt>Contact</tt>s corresponding
+ * to all participants currently participating in this room.
+ *
+ * @return a<tt>List</tt> of<tt>Contact</tt> corresponding to all room
+ * participants.
+ */
+ public List<Contact> getParticipants()
+ {
+ return new LinkedList<Contact>(participants.values());
+ }
+
+ /**
+ * Returns the number of participants that are currently in this chat room.
+ *
+ * @return the number of<tt>Contact</tt>s, currently participating in
+ * this room.
+ */
+ public int getParticipantsCount()
+ {
+ return participants.size();
+ }
+
+ /**
+ * Returns the name of this<tt>AdHocChatRoom</tt>.
+ *
+ * @return a<tt>String</tt> containing the name of this<tt>ChatRoom</tt>.
+ */
+ public String getName()
+ {
+ return chatRoomName;
+ }
+
+ /**
+ * Returns the protocol provider service that created us.
+ *
+ * @return the protocol provider service that created us.
+ */
+ public ProtocolProviderService getParentProvider()
+ {
+ return provider;
+ }
+
+ /**
+ * Returns the last known room subject/theme or<tt>null</tt> if the user
+ * hasn't joined the room or the room does not have a subject yet.<p> To be
+ * notified every time the room's subject change you should add a
+ *<tt>ChatRoomPropertyChangelistener</tt> to this room.<p>
+ *
+ * To change the room's subject use {@link #setSubject(String)}. Note: Not
+ * possible inside the msn protocol!
+ *
+ * @return the room subject or<tt>null</tt> if the user hasn't joined the
+ * room or the room does not have a subject yet.
+ */
+ public String getSubject()
+ {
+ return chatSubject;
+ }
+
+ /**
+ * Returns the local user's nickname in the context of this chat room or
+ *<tt>null</tt> if not currently joined.
+ *
+ * @return the nickname currently being used by the local user in the
+ * context of the local chat room.
+ */
+ public String getUserNickname()
+ {
+ if (nickName == null)
+ nickName = provider.getInfoRetreiver().getNickName(
+ provider.getAccountID().getUserID());
+
+ return nickName;
+ }
+
+ /**
+ * Invites another user to this room. If we're not joined nothing will
+ * happen.
+ *
+ * @param userAddress the address of the user (email address) to invite to
+ * the room.(one may also invite users not on their contact list).
+ * @param reason You cannot specify a Reason inside the msn protocol
+ */
+ public void invite(String userAddress, String reason)
+ {
+ assertConnected();
+
+ if (logger.isInfoEnabled())
+ logger.info("Inviting " + userAddress + " for reason: " + reason);
+
+ if (chatRoomSession.getState().equals(ChatSessionState.INROOM))
+ chatRoomSession.invite(new Screenname(userAddress), reason);
+ else
+ inviteUserList.put(userAddress, reason);
+ }
+
+ /**
+ * Joins this chat room with the nickname of the local user so that the
+ * user would start receiving events and messages for it.
+ *
+ * @throws OperationFailedException with the corresponding code if an
+ * error occurs while joining the room.
+ */
+ public void join() throws OperationFailedException
+ {
+ if (chatRoomSession == null&& chatInvitation == null)
+ { // the session is not set and we don't have a chatInvitatoin
+ // so we try to join the chatRoom again
+ ChatRoomManager chatRoomManager = provider.getAimConnection()
+ .getChatRoomManager();
+ chatRoomSession = chatRoomManager.joinRoom(this.getName());
+ chatRoomSession.addListener(
+ new AdHocChatRoomSessionListenerImpl(this));
+ }
+ else if (chatInvitation != null)
+ {
+ chatRoomSession = chatInvitation.accept();
+ chatRoomSession.addListener(
+ new AdHocChatRoomSessionListenerImpl(this));
+ }
+
+ // We don't specify a reason.
+ opSetMuc.fireLocalUserPresenceEvent(this,
+ LocalUserAdHocChatRoomPresenceChangeEvent.LOCAL_USER_JOINED, null);
+ }
+
+ /**
+ * Leave this chat room. Once this method is called, the user won't be
+ * listed as a member of the chat room any more and no further chat events
+ * will be delivered. Depending on the underlying protocol and
+ * implementation leave() might cause the room to be destroyed if it has
+ * been created by the local user.
+ */
+ public void leave()
+ {
+ if (chatRoomSession != null)
+ { // manually close the chat room session
+ // and set the chat room session to null.
+ chatRoomSession.close();
+ chatRoomSession = null;
+ }
+
+ Iterator<Entry<String, Contact>> membersSet
+ = participants.entrySet().iterator();
+
+ while (membersSet.hasNext())
+ {
+ Map.Entry<String, Contact> memberEntry = membersSet.next();
+
+ Contact participant = (Contact) memberEntry.getValue();
+
+ fireParticipantPresenceEvent(participant,
+ AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_LEFT,
+ "Local user has left the chat room.");
+ }
+
+ // Delete the list of members
+ participants.clear();
+ }
+
+ /**
+ * Removes a listener that was being notified of changes in the status of
+ * other ad-hoc chat room participants.
+ *
+ * @param listener a participant status listener.
+ */
+ public void removeParticipantPresenceListener(
+ AdHocChatRoomParticipantPresenceListener listener)
+ {
+ synchronized (memberListeners)
+ {
+ memberListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Removes<tt>listener</tt> so that it won't receive any further message
+ * events from this room.
+ *
+ * @param listener the<tt>MessageListener</tt> to remove from this room
+ */
+ public void removeMessageListener(AdHocChatRoomMessageListener listener)
+ {
+ synchronized (messageListeners)
+ {
+ messageListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Sends the<tt>message</tt> to the destination indicated by the
+ *<tt>to</tt> contact.
+ *
+ * @param message The<tt>Message</tt> to send.
+ * @throws OperationFailedException if the underlying stack is not
+ * registered or initialized or if the chat room is not joined.
+ */
+ public void sendMessage(Message message) throws OperationFailedException
+ {
+ assertConnected();
+ try
+ {
+ chatRoomSession.sendMessage(message.getContent());
+
+ //we don't need to fire a message delivered event, because
+ // we will receive this message again.
+ AdHocChatRoomMessageDeliveredEvent msgDeliveredEvt
+ = new AdHocChatRoomMessageDeliveredEvent(
+ this,
+ System.currentTimeMillis(),
+ message,
+ AdHocChatRoomMessageDeliveredEvent
+ .CONVERSATION_MESSAGE_DELIVERED);
+
+ fireMessageEvent(msgDeliveredEvt);
+ }
+ catch (Exception e)
+ {
+ logger.debug("Failed to send a conference message.");
+ throw new OperationFailedException(
+ "Failed to send a conference message.",
+ OperationFailedException.GENERAL_ERROR);
+ }
+ }
+
+ /**
+ * Notifies all interested listeners that a
+ *<tt>ChatRoomMessageDeliveredEvent</tt>,
+ *<tt>ChatRoomMessageReceivedEvent</tt> or a
+ *<tt>ChatRoomMessageDeliveryFailedEvent</tt> has been fired.
+ * @param evt The specific event
+ */
+ public void fireMessageEvent(EventObject evt)
+ {
+ Iterator<AdHocChatRoomMessageListener> listeners = null;
+ synchronized (messageListeners)
+ {
+ listeners = new ArrayList<AdHocChatRoomMessageListener>
+ (messageListeners).iterator();
+ }
+
+ while (listeners.hasNext())
+ {
+ AdHocChatRoomMessageListener listener
+ = listeners.next();
+
+ if (evt instanceof AdHocChatRoomMessageDeliveredEvent)
+ {
+ listener.messageDelivered(
+ (AdHocChatRoomMessageDeliveredEvent) evt);
+ }
+ else if (evt instanceof AdHocChatRoomMessageReceivedEvent)
+ {
+ listener.messageReceived(
+ (AdHocChatRoomMessageReceivedEvent) evt);
+ }
+ else if (evt instanceof AdHocChatRoomMessageDeliveryFailedEvent)
+ {
+ listener.messageDeliveryFailed(
+ (AdHocChatRoomMessageDeliveryFailedEvent) evt);
+ }
+ }
+ }
+
+ /**
+ * Creates the corresponding AdHocChatRoomParticipantPresenceChangeEvent and
+ * notifies all<tt>AdHocChatRoomParticipantPresenceListener</tt>s
+ * that a Contact has joined or left this<tt>AdHocChatRoom</tt>.
+ *
+ * @param member the<tt>Contact</tt> that this
+ * @param eventID the identifier of the event
+ * @param eventReason the reason of the event
+ */
+ private void fireParticipantPresenceEvent(Contact member, String eventID,
+ String eventReason)
+ {
+ AdHocChatRoomParticipantPresenceChangeEvent evt
+ = new AdHocChatRoomParticipantPresenceChangeEvent(this,
+ member,
+ eventID,
+ eventReason);
+
+ logger.trace("Will dispatch the following ChatRoom event: " + evt);
+
+ Iterator<AdHocChatRoomParticipantPresenceListener> listeners = null;
+ synchronized (memberListeners)
+ {
+ listeners = new ArrayList<AdHocChatRoomParticipantPresenceListener>
+ (memberListeners).iterator();
+ }
+
+ while (listeners.hasNext())
+ {
+ AdHocChatRoomParticipantPresenceListener listener
+ = listeners.next();
+
+ listener.participantPresenceChanged(evt);
+ }
+ }
+
+ /**
+ * Our listener for all events for this chat room, e.g. incoming messages or
+ * users that leave or join the chat room.
+ *
+ */
+
+ private class AdHocChatRoomSessionListenerImpl implements
+ ChatRoomSessionListener
+ {
+ /**
+ * The chat room this listener is for.
+ */
+ private AdHocChatRoomIcqImpl chatRoom = null;
+
+ /**
+ * Constructor for this listener, needed to set the chatRoom.
+ * @param room The containing chat room.
+ */
+ public AdHocChatRoomSessionListenerImpl(AdHocChatRoomIcqImpl room)
+ {
+ chatRoom = room;
+ }
+
+ /**
+ * Handles incoming messages for the specified chat room.
+ * @param chatRoomSession Specific chat room session
+ * @param chatRoomUser The User who sends the message
+ * @param chatMessage The message
+ */
+
+ public void handleIncomingMessage(ChatRoomSession chatRoomSession,
+ ChatRoomUser chatRoomUser, ChatMessage chatMessage)
+ {
+ logger.debug("Incoming multi user chat message received: "
+ + chatMessage.getMessage());
+
+ String msgBody = chatMessage.getMessage();
+
+ String msgContent;
+ if (msgBody.startsWith(defaultHtmlStartTag))
+ {
+ msgContent = msgBody.substring(
+ msgBody.indexOf(defaultHtmlStartTag)
+ + defaultHtmlStartTag.length(),
+ msgBody.indexOf(defaultHtmlEndTag));
+ }
+ else
+ msgContent = msgBody;
+
+ Message newMessage = createMessage(
+ msgContent.getBytes(),
+ HTML_MIME_TYPE,
+ OperationSetBasicInstantMessagingIcqImpl
+ .DEFAULT_MIME_ENCODING,
+ null);
+
+ String participantUID = chatRoomUser.getScreenname().getFormatted();
+
+ if(participantUID.equals(nickName))
+ return;
+
+ AdHocChatRoomMessageReceivedEvent msgReceivedEvent
+ = new AdHocChatRoomMessageReceivedEvent(
+ chatRoom,
+ participants.get(participantUID),
+ System.currentTimeMillis(),
+ newMessage,
+ AdHocChatRoomMessageReceivedEvent
+ .CONVERSATION_MESSAGE_RECEIVED);
+
+ fireMessageEvent(msgReceivedEvent);
+ }
+
+ public void handleStateChange(ChatRoomSession chatRoomSession,
+ ChatSessionState oldChatSessionState,
+ ChatSessionState newChatSessionState)
+ {
+ logger.debug("ChatRoomSessionState changed to: "
+ + newChatSessionState);
+
+ if (chatInvitation == null
+&& newChatSessionState.equals(ChatSessionState.INROOM))
+ {
+ try
+ {
+ chatRoom.join();
+ }
+ catch (Exception e)
+ {
+ logger.debug("Failed to join the chat room: " + e);
+ }
+ }
+
+ if(inviteUserList != null
+&& newChatSessionState.equals(ChatSessionState.INROOM) )
+ {
+ Iterator<Map.Entry<String, String>> invitesIter
+ = inviteUserList.entrySet().iterator();
+
+ while (invitesIter.hasNext())
+ {
+ Map.Entry<String, String> entry = invitesIter.next();
+
+ chatRoom.invite(entry.getKey(),
+ entry.getValue());
+ }
+ }
+
+ if (newChatSessionState.equals(ChatSessionState.CLOSED)
+ || newChatSessionState.equals(ChatSessionState.FAILED))
+ {
+ // the chatRoom is closed or we failed to join, so we remove all
+ // chat room user from the chat room member list
+ updateMemberList(chatRoomSession.getUsers(), true);
+ }
+ }
+
+ public void handleUsersJoined(ChatRoomSession chatRoomSession,
+ Set<ChatRoomUser> chatRoomUserSet)
+ {
+ // add the new members to the member list
+ updateMemberList(chatRoomUserSet, false);
+ }
+
+ public void handleUsersLeft(ChatRoomSession chatRoomSession,
+ Set<ChatRoomUser> chatRoomUserSet)
+ {
+ // remove the given members from the member list
+ updateMemberList(chatRoomUserSet, true);
+ }
+ }
+
+ /**
+ * Updates the member list, if the given boolean is true given members will
+ * be added, if it is false the given members will be removed.
+ *
+ * @param chatRoomUserSet New members or members to remove
+ * @param removeMember True if members should be removed, False if members
+ * should be added.
+ */
+ private void updateMemberList( Set<ChatRoomUser> chatRoomUserSet,
+ boolean removeMember)
+ {
+ Iterator<ChatRoomUser> it = chatRoomUserSet.iterator();
+
+ while (it.hasNext())
+ {
+ ChatRoomUser user = it.next();
+ String uid = user.getScreenname().getFormatted();
+
+ //we want to add a member and he/she is not in our member list
+ if (!removeMember
+&& !participants.containsKey(uid)
+&& !uid.equals(provider.getAccountID().getUserID()))
+ {
+ OperationSetPersistentPresenceIcqImpl presenceOpSet
+ = (OperationSetPersistentPresenceIcqImpl) getParentProvider()
+ .getOperationSet(OperationSetPersistentPresence.class);
+
+ Contact participant= presenceOpSet.getServerStoredContactList()
+ .findContactByScreenName(uid);
+
+ participants.put(uid, participant);
+
+ fireParticipantPresenceEvent(
+ participant,
+ AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_JOINED,
+ null);
+ }
+ //we want to remove a member and found him/her in our member list
+ if (removeMember&& participants.containsKey(uid))
+ {
+ Contact participant = participants
+ .get(uid);
+
+ participants.remove(uid);
+
+ fireParticipantPresenceEvent(
+ participant,
+ AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_LEFT,
+ null);
+ }
+ }
+ }
+
+ /**
+ * Utility method throwing an exception if the stack is not properly
+ * initialized.
+ * @throws java.lang.IllegalStateException if the underlying stack is
+ * not registered and initialized.
+ */
+ private void assertConnected() throws IllegalStateException
+ {
+ if (provider == null)
+ throw new IllegalStateException(
+ "The provider must be non-null and signed on the "
+ + "service before being able to communicate.");
+ if (!provider.isRegistered())
+ throw new IllegalStateException(
+ "The provider must be signed on the service before "
+ + "being able to communicate.");
+ }
+
+ /**
+ * Finds the member of this chat room corresponding to the given nick name.
+ *
+ * @param nickName the nick name to search for.
+ * @return the member of this chat room corresponding to the given nick name.
+ */
+ public Contact findParticipantForNickName(String nickName)
+ {
+ return participants.get(nickName);
+ }
+}

Added: trunk/src/net/java/sip/communicator/impl/protocol/icq/AdHocChatRoomInvitationIcqImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/icq/AdHocChatRoomInvitationIcqImpl.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/protocol/icq/AdHocChatRoomInvitationIcqImpl.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,96 @@
+/*
+ * 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.icq;
+
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * The ICQ implementation of the<tt>ChatRoomInvitation</tt> interface for
+ * ad-hoc chat rooms.
+ *
+ * @author Valentin Martinet
+ */
+public class AdHocChatRoomInvitationIcqImpl
+ implements AdHocChatRoomInvitation
+{
+ /**
+ * Corresponding ad-hoc chat room instance.
+ */
+ private AdHocChatRoom chatRoom;
+
+ /**
+ * The name of the inviter
+ */
+ private String inviter;
+
+ /**
+ * The invitation reason.
+ */
+ private String reason;
+
+ /**
+ * The password.
+ */
+ private byte[] password;
+
+ /**
+ * Creates an instance of the<tt>AdHocChatRoomInvitationIcqImpl</tt> by
+ * specifying the targetChatRoom, the inviter, the reason and the password.
+ *
+ * @param targetChatRoom The<tt>AdHocChatRoom</tt> for which the invitation
+ * is
+ * @param inviter The<tt>Contact</tt>, which sent the invitation
+ * @param reason The Reason for the invitation
+ * @param password The password
+ */
+ public AdHocChatRoomInvitationIcqImpl(AdHocChatRoom targetChatRoom,
+ String inviter,
+ String reason,
+ byte[] password)
+ {
+ this.chatRoom = targetChatRoom;
+ this.inviter = inviter;
+ this.reason = reason;
+ this.password = password;
+ }
+
+ /**
+ * Returns the corresponding ad-hoc chat room.
+ * @return The ad-hoc chat room
+ */
+ public AdHocChatRoom getTargetAdHocChatRoom()
+ {
+ return chatRoom;
+ }
+
+ /**
+ * Returns the corresponding inviter.
+ * @return The name of the inviter
+ */
+ public String getInviter()
+ {
+ return inviter;
+ }
+
+ /**
+ * Returns the invitation reason.
+ * @return the invitation reason
+ */
+ public String getReason()
+ {
+ return reason;
+ }
+
+ /**
+ * Returns the password of the chat room.
+ * @return The password
+ */
+ public byte[] getAdHocChatRoomPassword()
+ {
+ return password;
+ }
+}

Removed: trunk/src/net/java/sip/communicator/impl/protocol/icq/ChatRoomIcqImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/icq/ChatRoomIcqImpl.java?view=auto&rev=5963

Removed: trunk/src/net/java/sip/communicator/impl/protocol/icq/ChatRoomInvitationIcqImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/icq/ChatRoomInvitationIcqImpl.java?view=auto&rev=5963

Removed: trunk/src/net/java/sip/communicator/impl/protocol/icq/ChatRoomMemberIcqImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/icq/ChatRoomMemberIcqImpl.java?view=auto&rev=5963

Added: trunk/src/net/java/sip/communicator/impl/protocol/icq/OperationSetAdHocMultiUserChatIcqImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/icq/OperationSetAdHocMultiUserChatIcqImpl.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/protocol/icq/OperationSetAdHocMultiUserChatIcqImpl.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,513 @@
+/*
+ * 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.icq;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.event.*;
+import net.java.sip.communicator.util.Logger;
+import net.kano.joscar.*;
+import net.kano.joustsim.oscar.oscar.service.chatrooms.*;
+
+/**
+ * A ICQ implementation of the ad-hoc multi user chat operation set.
+ *
+ * @author Valentin Martinet
+ */
+public class OperationSetAdHocMultiUserChatIcqImpl
+ implements OperationSetAdHocMultiUserChat
+{
+ private static final Logger logger = Logger
+ .getLogger(OperationSetAdHocMultiUserChatIcqImpl.class);
+
+ /**
+ * The currently valid ICQ protocol provider service implementation.
+ */
+ private ProtocolProviderServiceIcqImpl icqProvider = null;
+
+ /**
+ * A list of listeners subscribed for invitations multi user chat events.
+ */
+ private Vector<AdHocChatRoomInvitationListener> invitationListeners
+ = new Vector<AdHocChatRoomInvitationListener>();
+
+ /**
+ * A list of listeners subscribed for events indicating rejection of a
+ * multi user chat invitation sent by us.
+ */
+ private Vector<AdHocChatRoomInvitationRejectionListener>
+ invitationRejectionListeners
+ = new Vector<AdHocChatRoomInvitationRejectionListener>();
+
+ /**
+ * Listeners that will be notified of changes in our status in the
+ * room such as us being kicked, banned, or granted admin permissions.
+ */
+ private Vector<LocalUserAdHocChatRoomPresenceListener> presenceListeners
+ = new Vector<LocalUserAdHocChatRoomPresenceListener>();
+
+ /**
+ * A list of the rooms that are currently open by this account. Note that
+ * we have not necessarily joined these rooms, we might have simply been
+ * searching through them.
+ */
+ private Hashtable<String, AdHocChatRoom> chatRoomCache
+ = new Hashtable<String, AdHocChatRoom>();
+
+ /**
+ * The registration listener that would get notified when the underlying
+ * ICQ provider gets registered.
+ */
+ private RegistrationStateListener providerRegListener
+ = new RegistrationStateListener();
+
+ /**
+ * A reference to the persistent presence operation set that we use
+ * to match incoming messages to<tt>Contact</tt>s and vice versa.
+ */
+ protected OperationSetPersistentPresenceIcqImpl opSetPersPresence = null;
+
+ /**
+ * Hash table that contains all invitations, this is needed if the user wants
+ * to reject an invitation.
+ */
+ private Hashtable<AdHocChatRoom, ChatInvitation> invitations
+ = new Hashtable<AdHocChatRoom, ChatInvitation>();
+
+ /**
+ * Instantiates the user operation set with a currently valid instance of
+ * the Icq protocol provider.
+ * @param icqProvider a currently valid instance of
+ * ProtocolProviderServiceIcqImpl.
+ */
+ OperationSetAdHocMultiUserChatIcqImpl(
+ ProtocolProviderServiceIcqImpl icqProvider)
+ {
+ this.icqProvider = icqProvider;
+ icqProvider.addRegistrationStateChangeListener(providerRegListener);
+ }
+
+ /**
+ * Adds a listener to invitation notifications.
+ *
+ * @param listener an invitation listener.
+ */
+ public void addInvitationListener(AdHocChatRoomInvitationListener listener)
+ {
+ synchronized (invitationListeners)
+ {
+ if (!invitationListeners.contains(listener))
+ invitationListeners.add(listener);
+ }
+ }
+
+ /**
+ * Subscribes<tt>listener</tt> so that it would receive events indicating
+ * rejection of a multi user chat invitation that we've sent earlier.
+ *
+ * @param listener the listener that we'll subscribe for invitation
+ * rejection events.
+ */
+ public void addInvitationRejectionListener(
+ AdHocChatRoomInvitationRejectionListener listener)
+ {
+ synchronized (invitationRejectionListeners)
+ {
+ if (!invitationRejectionListeners.contains(listener))
+ invitationRejectionListeners.add(listener);
+ }
+ }
+
+ /**
+ * Adds a listener that will be notified of changes in our status in a chat
+ * room such as us being kicked, banned or dropped.
+ *
+ * @param listener the<tt>LocalUserAdHocChatRoomPresenceListener</tt>.
+ */
+ public void addPresenceListener(
+ LocalUserAdHocChatRoomPresenceListener listener)
+ {
+ synchronized (presenceListeners)
+ {
+ if (!presenceListeners.contains(listener))
+ presenceListeners.add(listener);
+ }
+ }
+
+ /**
+ * Returns a reference to a chatRoom by an given chat invitation. This method
+ * is called, when the user received a chat invitation. The chat room will be
+ * created and the chatInvitation will be saved in the created chat room. This
+ * ensures to get the chat room session for each chat room.
+ *
+ * @param chatInvitation The Chat invitation the user received
+ * @return A chat room based on the chat invitation
+ * @throws OperationFailedException if an error occurs while trying to
+ * discover the room on the server.
+ * @throws OperationNotSupportedException if the server does not support
+ * multi user chat
+ */
+ public AdHocChatRoom findRoom(ChatInvitation chatInvitation)
+ throws OperationFailedException, OperationNotSupportedException
+ {
+ AdHocChatRoom chatRoom = (AdHocChatRoom) chatRoomCache.get(chatInvitation
+ .getRoomName());
+
+ if (chatRoom == null)
+ {
+ chatRoom = createLocalChatRoomInstance(chatInvitation);
+ }
+
+ return chatRoom;
+ }
+
+ /**
+ * Creates an<tt>AdHocChatRoom</tt> from the specified smack
+ *<tt>MultiUserChat</tt>.
+ *
+ * @param chatInvitation The chat invitation we received from the
+ * chatRoomManager
+ *
+ * @return ChatRoom the chat room that we've just created.
+ */
+
+ private AdHocChatRoom createLocalChatRoomInstance(
+ ChatInvitation chatInvitation)
+ {
+ synchronized (chatRoomCache)
+ {
+ AdHocChatRoom newChatRoom = new AdHocChatRoomIcqImpl(chatInvitation,
+ icqProvider);
+
+ chatRoomCache.put(chatInvitation.getRoomName(), newChatRoom);
+ return newChatRoom;
+ }
+ }
+
+ /**
+ * Creates a room with the named<tt>roomName</tt> and according to the
+ * specified<tt>roomProperties</tt> on the server that this protocol
+ * provider is currently connected to.
+ *
+ * @param roomName the name of the<tt>AdHocChatRoom</tt> to create.
+ * @param roomProperties properties specifying how the room should be
+ * created. Contains list of invitees and the invitation message.
+ *
+ * @throws OperationFailedException if the room couldn't be created for
+ * some reason (e.g. room already exists; user already joined to an
+ * existent room or user has no permissions to create an ad-hoc chat room).
+ * @throws OperationNotSupportedException if ad-hoc chat room creation is not
+ * supported by this server
+ *
+ * @return AdHocChatRoom the ad-hoc chat room that we've just created.
+ */
+ public AdHocChatRoom createAdHocChatRoom( String roomName,
+ Map<String, Object> roomProperties)
+ throws OperationFailedException,
+ OperationNotSupportedException
+ {
+ AdHocChatRoom chatRoom = null;
+
+ ChatRoomManager chatRoomManager = icqProvider.getAimConnection()
+ .getChatRoomManager();
+
+ ChatRoomSession chatRoomSession = chatRoomManager.joinRoom(roomName);
+
+ if(chatRoomSession != null)
+ {
+ chatRoom = new AdHocChatRoomIcqImpl( roomName,
+ chatRoomSession,
+ icqProvider);
+ }
+
+ return chatRoom;
+ }
+
+ /**
+ * Creates an ad-hoc room with the named<tt>adHocRoomName</tt> and in
+ * including to the specified<tt>contacts</tt>. When the method
+ * returns the ad-hoc room the local user will not have joined it and thus
+ * will not receive messages on it until the<tt>AdHocChatRoom.join()</tt>
+ * method is called.
+ *
+ * NOTE: this method was done for the Yahoo! implementation. But since both
+ * Yahoo! and ICQ are implementing the ad-hoc multi-user-chat operation set,
+ * we have to define this method here.
+ *
+ * @param adHocRoomName the name of the ad-hoc room
+ * @param contacts the list of contacts
+ *
+ * @throws OperationFailedException
+ * @throws OperationNotSupportedException
+ */
+ public AdHocChatRoom createAdHocChatRoom(String adHocRoomName,
+ List<Contact> contacts)
+ throws OperationFailedException,
+ OperationNotSupportedException
+ {
+ AdHocChatRoom chatRoom = null;
+
+ ChatRoomManager chatRoomManager = icqProvider.getAimConnection()
+ .getChatRoomManager();
+
+ ChatRoomSession chatRoomSession = chatRoomManager.joinRoom(adHocRoomName);
+
+ if(chatRoomSession != null)
+ {
+ chatRoom = new AdHocChatRoomIcqImpl( adHocRoomName,
+ chatRoomSession,
+ icqProvider);
+ }
+
+ return chatRoom;
+ }
+
+ /**
+ * Returns a reference to a chatRoom named<tt>roomName</tt> or null if
+ * no such room exists.
+ *
+ * @param roomName the name of the<tt>AdHocChatRoom</tt> that we're looking
+ * for.
+ * @return the<tt>AdHocChatRoom</tt> named<tt>roomName</tt> or null if no
+ * such room exists on the server that this provider is currently
+ * connected to.
+ * @throws OperationFailedException if an error occurs while trying to
+ * discover the room on the server.
+ * @throws OperationNotSupportedException if the server does not support
+ * multi user chat
+ */
+
+ public AdHocChatRoom findRoom(String roomName)
+ throws OperationFailedException, OperationNotSupportedException
+ {
+ AdHocChatRoom room = (AdHocChatRoom) chatRoomCache.get(roomName);
+
+ return room;
+ }
+
+ /**
+ * Returns true if<tt>contact</tt> supports multi user chat sessions.
+ *
+ * @param contact reference to the contact whose support for chat rooms
+ * we are currently querying.
+ * @return a boolean indicating whether<tt>contact</tt> supports
+ * chat rooms.
+ */
+ public boolean isMultiChatSupportedByContact(Contact contact)
+ {
+ if (contact.getProtocolProvider().getOperationSet(
+ OperationSetAdHocMultiUserChat.class) != null)
+ return true;
+
+ return false;
+ }
+
+ /**
+ * Informs the sender of an invitation that we decline their invitation.
+ *
+ * @param invitation the connection to use for sending the rejection.
+ * @param rejectReason the reason to reject the given invitation
+ */
+ public void rejectInvitation(AdHocChatRoomInvitation invitation,
+ String rejectReason)
+ {
+ ChatInvitation inv = (ChatInvitation) invitations.get(invitation
+ .getTargetAdHocChatRoom());
+
+ if (inv != null)
+ { //send the rejection
+ inv.reject();
+ }
+ //remove the invitation
+ invitations.remove(invitation.getTargetAdHocChatRoom());
+ }
+
+ /**
+ * Removes<tt>listener</tt> from the list of invitation listeners
+ * registered to receive invitation events.
+ *
+ * @param listener the invitation listener to remove.
+ */
+ public void removeInvitationListener(
+ AdHocChatRoomInvitationListener listener)
+ {
+ synchronized (invitationListeners)
+ {
+ invitationListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Removes<tt>listener</tt> from the list of invitation listeners
+ * registered to receive invitation rejection events.
+ *
+ * @param listener the invitation listener to remove.
+ */
+ public void removeInvitationRejectionListener(
+ AdHocChatRoomInvitationRejectionListener listener)
+ {
+ synchronized (invitationRejectionListeners)
+ {
+ invitationRejectionListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Removes a listener that was being notified of changes in our status in
+ * a room such as us being joined or dropped.
+ *
+ * @param listener the<tt>LocalUserAdHocChatRoomPresenceListener</tt>.
+ */
+ public void removePresenceListener(
+ LocalUserAdHocChatRoomPresenceListener listener)
+ {
+ synchronized (presenceListeners)
+ {
+ presenceListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Delivers a<tt>AdHocChatRoomInvitationReceivedEvent</tt> to all
+ * registered<tt>AdHocChatRoomInvitationListener</tt>s.
+ *
+ * @param targetChatRoom the ad-hoc 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, byte[] password)
+ {
+ AdHocChatRoomInvitationIcqImpl invitation =
+ new AdHocChatRoomInvitationIcqImpl(
+ targetChatRoom, inviter, reason, password);
+
+ AdHocChatRoomInvitationReceivedEvent evt
+ = new AdHocChatRoomInvitationReceivedEvent(
+ this, invitation, new Date(System.currentTimeMillis()));
+
+ Iterator<AdHocChatRoomInvitationListener> listeners = null;
+ synchronized (invitationListeners)
+ {
+ listeners = new ArrayList<AdHocChatRoomInvitationListener>
+ (invitationListeners).iterator();
+ }
+
+ while (listeners.hasNext())
+ {
+ AdHocChatRoomInvitationListener listener
+ = (AdHocChatRoomInvitationListener) listeners.next();
+
+ listener.invitationReceived(evt);
+ }
+ }
+
+ /**
+ * Delivers a<tt>LocalUserAdHocChatRoomPresenceChangeEvent</> to all
+ * registered<tt>LocalUserAdHocChatRoomPresenceListener</tt>s.
+ *
+ * @param chatRoom the<tt>AdHocChatRoom</tt> which has been joined, left,
+ * etc.
+ * @param eventType the type of this event; one of LOCAL_USER_JOINED,
+ * LOCAL_USER_LEFT, etc.
+ * @param reason the reason
+ */
+ public void fireLocalUserPresenceEvent( AdHocChatRoom chatRoom,
+ String eventType,
+ String reason)
+ {
+ LocalUserAdHocChatRoomPresenceChangeEvent evt =
+ new LocalUserAdHocChatRoomPresenceChangeEvent(
+ this, chatRoom, eventType, reason);
+
+ Iterator<LocalUserAdHocChatRoomPresenceListener> listeners = null;
+ synchronized (presenceListeners)
+ {
+ listeners = new ArrayList<LocalUserAdHocChatRoomPresenceListener>
+ (presenceListeners).iterator();
+ }
+
+ while (listeners.hasNext())
+ {
+ LocalUserAdHocChatRoomPresenceListener listener
+ = (LocalUserAdHocChatRoomPresenceListener) listeners.next();
+
+ listener.localUserAdHocPresenceChanged(evt);
+ }
+ }
+
+ /**
+ * Our listener that will tell us when we're registered to icq and joust
+ * sim is ready to accept us as a listener.
+ */
+ private class RegistrationStateListener implements
+ RegistrationStateChangeListener
+ {
+ /**
+ * The method is called by a ProtocolProvider implementation whenever
+ * a change in the registration state of the corresponding provider had
+ * occurred.
+ * @param evt ProviderStatusChangeEvent the event describing the status
+ * change.
+ */
+ public void registrationStateChanged(RegistrationStateChangeEvent evt)
+ {
+ logger.debug("The ICQ provider changed state from: "
+ + evt.getOldState() + " to: " + evt.getNewState());
+ if (evt.getNewState() == RegistrationState.REGISTERED)
+ {
+ String customMessageEncoding = null;
+ if ((customMessageEncoding = System
+ .getProperty("icq.custom.message.charset")) != null)
+ OscarTools.setDefaultCharset(customMessageEncoding);
+
+ opSetPersPresence =
+ (OperationSetPersistentPresenceIcqImpl) icqProvider
+ .getOperationSet(OperationSetPersistentPresence.class);
+
+ //add ChatRoomMangagerListener
+ icqProvider.getAimConnection().getChatRoomManager()
+ .addListener(new ChatRoomManagerListenerImpl());
+ }
+ }
+ }
+
+ /**
+ * Our listener for chat room invitations.
+ *
+ */
+ private class ChatRoomManagerListenerImpl
+ implements ChatRoomManagerListener
+ {
+ public void handleInvitation(ChatRoomManager chatRoomManager,
+ ChatInvitation chatInvitation)
+ {
+ logger
+ .debug("Invitation received: "
+ + chatInvitation.getRoomName());
+ try
+ {
+ AdHocChatRoom chatRoom = findRoom(chatInvitation);
+ // save chatInvitation, for a possible rejection
+ invitations.put(chatRoom, chatInvitation);
+
+ fireInvitationEvent(chatRoom, chatInvitation.getScreenname()
+ .toString(), chatInvitation.getMessage(), null);
+ }
+ catch (OperationNotSupportedException onse)
+ {
+ logger.debug("Failed to handle ChatInvitation: " + onse);
+ }
+ catch (OperationFailedException ofe)
+ {
+ logger.debug("Failed to handle ChatInvitation: " + ofe);
+ }
+ }
+ }
+}

Removed: trunk/src/net/java/sip/communicator/impl/protocol/icq/OperationSetMultiUserChatIcqImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/icq/OperationSetMultiUserChatIcqImpl.java?view=auto&rev=5963

Modified: trunk/src/net/java/sip/communicator/impl/protocol/icq/ProtocolProviderServiceIcqImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/icq/ProtocolProviderServiceIcqImpl.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/protocol/icq/ProtocolProviderServiceIcqImpl.java&p2=trunk/src/net/java/sip/communicator/impl/protocol/icq/ProtocolProviderServiceIcqImpl.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/protocol/icq/ProtocolProviderServiceIcqImpl.java (original)
+++ trunk/src/net/java/sip/communicator/impl/protocol/icq/ProtocolProviderServiceIcqImpl.java 2009-09-14 15:51:47+0000
@@ -26,6 +26,7 @@
  *
  * @author Emil Ivov
  * @author Damian Minkov
+ * @author Valentin Martinet
  */
public class ProtocolProviderServiceIcqImpl
     extends AbstractProtocolProviderService
@@ -455,9 +456,10 @@
             if(IcqAccountID.isAIM(accountID.getAccountProperties()))
                     USING_ICQ = false;

- supportedOperationSets.put(OperationSetInstantMessageTransform.class.getName(),
+ supportedOperationSets.put(
+ OperationSetInstantMessageTransform.class.getName(),
                 new OperationSetInstantMessageTransformImpl());
-
+
             //initialize the presence operationset
             OperationSetPersistentPresence persistentPresence =
                 new OperationSetPersistentPresenceIcqImpl(this, screenname);
@@ -477,13 +479,13 @@
             supportedOperationSets.put(
                 OperationSetBasicInstantMessaging.class.getName(),
                 basicInstantMessaging);
-
- //initialize the multi chat operation set
- OperationSetMultiUserChatIcqImpl multiUserOpSet
- = new OperationSetMultiUserChatIcqImpl(this);
+
+ //initialize the multi chat operation set
+ OperationSetAdHocMultiUserChatIcqImpl multiUserOpSet
+ = new OperationSetAdHocMultiUserChatIcqImpl(this);

             supportedOperationSets.put(
- OperationSetMultiUserChat.class.getName(),
+ OperationSetAdHocMultiUserChat.class.getName(),
                 multiUserOpSet);

             //initialize the typing notifications operation set

Copied: trunk/src/net/java/sip/communicator/impl/protocol/msn/AdHocChatRoomInvitationMsnImpl.java (from r5898, /trunk/src/net/java/sip/communicator/impl/protocol/msn/ChatRoomInvitationMsnImpl.java)
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/msn/AdHocChatRoomInvitationMsnImpl.java?view=diff&rev=5964&p1=/trunk/src/net/java/sip/communicator/impl/protocol/msn/ChatRoomInvitationMsnImpl.java&p2=trunk/src/net/java/sip/communicator/impl/protocol/msn/AdHocChatRoomInvitationMsnImpl.java&r1=5898&r2=5964

--- /trunk/src/net/java/sip/communicator/impl/protocol/msn/ChatRoomInvitationMsnImpl.java (original)
+++ trunk/src/net/java/sip/communicator/impl/protocol/msn/AdHocChatRoomInvitationMsnImpl.java 2009-09-14 15:51:47+0000
@@ -9,54 +9,43 @@
import net.java.sip.communicator.service.protocol.*;

/**
- * The MSN implementation of the<tt>ChatRoomInvitation</tt> interface.
+ * The MSN implementation of the<tt>AdHocChatRoomInvitation</tt> interface.
+ *
  * @author Rupert Burchardi
+ * @author Yana Stamcheva
  */
-public class ChatRoomInvitationMsnImpl implements ChatRoomInvitation
+public class AdHocChatRoomInvitationMsnImpl
+ implements AdHocChatRoomInvitation
{
    /**
     * Corresponding chat room instance.
     */
- private ChatRoom chatRoom;
+ private AdHocChatRoom chatRoom;
    /**
- * The name of the inviter
+ * The name of the inviter.
     */
    private String inviter;
- /**
- * The invitation reason. Note: Not supported in the msn protocol.
- */
- private String reason;
-
- /**
- * The password. Note: Not supported in the msn protocol.
- */
- private byte[] password;

    /**
- * Creates an instance of the<tt>ChatRoomInvitationMsnImpl</> by
+ * Creates an instance of the<tt>AdHocChatRoomInvitationMsnImpl</tt> by
     * specifying the targetChatRoom, the inviter, the reason and the password.
     *
- * @param targetChatRoom The<tt>ChatRoom</tt> for which the invitation is
- * @param inviter The<tt>ChatRoomMember</tt>, which sent the invitation
- * @param reason The Reason for the invitation
- * @param password The password
- */
- public ChatRoomInvitationMsnImpl(ChatRoom targetChatRoom,
- String inviter,
- String reason,
- byte[] password)
+ * @param targetChatRoom the<tt>AdHocChatRoom</tt> for which the invitation
+ * is
+ * @param inviter the contact, which sent the invitation
+ */
+ public AdHocChatRoomInvitationMsnImpl(AdHocChatRoom targetChatRoom,
+ String inviter)
    {
        this.chatRoom = targetChatRoom;
        this.inviter = inviter;
- this.reason = reason;
- this.password = password;
    }

    /**
     * Returns the corresponding chat room.
     * @return The chat room
     */
- public ChatRoom getTargetChatRoom()
+ public AdHocChatRoom getTargetAdHocChatRoom()
    {
        return chatRoom;
    }
@@ -76,14 +65,7 @@
     */
    public String getReason()
    {
- return reason;
- }
- /**
- * Returns the password of the chat room.
- * @return The password
- */
- public byte[] getChatRoomPassword()
- {
- return password;
+ //Not supported in the Msn protocol.
+ return null;
    }
}

Added: trunk/src/net/java/sip/communicator/impl/protocol/msn/AdHocChatRoomMsnImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/msn/AdHocChatRoomMsnImpl.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/protocol/msn/AdHocChatRoomMsnImpl.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,557 @@
+/*
+ * 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.msn;
+
+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 net.sf.jml.*;
+
+/**
+ * Implements ad-hoc chat rooms for MSN.
+ *
+ * @author Rupert Burchardi
+ * @author Valentin Martinet
+ */
+public class AdHocChatRoomMsnImpl
+ implements AdHocChatRoom
+{
+ private static final Logger logger
+ = Logger.getLogger(AdHocChatRoomMsnImpl.class);
+
+ /**
+ * The protocol provider that created us
+ */
+ private final ProtocolProviderServiceMsnImpl provider;
+
+ /**
+ * The OperationSet for MSN multi user chats.
+ */
+ private OperationSetAdHocMultiUserChatMsnImpl opSetAdHocMuc = null;
+
+ /**
+ * The corresponding switchboard for the chat room. Each chat room has its
+ * own switchboard and if it is closed the user cannot reconnect to it, see
+ * MSN documentation for further infos.
+ */
+ private MsnSwitchboard switchboard = null;
+
+ /**
+ * Listeners that will be notified of changes in participants status in the
+ * ad-hoc room, such as participant joined, left, etc.
+ */
+ private Vector<AdHocChatRoomParticipantPresenceListener>
+ participantsPresenceListeners =
+ new Vector<AdHocChatRoomParticipantPresenceListener>();
+
+ /**
+ * Listeners that will be notified every time a new message is received on
+ * this ad-hoc chat room.
+ */
+ private Vector<AdHocChatRoomMessageListener> messageListeners
+ = new Vector<AdHocChatRoomMessageListener>();
+
+ /**
+ * A Message buffer, will keep all messages until the MSN ad-hoc chat room
+ * is ready.
+ */
+ public Vector<EventObject> messageBuffer = new Vector<EventObject>();
+
+ /**
+ * The name of this ad-hoc chat room
+ */
+ private String name;
+
+ /**
+ * The list of participants of this ad-hoc chat room.
+ */
+ private final Hashtable<String, Contact> participants =
+ new Hashtable<String, Contact>();
+
+ /**
+ * List of unresolved member names.
+ */
+ private ArrayList<String> pendingInvitations = new ArrayList<String>();
+
+ /**
+ * Creates a new ad-hoc chat room for MSN named<tt>name</tt>, using the
+ * protocol provider<tt>provider</tt>.
+ *
+ * @param name
+ * @param provider
+ */
+ public AdHocChatRoomMsnImpl(String name,
+ ProtocolProviderServiceMsnImpl provider)
+ {
+ this.name = name;
+ this.provider = provider;
+ this.opSetAdHocMuc =
+ (OperationSetAdHocMultiUserChatMsnImpl)
+ this.provider.getOperationSet(OperationSetAdHocMultiUserChat.class);
+ }
+
+ /**
+ * Creates a new ad-hoc chat room for MSN named<tt>name</tt>, using the
+ * protocol provider<tt>provider</tt> and the msn switchboard
+ *<tt>switchboard</tt>.
+ *
+ * @param name
+ * @param provider
+ * @param switchboard
+ */
+ public AdHocChatRoomMsnImpl(String name,
+ ProtocolProviderServiceMsnImpl provider,
+ MsnSwitchboard switchboard)
+ {
+ this.name = name;
+ this.provider = provider;
+ this.opSetAdHocMuc =
+ (OperationSetAdHocMultiUserChatMsnImpl)
+ this.provider.getOperationSet(OperationSetAdHocMultiUserChat.class);
+ this.switchboard = switchboard;
+ }
+
+ /**
+ * Adds a listener that will be notified of changes in our status in the
+ * room.
+ *
+ * @param listener a participant status listener.
+ */
+ public void addParticipantPresenceListener(
+ AdHocChatRoomParticipantPresenceListener listener)
+ {
+ synchronized(this.participantsPresenceListeners)
+ {
+ if (!this.participantsPresenceListeners.contains(listener))
+ this.participantsPresenceListeners.add(listener);
+ }
+ }
+
+ /**
+ * Registers<tt>listener</tt> so that it would receive events every time a
+ * new message is received on this chat room.
+ *
+ * @param listener a<tt>MessageListener</tt> that would be notified every
+ * time a new message is received on this chat room.
+ */
+ public void addMessageListener(AdHocChatRoomMessageListener listener)
+ {
+ synchronized(this.messageListeners)
+ {
+ if (!this.messageListeners.contains(listener))
+ this.messageListeners.add(listener);
+ }
+ }
+
+ /**
+ * Removes<tt>listener</tt> so that it won't receive any further message
+ * events from this room.
+ *
+ * @param listener the<tt>MessageListener</tt> to remove from this room
+ */
+ public void removeMessageListener(ChatRoomMessageListener listener)
+ {
+ synchronized (messageListeners)
+ {
+ if (messageListeners.contains(listener))
+ messageListeners.remove(messageListeners.indexOf(listener));
+ }
+ }
+
+ /**
+ * Finds the participant of this ad-hoc chat room corresponding to the
+ * given address.
+ *
+ * @param address the address to search for.
+ * @return the participant of this chat room corresponding to the given
+ * nick name.
+ */
+ public Contact findParticipantForAddress(String address)
+ {
+ Iterator<Contact> participantsIter
+ = this.participants.values().iterator();
+
+ while (participantsIter.hasNext())
+ {
+ Contact contact = participantsIter.next();
+
+ if (contact.getAddress().equals(address))
+ {
+ return contact;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Creates a<tt>Message</tt> for this ad-hoc chat room containing
+ *<tt>text</tt>.
+ *
+ * @param text
+ * @return Message the newly created<tt>Message</tt>
+ */
+ public Message createMessage(String text)
+ {
+ Message msg =
+ new MessageMsnImpl(text,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_ENCODING, null);
+
+ return msg;
+ }
+
+ /**
+ * Returns the name of this ad-hoc chatroom
+ *
+ * @return String
+ */
+ public String getName()
+ {
+ return this.name;
+ }
+
+ /**
+ * Returns the parent provider
+ *
+ * @return ProtocolProviderService
+ */
+ public ProtocolProviderService getParentProvider()
+ {
+ return this.provider;
+ }
+
+ /**
+ * Returns a list containing all the<tt>Contact</tt>s who participate in
+ * this ad-hoc chat room.
+ *
+ * @return List<Contact>
+ */
+ public List<Contact> getParticipants()
+ {
+ return new LinkedList<Contact>(this.participants.values());
+ }
+
+ /**
+ * Returns the participant of this ad-hoc chat room which corresponds to
+ * the given _id.
+ *
+ * @param _id
+ * @return Contact the corresponding Contact
+ */
+ public Contact getAdHocChatRoomParticipant(String id)
+ {
+ return this.participants.get(id);
+ }
+
+ /**
+ * Adds a participant to the participants list.
+ *
+ * @param participant The participant (<tt>Contact</tt>) to add.
+ */
+ public void addAdHocChatRoomParticipant(String id, Contact participant)
+ {
+ this.participants.put(id, participant);
+
+ fireParticipantPresenceEvent(participant,
+ AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_JOINED, null);
+ }
+
+ /**
+ * Removes the participant of this ad-hoc chat room which corresponds to
+ * the given _id.
+ *
+ * @param _id
+ */
+ public void removeParticipant(String id)
+ {
+ Contact contact= this.participants.get(id);
+ this.participants.remove(id);
+
+ fireParticipantPresenceEvent(contact,
+ AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_LEFT, null);
+ }
+
+ /**
+ * Returns the number of<tt>Contact</tt>s who participate in this ad-hoc
+ * chat room.
+ */
+ public int getParticipantsCount()
+ {
+ return this.participants.size();
+ }
+
+ public String getSubject()
+ {
+ return null;
+ }
+
+ /**
+ * Invites another user to this room. If we're not joined nothing will
+ * happen.
+ *
+ * @param userAddress the address of the user (email address) to invite to
+ * the room.(one may also invite users not on their contact
+ * list).
+ * @param reason You cannot specify a Reason inside the msn protocol
+ */
+ public void invite(String userAddress, String reason)
+ {
+ // msn requires lower case email addresses
+ userAddress = userAddress.toLowerCase();
+
+ if (switchboard == null)
+ {
+ pendingInvitations.add(userAddress);
+ }
+ else
+ {
+ switchboard.inviteContact(Email.parseStr(userAddress));
+ }
+ }
+
+ public void join()
+ {
+ // We don't specify a reason.
+ this.opSetAdHocMuc.fireLocalUserPresenceEvent(this,
+ LocalUserAdHocChatRoomPresenceChangeEvent.LOCAL_USER_JOINED, null);
+
+ // We buffered the messages before the user has joined the chat, now the
+ // user has joined so we fire them again
+ for (EventObject evt : this.messageBuffer)
+ {
+ this.fireMessageEvent(evt);
+ }
+ }
+
+ /**
+ * Leave this chat room. Once this method is called, the user won't be
+ * listed as a member of the chat room any more and no further chat events
+ * will be delivered. Depending on the underlying protocol and
+ * implementation leave() might cause the room to be destroyed if it has
+ * been created by the local user.
+ */
+ public void leave()
+ {
+ if (switchboard != null)
+ {
+ switchboard.close();
+ switchboard = null;
+ }
+
+ Iterator<Contact> participantsIter
+ = participants.values().iterator();
+
+ while (participantsIter.hasNext())
+ {
+ Contact participant = (Contact) participantsIter.next();
+
+ fireParticipantPresenceEvent(participant,
+ AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_LEFT,
+ "Local user has left the chat room.");
+ }
+
+ // Delete the list of members
+ participants.clear();
+ }
+
+ public boolean isSystem()
+ {
+ return false;
+ }
+
+ /**
+ * Sends the given message through the participants of this ad-hoc chat
+ * room.
+ *
+ * @param message the message to delivered
+ *
+ * @throws OperationFailedException if send fails
+ */
+ public void sendMessage(Message message) throws OperationFailedException
+ {
+ logger.setLevelInfo();
+ logger.info("switchboard="+this.switchboard);
+ this.switchboard.sendText(message.getContent());
+
+ AdHocChatRoomMessageDeliveredEvent msgDeliveredEvt
+ = new AdHocChatRoomMessageDeliveredEvent(
+ this,
+ System.currentTimeMillis(),
+ message,
+ AdHocChatRoomMessageDeliveredEvent.CONVERSATION_MESSAGE_DELIVERED);
+
+ this.fireMessageEvent(msgDeliveredEvt);
+ }
+
+ /**
+ * Sets the corresponding switchboard.
+ *
+ * @param switchboard Corresponding switchboard.
+ */
+ public void setSwitchboard(MsnSwitchboard switchboard)
+ {
+ this.switchboard = switchboard;
+ }
+
+ /**
+ * Creates the corresponding AdHocChatRoomParticipantPresenceChangeEvent and
+ * notifies all<tt>AdHocChatRoomParticipantPresenceListener</>s that a
+ * participant has joined or left this<tt>AdHocChatRoom</tt>.
+ *
+ * @param participant the<tt>Contact</tt>
+ * @param eventID the identifier of the event
+ * @param eventReason the reason of the event
+ */
+ private void fireParticipantPresenceEvent( Contact participant,
+ String eventID,
+ String eventReason)
+ {
+ AdHocChatRoomParticipantPresenceChangeEvent evt =
+ new AdHocChatRoomParticipantPresenceChangeEvent(
+ this, participant, eventID, eventReason);
+
+ logger.trace("Will dispatch the following AdHocChatRoom event: " + evt);
+
+ Iterator<AdHocChatRoomParticipantPresenceListener> listeners = null;
+ synchronized (this.participantsPresenceListeners)
+ {
+ listeners = new ArrayList<AdHocChatRoomParticipantPresenceListener>(
+ this.participantsPresenceListeners).iterator();
+ }
+
+ while (listeners.hasNext())
+ {
+ listeners.next().participantPresenceChanged(evt);
+ }
+ }
+
+ /**
+ * Notifies all interested listeners that a
+ *<tt>AdHocChatRoomMessageDeliveredEvent</tt>,
+ *<tt>AdHocChatRoomMessageReceivedEvent</tt> or a
+ *<tt>AdHocChatRoomMessageDeliveryFailedEvent</tt> has been fired.
+ *
+ * @param evt The specific event
+ */
+ public void fireMessageEvent(EventObject evt)
+ {
+ Iterator<AdHocChatRoomMessageListener> listeners = null;
+ synchronized (messageListeners)
+ {
+ listeners = new ArrayList<AdHocChatRoomMessageListener>(
+ messageListeners).iterator();
+ }
+
+ if (!listeners.hasNext())
+ {
+ messageBuffer.add(evt);
+ }
+
+ while (listeners.hasNext())
+ {
+ AdHocChatRoomMessageListener listener =
+ (AdHocChatRoomMessageListener) listeners.next();
+
+ if (evt instanceof AdHocChatRoomMessageDeliveredEvent)
+ {
+ listener.messageDelivered(
+ (AdHocChatRoomMessageDeliveredEvent) evt);
+ }
+ else if (evt instanceof AdHocChatRoomMessageReceivedEvent)
+ {
+ listener.messageReceived(
+ (AdHocChatRoomMessageReceivedEvent) evt);
+ }
+ else if (evt instanceof AdHocChatRoomMessageDeliveryFailedEvent)
+ {
+ listener.messageDeliveryFailed(
+ (AdHocChatRoomMessageDeliveryFailedEvent) evt);
+ }
+ }
+ }
+
+ /**
+ * Fills the participants list with all participants inside the switchboard
+ * (ad-hoc chat room).
+ *
+ * @param switchboard The corresponding switchboard
+ */
+ public void updateParticipantsList(MsnSwitchboard switchboard)
+ {
+ MsnContact[] contacts = switchboard.getAllContacts();
+
+ for (MsnContact msnContact : contacts)
+ {
+ if (!this.participants.containsKey(msnContact.getId()))
+ {
+// // if the member is not inside the members list, create a
+// // contact instance,
+// // add it to the list and fire a member presence event
+// Contact participant =
+// new ContactMsnImpl(msnContact,
+// msnContact.getDisplayName(),
+// msnContact.getEmail().getEmailAddress(),
+// ChatRoomMemberRole.MEMBER);
+
+ this.participants.put(msnContact.getId(), (Contact) msnContact);
+
+ fireParticipantPresenceEvent(
+ (Contact) msnContact,
+ AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_JOINED,
+ null);
+ }
+ }
+
+ for (String contactAddress: this.pendingInvitations)
+ {
+ this.invite(contactAddress, "");
+ }
+ }
+
+ /**
+ * Returns the identifier of this ad-hoc chat room.
+ *
+ * @return a<tt>String</tt> containing the identifier of this ad-hoc room
+ */
+ public String getIdentifier()
+ {
+ return this.getName();
+ }
+
+ /**
+ * Removes the given participant presence listener.
+ *
+ * @param listener the listener to remove
+ */
+ public void removeParticipantPresenceListener(
+ AdHocChatRoomParticipantPresenceListener listener)
+ {
+ synchronized (this.participantsPresenceListeners)
+ {
+ if (this.participantsPresenceListeners.contains(listener))
+ this.participantsPresenceListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Removes the given message listener.
+ *
+ * @param listener the listener to remove
+ */
+ public void removeMessageListener(AdHocChatRoomMessageListener listener)
+ {
+ synchronized(this.messageListeners)
+ {
+ if(this.messageListeners.contains(listener))
+ {
+ this.messageListeners.remove(listener);
+ }
+ }
+ }
+}

Removed: trunk/src/net/java/sip/communicator/impl/protocol/msn/ChatRoomInvitationMsnImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/msn/ChatRoomInvitationMsnImpl.java?view=auto&rev=5963

Removed: trunk/src/net/java/sip/communicator/impl/protocol/msn/ChatRoomMemberMsnImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/msn/ChatRoomMemberMsnImpl.java?view=auto&rev=5963

Removed: trunk/src/net/java/sip/communicator/impl/protocol/msn/ChatRoomMsnImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/msn/ChatRoomMsnImpl.java?view=auto&rev=5963

Added: trunk/src/net/java/sip/communicator/impl/protocol/msn/OperationSetAdHocMultiUserChatMsnImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/msn/OperationSetAdHocMultiUserChatMsnImpl.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/protocol/msn/OperationSetAdHocMultiUserChatMsnImpl.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,734 @@
+/*
+ * 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.msn;
+
+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 net.sf.jml.*;
+import net.sf.jml.event.*;
+import net.sf.jml.message.*;
+
+/**
+ * A MSN implementation of the ad-hoc multi user chat operation set.
+ *
+ * @author Valentin Martinet
+ */
+public class OperationSetAdHocMultiUserChatMsnImpl
+ implements OperationSetAdHocMultiUserChat
+{
+ private static final Logger logger
+ = Logger.getLogger(OperationSetAdHocMultiUserChatMsnImpl.class);
+
+ /**
+ * Listeners that will be notified of changes in our status in the room.
+ */
+ private Vector<LocalUserAdHocChatRoomPresenceListener> presenceListeners
+ = new Vector<LocalUserAdHocChatRoomPresenceListener>();
+
+ /**
+ * The currently valid MSN protocol provider service implementation.
+ */
+ private ProtocolProviderServiceMsnImpl provider = null;
+
+ /**
+ * The ad-hoc rooms we currently are in.
+ */
+ private Hashtable<String, AdHocChatRoomMsnImpl> adHocChatRoomCache
+ = new Hashtable<String, >();
+
+ /**
+ * A list of listeners subscribed for invitations multi user chat events.
+ */
+ private Vector<AdHocChatRoomInvitationListener> invitationListeners
+ = new Vector<AdHocChatRoomInvitationListener>();
+
+ /**
+ * A list of listeners subscribed for events indicating rejection of a multi
+ * user chat invitation sent by us.
+ */
+ private Vector<AdHocChatRoomInvitationRejectionListener>
+ invitationRejectionListeners
+ = new Vector<AdHocChatRoomInvitationRejectionListener>();
+
+ /**
+ * A list of the ad-hoc rooms that are currently open and created by this
+ * account.
+ */
+ private Hashtable<Object, AdHocChatRoom> userCreatedAdHocChatRoomList
+ = new Hashtable<Object, AdHocChatRoom>();
+
+ /**
+ * Creates an<tt>OperationSetAdHocMultiUserChatMsnImpl</tt> by specifying
+ * the parent provider.
+ */
+ public OperationSetAdHocMultiUserChatMsnImpl(
+ ProtocolProviderServiceMsnImpl provider)
+ {
+ this.provider = provider;
+ this.provider.addRegistrationStateChangeListener(
+ new RegistrationStateListener());
+ }
+
+ /**
+ * Adds the given presence listener to existing presence listeners list.
+ *
+ * @param listener the listener to add
+ */
+ public void addPresenceListener(
+ LocalUserAdHocChatRoomPresenceListener listener)
+ {
+ synchronized(presenceListeners)
+ {
+ if(!presenceListeners.contains(listener))
+ presenceListeners.add(listener);
+ }
+ }
+
+ /**
+ * Adds a listener to invitation notifications.
+ *
+ * @param listener an invitation listener.
+ */
+ public void addInvitationListener(AdHocChatRoomInvitationListener listener)
+ {
+ synchronized (invitationListeners)
+ {
+ if (!invitationListeners.contains(listener))
+ invitationListeners.add(listener);
+ }
+ }
+
+ /**
+ * Removes<tt>listener</tt> from the list of invitation listeners
+ * registered to receive invitation events.
+ *
+ * @param listener the invitation listener to remove.
+ */
+ public void removeInvitationListener(
+ AdHocChatRoomInvitationListener listener)
+ {
+ synchronized (invitationListeners)
+ {
+ invitationListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Adds a listener to invitation notifications.
+ *
+ * @param listener an invitation listener.
+ */
+ public void addInvitationRejectionListener(
+ AdHocChatRoomInvitationRejectionListener listener)
+ {
+ synchronized (invitationRejectionListeners)
+ {
+ if (!invitationRejectionListeners.contains(listener))
+ invitationRejectionListeners.add(listener);
+ }
+ }
+
+ /**
+ * Removes<tt>listener</tt> from the list of invitation listeners
+ * registered to receive invitation events.
+ *
+ * @param listener the invitation listener to remove.
+ */
+ public void removeInvitationRejectionListener(
+ AdHocChatRoomInvitationRejectionListener listener)
+ {
+ synchronized (invitationRejectionListeners)
+ {
+ invitationRejectionListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Creates an<tt>AdHocChatRoom</tt> from the specified _adHocChatRoomName
+ * and the corresponding _switchboard.
+ *
+ * @param adHocChatRoomName the specific chat room name.
+ * @param switchboard The corresponding switchboard.
+ *
+ * @return AdHocChatRoomMsnImpl the chat room that we've just created.
+ */
+ private AdHocChatRoomMsnImpl createAdHocChatRoom(String adHocChatRoomName,
+ MsnSwitchboard switchboard)
+ {
+ synchronized (this.adHocChatRoomCache)
+ {
+ AdHocChatRoomMsnImpl adHocChatRoom = new AdHocChatRoomMsnImpl(
+ adHocChatRoomName, this.provider, switchboard);
+
+ this.adHocChatRoomCache.put(adHocChatRoom.getName(), adHocChatRoom);
+ adHocChatRoom.join();
+ return adHocChatRoom;
+ }
+
+ }
+
+ /**
+ * Creates a message by a given message text.
+ *
+ * @param messageText The message text.
+ * @return the newly created message.
+ */
+ public Message createMessage(String messageText)
+ {
+ return new MessageMsnImpl(messageText,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_ENCODING, null);
+ }
+
+ /**
+ * Creates an ad-hoc room with the named<tt>adHocRoomName</> and in
+ * including to the specified<tt>contacts</tt>. When the method
+ * returns the ad-hoc room the local user will not have joined it and thus
+ * will not receive messages on it until the<tt>AdHocChatRoom.join()</tt>
+ * method is called.
+ *
+ * NOTE: this method was done for the Yahoo! implementation. But since both
+ * Yahoo! and MSN are implementing the ad-hoc multi-user-chat operation set,
+ * we have to define this method here.
+ *
+ * @param adHocRoomName the name of the ad-hoc room
+ * @param contacts the list of contacts
+ *
+ * @throws OperationFailedException
+ * @throws OperationNotSupportedException
+ */
+ public AdHocChatRoom createAdHocChatRoom(String adHocRoomName,
+ List<Contact> contacts)
+ throws OperationFailedException, OperationNotSupportedException
+ {
+ AdHocChatRoom adHocRoom = null;
+ adHocRoom = findRoom(adHocRoomName);
+ if (adHocRoom == null)
+ {
+ // when the room hasn't been created, we create it.
+ adHocRoom = createLocalAdHocChatRoomInstance(adHocRoomName);
+
+ // we create an identifier object and create a new switchboard
+ // we need to track this object to identify this chatRoom
+ Object id = new Object();
+ this.provider.getMessenger().newSwitchboard(id);
+ // we put it into a hash table
+ this.userCreatedAdHocChatRoomList.put(id, adHocRoom);
+ }
+ adHocRoom.join();
+ return adHocRoom;
+ }
+
+ /**
+ * Creates an<tt>AdHocChatRoom</tt> whose name is _adHocRoomName with the
+ * properties contained in _adHocRoomProperties
+ *
+ * @param adHocRoomName the name of the ad-hoc room
+ * @param adHocRoomProperties the ad-hoc room's properties
+ *
+ * @throws OperationFailedException
+ * @throws OperationNotSupportedException
+ */
+ public AdHocChatRoom createAdHocChatRoom(String adHocRoomName,
+ Map<String, Object> adHocRoomProperties)
+ throws OperationFailedException, OperationNotSupportedException {
+ AdHocChatRoom adHocRoom = null;
+ adHocRoom = findRoom(adHocRoomName);
+ if (adHocRoom == null)
+ {
+ // when the room hasn't been created, we create it.
+ adHocRoom = createLocalAdHocChatRoomInstance(adHocRoomName);
+
+ // we create an identifier object and create a new switchboard
+ // we need to track this object to identify this chatRoom
+ Object id = new Object();
+ this.provider.getMessenger().newSwitchboard(id);
+ // we put it into a hash table
+ this.userCreatedAdHocChatRoomList.put(id, adHocRoom);
+ }
+ adHocRoom.join();
+ return adHocRoom;
+ }
+
+ /**
+ * Creates a<tt>ChatRoom</tt> from the specified chatRoomName.
+ *
+ * @param adHocChatRoomName the specific ad-hoc chat room name.
+ *
+ * @return AdHocChatRoom the ad-hoc chat room that we've just created.
+ */
+ private AdHocChatRoom createLocalAdHocChatRoomInstance(
+ String adHocChatRoomName)
+ {
+ synchronized (this.adHocChatRoomCache)
+ {
+ AdHocChatRoomMsnImpl adHocChatRoom =
+ new AdHocChatRoomMsnImpl(adHocChatRoomName, this.provider);
+
+ this.adHocChatRoomCache.put(adHocChatRoom.getName(), adHocChatRoom);
+ return adHocChatRoom;
+ }
+ }
+
+ /**
+ * Returns a reference to a chatRoom named<tt>_adHocRoomName</> or null.
+ * Note: Only called by user.
+ *
+ * @param adHocRoomName the name of the<tt>AdHocChatRoom</tt> that we're
+ * looking for.
+ * @return the<tt>AdHocChatRoom</tt> named<tt>_adHocRoomName</> or null
+ * if no such ad-hoc room exists on the server that this provider is
+ * currently connected to.
+ *
+ * @throws OperationFailedException if an error occurs while trying to
+ * discover the ad-hoc room on the server.
+ * @throws OperationNotSupportedException if the server does not support
+ * multi user chat
+ */
+ public AdHocChatRoom findRoom(String adHocRoomName)
+ throws OperationFailedException, OperationNotSupportedException
+ {
+ assertConnected();
+
+ AdHocChatRoom adHocRoom =
+ (AdHocChatRoom) this.adHocChatRoomCache.get(adHocRoomName);
+
+ return adHocRoom;
+ }
+
+ /**
+ * Returns a reference to an chatRoom named<tt>roomName</tt>. If the chat
+ * room doesn't exist, a new chat room is created for the given
+ * MsnSwitchboard.
+ *
+ * @param switchboard The specific switchboard for the chat room.
+ *
+ * @return the corresponding chat room
+ *
+ * @throws OperationFailedException if an error occurs while trying to
+ * discover the room on the server.
+ * @throws OperationNotSupportedException if the server does not support
+ * multi user chat
+ */
+
+ public AdHocChatRoom findRoom(MsnSwitchboard switchboard)
+ throws OperationFailedException,
+ OperationNotSupportedException
+ {
+ this.assertConnected();
+
+ AdHocChatRoomMsnImpl adHocRoom = (AdHocChatRoomMsnImpl)
+ this.adHocChatRoomCache.get(String.valueOf(switchboard.hashCode()));
+
+ if (adHocRoom == null)
+ {
+ String name = String.valueOf(switchboard.hashCode());
+ adHocRoom = this.createAdHocChatRoom(name, switchboard);
+ adHocRoom.setSwitchboard(switchboard);
+ adHocRoom.updateParticipantsList(switchboard);
+
+ this.adHocChatRoomCache.put(name, adHocRoom);
+
+ // fireInvitationEvent(room,
+ // switchboard.getMessenger().getOwner().getDisplayName(),
+ // "You have been invited to a group chat", null);
+ adHocRoom.join();
+ }
+
+ return adHocRoom;
+ }
+
+ /**
+ * Delivers a<tt>LocalUserAdHocChatRoomPresenceChangeEvent</> to all
+ * registered<tt>LocalUserAdHocChatRoomPresenceListener</tt>s.
+ *
+ * @param adHocChatRoom the<tt>AdHocChatRoom</tt> which has been joined,
+ * left, etc.
+ * @param eventType the type of this event; one of LOCAL_USER_JOINED,
+ * LOCAL_USER_LEFT, etc.
+ * @param reason the reason
+ */
+ public void fireLocalUserPresenceEvent( AdHocChatRoom adHocChatRoom,
+ String eventType,
+ String reason)
+ {
+ LocalUserAdHocChatRoomPresenceChangeEvent evt =
+ new LocalUserAdHocChatRoomPresenceChangeEvent(
+ this,
+ adHocChatRoom,
+ eventType,
+ reason);
+
+ Iterator<LocalUserAdHocChatRoomPresenceListener> listeners = null;
+ synchronized(this.presenceListeners)
+ {
+ listeners = new ArrayList<LocalUserAdHocChatRoomPresenceListener>
+ (this.presenceListeners).iterator();
+ }
+
+ while (listeners.hasNext())
+ {
+ LocalUserAdHocChatRoomPresenceListener listener = listeners.next();
+
+ listener.localUserAdHocPresenceChanged(evt);
+ }
+ }
+
+ /**
+ * Checks if an incoming message is a multi user chat message. This is done
+ * by the switchboard, if it is not created by the user, its an active file
+ * transfer switchboard or the user count is too low then this method return
+ * false.
+ *
+ * @param switchboard The corresponding MSNswitchboard.
+ * @return true if it is a group chat message or false in the other case.
+ */
+ public boolean isGroupChatMessage(MsnSwitchboard switchboard)
+ {
+ // //fileTransfer??
+ // if (switchboard.getActiveFileTransfers() != null)
+ // return false;
+
+ Object attachment = switchboard.getAttachment();
+ if (attachment == null)
+ { // the user did not created the chat room by him/her self,
+ // the only way to figure out if this is a group chat message
+ // is to check the user count
+ return (switchboard.getAllContacts().length> 1);
+
+ }
+
+ return this.userCreatedAdHocChatRoomList.containsKey(attachment);
+ }
+
+ public boolean isMultiChatSupportedByContact(Contact contact)
+ {
+ return false;
+ }
+
+ /**
+ * Removes the given listener from presence listeners' list.
+ *
+ * @param listener the listener to remove
+ */
+ public void removePresenceListener(
+ LocalUserAdHocChatRoomPresenceListener listener)
+ {
+ synchronized (this.presenceListeners)
+ {
+ if(this.presenceListeners.contains(listener))
+ {
+ this.presenceListeners.remove(listener);
+ }
+ }
+ }
+
+ /**
+ * Makes sure that we are properly connected.
+ *
+ * @throws OperationFailedException if the provider is not connected.
+ * @throws OperationNotSupportedException if the service is not supported by
+ * the server.
+ */
+ private void assertConnected()
+ throws OperationFailedException,
+ OperationNotSupportedException
+ {
+ if (this.provider == null)
+ throw new IllegalStateException(
+ "The provider must be non-null and signed on the "
+ + "service before being able to communicate.");
+ if (!this.provider.isRegistered())
+ throw new IllegalStateException(
+ "The provider must be signed on the service before "
+ + "being able to communicate.");
+ }
+
+ /**
+ * Our listener that will tell us when we're registered to msn.
+ */
+ private class RegistrationStateListener
+ implements RegistrationStateChangeListener
+ {
+ /**
+ * The method is called by a ProtocolProvider implementation whenever a
+ * change in the registration state of the corresponding provider had
+ * occurred.
+ *
+ * @param evt ProviderStatusChangeEvent the event describing the status
+ * change.
+ */
+ public void registrationStateChanged(RegistrationStateChangeEvent evt)
+ {
+ if (evt.getNewState() == RegistrationState.REGISTERED)
+ {
+ provider.getMessenger().addSwitchboardListener(
+ new MsnSwitchboardListener());
+ provider.getMessenger().addMessageListener(
+ new MsnMessageListener());
+ }
+ }
+
+ }
+
+ /**
+ * Our group chat message listener, it extends the MsnMessageAdapter from
+ * the the jml library.
+ */
+ private class MsnMessageListener
+ extends MsnMessageAdapter
+ implements MsnEmailListener
+ {
+ public void instantMessageReceived( MsnSwitchboard switchboard,
+ MsnInstantMessage message,
+ MsnContact contact)
+ {
+ if (!isGroupChatMessage(switchboard))
+ return;
+
+ Message newMessage = createMessage(message.getContent());
+
+ logger.debug("Group chat message received.");
+ Object attachment = switchboard.getAttachment();
+ try
+ {
+ AdHocChatRoomMsnImpl chatRoom = null;
+
+ if (attachment == null) // chat room session NOT created by
+ // yourself
+ {
+ chatRoom = (AdHocChatRoomMsnImpl) findRoom(switchboard);
+ }
+
+ // user created chat room session?
+ if (attachment != null
+&& userCreatedAdHocChatRoomList.containsKey(attachment))
+ { chatRoom =
+ (AdHocChatRoomMsnImpl) userCreatedAdHocChatRoomList
+ .get(attachment);
+ }
+
+ if (chatRoom == null)
+ {
+ return;
+ }
+
+ Contact participant =
+ chatRoom.getAdHocChatRoomParticipant(contact.getId());
+
+ AdHocChatRoomMessageReceivedEvent msgReceivedEvent =
+ new AdHocChatRoomMessageReceivedEvent(
+ chatRoom,
+ participant,
+ System.currentTimeMillis(),
+ newMessage,
+ AdHocChatRoomMessageReceivedEvent
+ .CONVERSATION_MESSAGE_RECEIVED);
+
+ chatRoom.fireMessageEvent(msgReceivedEvent);
+
+ }
+ catch (OperationFailedException e)
+ {
+ logger.error("Failed to find room with name: ", e);
+ }
+ catch (OperationNotSupportedException e)
+ {
+ logger.error("Failed to find room with name: ", e);
+ }
+
+ }
+
+ public void initialEmailNotificationReceived(
+ MsnSwitchboard switchboard, MsnEmailInitMessage message,
+ MsnContact contact)
+ {
+ }
+
+ public void initialEmailDataReceived(MsnSwitchboard switchboard,
+ MsnEmailInitEmailData message, MsnContact contact)
+ {
+ }
+
+ public void newEmailNotificationReceived(MsnSwitchboard switchboard,
+ MsnEmailNotifyMessage message, MsnContact contact)
+ {
+
+ }
+
+ public void activityEmailNotificationReceived(
+ MsnSwitchboard switchboard, MsnEmailActivityMessage message,
+ MsnContact contact)
+ {
+ }
+ }
+
+ /**
+ * The Switchboard Listener, listens to all four switchboard events:
+ * Switchboard started/closed and User joins/left.
+ *
+ */
+ private class MsnSwitchboardListener
+ extends MsnSwitchboardAdapter
+ {
+ public void contactJoinSwitchboard(MsnSwitchboard switchboard,
+ MsnContact contact)
+ {
+ if (!isGroupChatMessage(switchboard))
+ return;
+
+ Object attachment = switchboard.getAttachment();
+ try
+ {
+ AdHocChatRoomMsnImpl chatRoom = null;
+ if (attachment == null) // chat room session NOT created by
+ // yourself
+ chatRoom = (AdHocChatRoomMsnImpl) findRoom(switchboard);
+
+ // user created chat room session?
+ if (attachment != null
+&& userCreatedAdHocChatRoomList.containsKey(attachment))
+ chatRoom =
+ (AdHocChatRoomMsnImpl) userCreatedAdHocChatRoomList
+ .get(attachment);
+
+ if (chatRoom == null)
+ return;
+
+ Contact msnContact = new ContactMsnImpl(
+ contact, new ServerStoredContactListMsnImpl(
+ new OperationSetPersistentPresenceMsnImpl(provider),
+ provider), true, true);
+ chatRoom.addAdHocChatRoomParticipant( contact.getId(),
+ msnContact);
+ }
+ catch (Exception e)
+ {
+ logger.error("Failed to join switchboard.", e);
+ }
+
+ }
+
+ public void contactLeaveSwitchboard(MsnSwitchboard switchboard,
+ MsnContact contact)
+ {
+ logger
+ .debug(contact.getDisplayName() + " has left the Switchboard");
+
+ Object attachment = switchboard.getAttachment();
+
+ try
+ {
+ AdHocChatRoomMsnImpl adHocChatRoom = null;
+ if (attachment == null)// chat room session NOT created by
+ // yourself
+ adHocChatRoom = (AdHocChatRoomMsnImpl)findRoom(switchboard);
+
+ // user created chat room session?
+ if (attachment != null
+&& userCreatedAdHocChatRoomList.containsKey(attachment))
+ adHocChatRoom =
+ (AdHocChatRoomMsnImpl) userCreatedAdHocChatRoomList
+ .get(attachment);
+
+ if (adHocChatRoom == null)
+ return;
+
+ String participantId = contact.getId();
+
+ Contact participant =
+ adHocChatRoom.getAdHocChatRoomParticipant(participantId);
+
+ if (participant != null)
+ {
+ adHocChatRoom.removeParticipant(participantId);
+ }
+ }
+ catch (OperationFailedException e)
+ {
+ logger.debug( "Could not find a chat room corresponding" +
+ "to the given switchboard.", e);
+ }
+ catch (OperationNotSupportedException e)
+ {
+ logger.debug( "Could not find a chat room corresponding" +
+ "to the given switchboard.", e);
+ }
+ }
+
+ public void switchboardClosed(MsnSwitchboard switchboard)
+ {
+ Object attachment = switchboard.getAttachment();
+ try
+ {
+ AdHocChatRoomMsnImpl adHocChatRoom = null;
+ if (attachment == null)// chat room session NOT created by
+ // yourself
+ adHocChatRoom = (AdHocChatRoomMsnImpl) findRoom(switchboard);
+ // user created chat room session?
+ if (attachment != null
+&& userCreatedAdHocChatRoomList.containsKey(attachment))
+ adHocChatRoom =
+ (AdHocChatRoomMsnImpl) userCreatedAdHocChatRoomList
+ .get(attachment);
+
+ if (adHocChatRoom == null)
+ return;
+
+ adHocChatRoom.setSwitchboard(null);
+
+ adHocChatRoom.leave();
+ fireLocalUserPresenceEvent(adHocChatRoom,
+ LocalUserChatRoomPresenceChangeEvent.LOCAL_USER_DROPPED ,
+ "Switchboard closed.");
+ }
+ catch (Exception e)
+ {
+ }
+ }
+
+ public void switchboardStarted(MsnSwitchboard switchboard)
+ {
+
+ Object switchboardID = switchboard.getAttachment();
+ AdHocChatRoomMsnImpl adHocChatRoom = null;
+ if (switchboardID != null
+&& userCreatedAdHocChatRoomList.containsKey(switchboardID))
+ {
+ adHocChatRoom =
+ (AdHocChatRoomMsnImpl) userCreatedAdHocChatRoomList
+ .get(switchboardID);
+
+ adHocChatRoom.setSwitchboard(switchboard);
+ adHocChatRoom.updateParticipantsList(switchboard);
+ adHocChatRoom.join();
+ }
+ else
+ {
+ logger.setLevelDebug();
+ logger.debug("Could not join the Ad-hoc chat room.");
+ }
+ }
+ }
+
+ /**
+ * Supposed to reject an invitation for MUC.
+ * Note: Not supported inside the MSN.
+ */
+ public void rejectInvitation(AdHocChatRoomInvitation invitation,
+ String rejectReason)
+ {
+ // there is no way to block invitations, because there arn't any
+ // invitations.
+ // the only way would be to block the Friend and that shouldn't be done
+ // here.
+ return;
+ }
+}

Modified: trunk/src/net/java/sip/communicator/impl/protocol/msn/OperationSetBasicInstantMessagingMsnImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/msn/OperationSetBasicInstantMessagingMsnImpl.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/protocol/msn/OperationSetBasicInstantMessagingMsnImpl.java&p2=trunk/src/net/java/sip/communicator/impl/protocol/msn/OperationSetBasicInstantMessagingMsnImpl.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/protocol/msn/OperationSetBasicInstantMessagingMsnImpl.java (original)
+++ trunk/src/net/java/sip/communicator/impl/protocol/msn/OperationSetBasicInstantMessagingMsnImpl.java 2009-09-14 15:51:47+0000
@@ -25,8 +25,8 @@
public class OperationSetBasicInstantMessagingMsnImpl
     extends AbstractOperationSetBasicInstantMessaging
{
- private static final Logger logger =
- Logger.getLogger(OperationSetBasicInstantMessagingMsnImpl.class);
+ private static final Logger logger
+ = Logger.getLogger(OperationSetBasicInstantMessagingMsnImpl.class);

     /**
      * The provider that created us.
@@ -39,7 +39,7 @@
      */
     private OperationSetPersistentPresenceMsnImpl opSetPersPresence = null;

- private OperationSetMultiUserChatMsnImpl opSetMuc = null;
+ private OperationSetAdHocMultiUserChatMsnImpl opSetMuc = null;
     /**
      * Creates an instance of this operation set.
      * @param provider a ref to the<tt>ProtocolProviderServiceImpl</tt>
@@ -50,8 +50,8 @@
         ProtocolProviderServiceMsnImpl provider)
     {
         this.msnProvider = provider;
- opSetMuc = (OperationSetMultiUserChatMsnImpl) msnProvider
- .getOperationSet(OperationSetMultiUserChat.class);
+ opSetMuc = (OperationSetAdHocMultiUserChatMsnImpl) msnProvider
+ .getOperationSet(OperationSetAdHocMultiUserChat.class);
         provider.addRegistrationStateChangeListener(new RegistrationStateListener());
     }

Removed: trunk/src/net/java/sip/communicator/impl/protocol/msn/OperationSetMultiUserChatMsnImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/msn/OperationSetMultiUserChatMsnImpl.java?view=auto&rev=5963

Modified: trunk/src/net/java/sip/communicator/impl/protocol/msn/ProtocolProviderServiceMsnImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/msn/ProtocolProviderServiceMsnImpl.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/protocol/msn/ProtocolProviderServiceMsnImpl.java&p2=trunk/src/net/java/sip/communicator/impl/protocol/msn/ProtocolProviderServiceMsnImpl.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/protocol/msn/ProtocolProviderServiceMsnImpl.java (original)
+++ trunk/src/net/java/sip/communicator/impl/protocol/msn/ProtocolProviderServiceMsnImpl.java 2009-09-14 15:51:47+0000
@@ -261,12 +261,13 @@
         {
             this.accountID = accountID;

- supportedOperationSets.put(OperationSetInstantMessageTransform.class.getName(),
+ supportedOperationSets.put(
+ OperationSetInstantMessageTransform.class.getName(),
                 new OperationSetInstantMessageTransformImpl());
-
+
             //initialize the presence operationset
             persistentPresence = new OperationSetPersistentPresenceMsnImpl(this);
-
+
             supportedOperationSets.put(
                 OperationSetPersistentPresence.class.getName(),
                 persistentPresence);
@@ -275,16 +276,15 @@
             supportedOperationSets.put( OperationSetPresence.class.getName(),
                                         persistentPresence);

- // initialize the multi user chat operation set
- OperationSetMultiUserChat multiUserChat = new OperationSetMultiUserChatMsnImpl(
- this);
+ OperationSetAdHocMultiUserChat adHocMultiUserChat =
+ new OperationSetAdHocMultiUserChatMsnImpl(this);

- supportedOperationSets.put(OperationSetMultiUserChat.class
- .getName(), multiUserChat);
+ supportedOperationSets.put(OperationSetAdHocMultiUserChat.class
+ .getName(), adHocMultiUserChat);

            // initialize the IM operation set
- OperationSetBasicInstantMessagingMsnImpl basicInstantMessaging = new OperationSetBasicInstantMessagingMsnImpl(
- this);
+ OperationSetBasicInstantMessagingMsnImpl basicInstantMessaging
+ = new OperationSetBasicInstantMessagingMsnImpl(this);

            supportedOperationSets.put(OperationSetBasicInstantMessaging.class
                    .getName(), basicInstantMessaging);

Modified: trunk/src/net/java/sip/communicator/impl/protocol/sip/SipLogger.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/sip/SipLogger.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/protocol/sip/SipLogger.java&p2=trunk/src/net/java/sip/communicator/impl/protocol/sip/SipLogger.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/protocol/sip/SipLogger.java (original)
+++ trunk/src/net/java/sip/communicator/impl/protocol/sip/SipLogger.java 2009-09-14 15:51:47+0000
@@ -33,31 +33,31 @@
      * Implementation of StackLogger
      */

- /**
+ /**
      * log a stack trace. This helps to look at the stack frame.
      */
- public void logStackTrace()
+ public void logStackTrace()
     {
         logger.trace("JAIN-SIP stack trace", new Throwable());
     }

- public void logStackTrace(int traceLevel)
+ public void logStackTrace(int traceLevel)
     {
         // FIXE ME: don't ignore the level?
         logger.trace("JAIN-SIP stack trace", new Throwable());
     }

- /**
+ /**
      * Get the line count in the log stream.
      *
      * @return line count
      */
- public int getLineCount()
+ public int getLineCount()
     {
         return 0;
     }

- /**
+ /**
      * Log an exception.
      *
      * @param ex

Added: trunk/src/net/java/sip/communicator/impl/protocol/yahoo/AdHocChatRoomInvitationYahooImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/yahoo/AdHocChatRoomInvitationYahooImpl.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/protocol/yahoo/AdHocChatRoomInvitationYahooImpl.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,79 @@
+/*
+ * 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.yahoo;
+
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * The Yahoo implementation of the<tt>AdHocChatRoomInvitation</> interface.
+ *
+ * @author Rupert Burchardi
+ * @author Valentin Martinet
+ */
+public class AdHocChatRoomInvitationYahooImpl
+ implements AdHocChatRoomInvitation
+{
+ /**
+ * Corresponding chat room instance.
+ */
+ private AdHocChatRoom chatRoom;
+ /**
+ * The name of the inviter
+ */
+ private String inviter;
+
+ /**
+ * The invitation reason.
+ */
+ private String reason;
+
+ /**
+ * Creates an instance of the<tt>ChatRoomInvitationMsnImpl</> by
+ * specifying the targetChatRoom, the inviter, the reason.
+ *
+ * @param targetChatRoom The<tt>AdHocChatRoom</tt> for which the invitation
+ * is
+ * @param inviter The<tt>Contact</tt>, which sent the invitation
+ * @param reason The Reason for the invitation
+ */
+ public AdHocChatRoomInvitationYahooImpl( AdHocChatRoom targetChatRoom,
+ String inviter,
+ String reason)
+ {
+ this.chatRoom = targetChatRoom;
+ this.inviter = inviter;
+ this.reason = reason;
+ }
+
+ /**
+ * Returns the corresponding chat room.
+ * @return The ad-hoc chat room
+ */
+ public AdHocChatRoom getTargetAdHocChatRoom()
+ {
+ return chatRoom;
+ }
+
+ /**
+ * Returns the corresponding inviter.
+ * @return The name of the inviter
+ */
+ public String getInviter()
+ {
+ return inviter;
+ }
+
+ /**
+ * Returns the invitation reason.
+ * @return the invitation reason
+ */
+ public String getReason()
+ {
+ return reason;
+ }
+}

Added: trunk/src/net/java/sip/communicator/impl/protocol/yahoo/AdHocChatRoomYahooImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/yahoo/AdHocChatRoomYahooImpl.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/protocol/yahoo/AdHocChatRoomYahooImpl.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,596 @@
+/*
+ * 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.yahoo;
+
+import java.io.*;
+import java.util.*;
+
+import ymsg.network.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.event.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * Represents a Yahoo ad-hoc chat room, where multiple chat users could
+ * communicate in a many-to-many fashion.
+ *
+ * @author Rupert Burchardi
+ * @author Valentin Martinet
+ */
+public class AdHocChatRoomYahooImpl
+ implements AdHocChatRoom
+{
+ private static final Logger logger = Logger
+ .getLogger(AdHocChatRoomYahooImpl.class);
+
+ /**
+ * Listeners that will be notified of changes in member status in the room
+ * such as member joined, left or being kicked or dropped.
+ */
+ private Vector<AdHocChatRoomParticipantPresenceListener> memberListeners
+ = new Vector<AdHocChatRoomParticipantPresenceListener>();
+
+ /**
+ * Listeners that will be notified every time a new message is received on
+ * this ad-hoc chat room.
+ */
+ private Vector<AdHocChatRoomMessageListener> messageListeners
+ = new Vector<AdHocChatRoomMessageListener>();
+
+ /**
+ * The protocol provider that created us
+ */
+ private ProtocolProviderServiceYahooImpl provider = null;
+
+ /**
+ * The operation set that created us.
+ */
+ private OperationSetAdHocMultiUserChatYahooImpl opSetMuc = null;
+
+ /**
+ * The list of participants of this chat room.
+ */
+ private Hashtable<String, Contact> participants
+ = new Hashtable<String, Contact>();
+
+ /**
+ * The nickname of this chat room local user participant.
+ */
+ private String nickname;
+
+ /**
+ * The yahoo conference model of this ad-hoc chat room, its the
+ * representation of an ad-hoc chat room in the lib for this protocol.
+ */
+ private YahooConference yahooConference = null;
+
+ /**
+ * Creates an instance of a chat room that has been.
+ *
+ * @param multiUserChat
+ * MultiUserChat
+ * @param provider
+ * a reference to the currently valid jabber protocol provider.
+ */
+ public AdHocChatRoomYahooImpl( YahooConference multiUserChat,
+ ProtocolProviderServiceYahooImpl provider)
+ {
+ this.yahooConference = multiUserChat;
+ this.provider = provider;
+ this.opSetMuc = (OperationSetAdHocMultiUserChatYahooImpl) provider
+ .getOperationSet(OperationSetAdHocMultiUserChat.class);
+ }
+
+ /**
+ * Registers<tt>listener</tt> so that it would receive events every time a
+ * new message is received on this chat room.
+ *
+ * @param listener A<tt>MessageListener</tt> that would be notified every
+ * time a new message is received on this chat room.
+ */
+ public void addMessageListener(AdHocChatRoomMessageListener listener)
+ {
+ synchronized (messageListeners)
+ {
+ if (!messageListeners.contains(listener))
+ messageListeners.add(listener);
+ }
+ }
+
+ /**
+ * Removes<tt>listener</tt> so that it won't receive any further message
+ * events from this room.
+ *
+ * @param listener The<tt>MessageListener</tt> to remove from this room
+ */
+ public void removeMessageListener(AdHocChatRoomMessageListener listener)
+ {
+ synchronized (messageListeners)
+ {
+ messageListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Adds a listener that will be notified of changes in our status in the
+ * room.
+ *
+ * @param listener A participant status listener.
+ */
+ public void addParticipantPresenceListener(
+ AdHocChatRoomParticipantPresenceListener listener)
+ {
+ synchronized (memberListeners)
+ {
+ if (!memberListeners.contains(listener))
+ memberListeners.add(listener);
+ }
+ }
+
+ /**
+ * Removes a listener that was being notified of changes in the status of
+ * other chat room participants.
+ *
+ * @param listener A participant status listener.
+ */
+ public void removeParticipantPresenceListener(
+ AdHocChatRoomParticipantPresenceListener listener)
+ {
+ synchronized (memberListeners)
+ {
+ memberListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Create a Message instance for sending arbitrary MIME-encoding content.
+ *
+ * @param content
+ * content value
+ * @param contentType
+ * the MIME-type for<tt>content</tt>
+ * @param contentEncoding
+ * encoding used for<tt>content</tt>
+ * @param subject
+ * a<tt>String</tt> subject or<tt>null</tt> for now subject.
+ * @return the newly created message.
+ */
+ public Message createMessage(byte[] content, String contentType,
+ String contentEncoding, String subject)
+ {
+ return new MessageYahooImpl(new String(content), contentType,
+ contentEncoding, subject);
+ }
+
+ /**
+ * Create a Message instance for sending a simple text messages with default
+ * (text/plain) content type and encoding.
+ *
+ * @param messageText
+ * the string content of the message.
+ * @return Message the newly created message
+ */
+ public Message createMessage(String messageText)
+ {
+ Message msg = new MessageYahooImpl(messageText,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_ENCODING, null);
+ return msg;
+ }
+
+ /**
+ * Returns a<tt>List</tt> of<tt>Contact</tt>s corresponding to all members
+ * currently participating in this room.
+ *
+ * @return a<tt>List</tt> of<tt>Contact</tt> corresponding to all room
+ * members.
+ */
+ public List<Contact> getParticipants()
+ {
+ return new LinkedList<Contact>(participants.values());
+ }
+
+ /**
+ * Updates the member list of the chat room.
+ *
+ */
+ public void updateParticipantsList()
+ {
+ Iterator<?> it = yahooConference.getMembers().iterator();
+
+ while (it.hasNext())
+ {
+ YahooUser user = (YahooUser) it.next();
+ Contact contact;
+ OperationSetPersistentPresenceYahooImpl presenceOpSet
+ = (OperationSetPersistentPresenceYahooImpl) this
+ .getParentProvider().getOperationSet(
+ OperationSetPersistentPresence.class);
+
+ contact = presenceOpSet.findContactByID(user.getId());
+
+ if(!participants.containsKey(contact.getDisplayName()))
+ {
+ participants.put(contact.getDisplayName(), contact);
+ }
+ }
+ }
+
+ /**
+ * Returns the identifier of this<tt>AdHocChatRoom</tt>.
+ *
+ * @return a<tt>String</tt> containing the identifier of this
+ *<tt>AdHocChatRoom</tt>.
+ */
+ public String getIdentifier()
+ {
+ return yahooConference.getName();
+ }
+
+ /**
+ * Returns the number of participants that are currently in this ad-hoc chat
+ * room.
+ *
+ * @return the number of<tt>Contact</tt>s, currently participating in
+ * this ad-hoc room.
+ */
+ public int getParticipantsCount()
+ {
+ return yahooConference.getMembers().size();
+ }
+
+ /**
+ * Returns the name of this<tt>AdHocChatRoom</tt>.
+ *
+ * @return a<tt>String</tt> containing the name of this
+ *<tt>AdHocChatRoom</tt>.
+ */
+ public String getName()
+ {
+ return yahooConference.getName();
+ }
+
+ /**
+ * Returns the protocol provider service that created us.
+ *
+ * @return the protocol provider service that created us.
+ */
+ public ProtocolProviderService getParentProvider()
+ {
+ return provider;
+ }
+
+ /**
+ * Returns the local user's nickname in the context of this chat room or
+ *<tt>null</tt> if not currently joined.
+ *
+ * @return the nickname currently being used by the local user in the
+ * context of the local ad-hoc chat room.
+ */
+
+ public String getUserNickname()
+ {
+ if(nickname == null)
+ nickname = provider.getYahooSession().getLoginIdentity().getId();
+
+ return nickname;
+ }
+
+ /**
+ * Invites another user to this room. If we're not joined nothing will
+ * happen.
+ *
+ * @param userAddress The identifier of the contact (email address or yahoo
+ * id)
+ * @param reason The invite reason, which is send to the invitee.
+ */
+ public void invite(String userAddress, String reason)
+ {
+ try
+ {
+ // the contact is invited unless if he wasn't invited during room's
+ // creation:
+ if(!opSetMuc.getAlreadyInvitedContactAddresses().contains(
+ userAddress))
+ {
+ provider.getYahooSession().extendConference(yahooConference,
+ userAddress, reason);
+ }
+ }
+ catch (IOException ioe)
+ {
+ logger.debug("Failed to invite the user: " + userAddress
+ + " Error: " + ioe);
+ }
+ }
+
+ /**
+ * Indicates whether or not this chat room is corresponding to a server
+ * channel. Note: Returns always<code>false</code>.
+ *
+ * @return Always<code>false</code> since system chat room can't be joined
+ * with current yahoo library.
+ */
+ public boolean isSystem()
+ {
+ return false;
+ }
+
+ /**
+ * Joins this chat room with the nickname of the local user so that the user
+ * would start receiving events and messages for it.
+ *
+ * @throws OperationFailedException with the corresponding code if an error
+ * occurs while joining the room.
+ */
+ public void join() throws OperationFailedException
+ {
+ this.nickname = provider.getAccountID().getUserID();
+ try
+ {
+ provider.getYahooSession().acceptConferenceInvite(yahooConference);
+
+ // We don't specify a reason.
+ opSetMuc.fireLocalUserPresenceEvent(this,
+ LocalUserAdHocChatRoomPresenceChangeEvent.LOCAL_USER_JOINED,
+ null);
+ }
+ catch (Exception e)
+ {
+ logger.setLevelDebug();
+ logger.debug("Couldn't join the chat room: "
+ + yahooConference.getName() + e);
+ }
+ }
+
+ /**
+ * Leave this chat room. Once this method is called, the user won't be
+ * listed as a member of the chat room any more and no further chat events
+ * will be delivered. Depending on the underlying protocol and
+ * implementation leave() might cause the room to be destroyed if it has
+ * been created by the local user.
+ */
+ public void leave()
+ {
+ try
+ {
+ provider.getYahooSession().leaveConference(yahooConference);
+
+ Iterator< Map.Entry<String, Contact>> membersSet
+ = participants.entrySet().iterator();
+
+ while (membersSet.hasNext())
+ {
+ Map.Entry<String, Contact> memberEntry
+ = (Map.Entry<String, Contact>) membersSet.next();
+
+ Contact participant = memberEntry.getValue();
+
+ fireParticipantPresenceEvent(participant,
+ AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_LEFT,
+ "Local user has left the chat room.");
+ }
+ }
+ catch (IOException ioe)
+ {
+ logger.debug("Failed to leave the chat room: "
+ + yahooConference.getName() + " Error: " + ioe);
+ }
+
+ participants.clear();
+ }
+
+ /**
+ * Sends the<tt>message</tt> to the destination indicated by the
+ *<tt>to</tt> contact.
+ *
+ * @param message The<tt>Message</tt> to send.
+ * @throws OperationFailedException if the underlying stack is not
+ * registered or initialized or if the chat room is not joined.
+ */
+ public void sendMessage(Message message) throws OperationFailedException
+ {
+ assertConnected();
+
+ try
+ {
+ provider.getYahooSession().sendConferenceMessage(yahooConference,
+ message.getContent());
+
+ AdHocChatRoomMessageDeliveredEvent msgDeliveredEvt
+ = new AdHocChatRoomMessageDeliveredEvent(
+ this,
+ System.currentTimeMillis(),
+ message,
+ ChatRoomMessageDeliveredEvent.CONVERSATION_MESSAGE_DELIVERED);
+
+ fireMessageEvent(msgDeliveredEvt);
+ }
+ catch (Exception e)
+ {
+ logger.debug("Failed to send a conference message.");
+ }
+ }
+
+ /**
+ * Notifies all interested listeners that a
+ *<tt>AdHocChatRoomMessageDeliveredEvent</tt>,
+ *<tt>AdHocChatRoomMessageReceivedEvent</tt> or a
+ *<tt>AdHocChatRoomMessageDeliveryFailedEvent</tt> has been fired.
+ * @param evt The specific event
+ */
+ public void fireMessageEvent(EventObject evt)
+ {
+ Iterator<AdHocChatRoomMessageListener> listeners = null;
+ synchronized (messageListeners)
+ {
+ listeners = new ArrayList<AdHocChatRoomMessageListener>(
+ messageListeners).iterator();
+ }
+
+ while (listeners.hasNext())
+ {
+ AdHocChatRoomMessageListener listener
+ = (AdHocChatRoomMessageListener) listeners.next();
+
+ if (evt instanceof AdHocChatRoomMessageDeliveredEvent)
+ {
+ listener.messageDelivered(
+ (AdHocChatRoomMessageDeliveredEvent) evt);
+ }
+ else if (evt instanceof AdHocChatRoomMessageReceivedEvent)
+ {
+ listener.messageReceived(
+ (AdHocChatRoomMessageReceivedEvent) evt);
+ }
+ else if (evt instanceof AdHocChatRoomMessageDeliveryFailedEvent)
+ {
+ listener.messageDeliveryFailed(
+ (AdHocChatRoomMessageDeliveryFailedEvent) evt);
+ }
+ }
+ }
+
+ /**
+ * Creates the corresponding AdHocChatRoomParticipantPresenceChangeEvent and
+ * notifies all<tt>AdHocChatRoomParticipantPresenceListener</>s that a
+ * Contact has joined or left this<tt>AdHocChatRoom</tt>.
+ *
+ * @param participant the<tt>Contact</tt> that this
+ * @param eventID the identifier of the event
+ * @param eventReason the reason of the event
+ */
+ public void fireParticipantPresenceEvent(Contact participant, String eventID,
+ String eventReason)
+ {
+ AdHocChatRoomParticipantPresenceChangeEvent evt
+ = new AdHocChatRoomParticipantPresenceChangeEvent(this,
+ participant,
+ eventID,
+ eventReason);
+
+ logger.trace("Will dispatch the following ChatRoom event: " + evt);
+
+ Iterator<AdHocChatRoomParticipantPresenceListener> listeners = null;
+ synchronized (memberListeners)
+ {
+ listeners = new ArrayList<AdHocChatRoomParticipantPresenceListener>
+ (memberListeners).iterator();
+ }
+
+ while (listeners.hasNext())
+ {
+ AdHocChatRoomParticipantPresenceListener listener
+ = (AdHocChatRoomParticipantPresenceListener) listeners.next();
+
+ listener.participantPresenceChanged(evt);
+ }
+ }
+
+ /**
+ * Finds the participant of this ad-hoc chat room corresponding to the
+ * given address.
+ *
+ * @param address the address to search for.
+ * @return the participant of this chat room corresponding to the given
+ * nick name.
+ */
+ public Contact findParticipantForAddress(String address)
+ {
+ Iterator<Contact> participantsIter
+ = this.participants.values().iterator();
+
+ while (participantsIter.hasNext())
+ {
+ Contact contact = participantsIter.next();
+
+ if (contact.getAddress().equals(address))
+ {
+ return contact;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Removes the specified ad-hoc chat room participant from the participants
+ * list of this ad-hoc chat room.
+ * @param contact The member, who should be removed from the ad-hoc chat room
+ * participants list.
+ */
+ public void removeChatRoomParticipant(Contact participant)
+ {
+ if(participant == null)
+ return;
+
+ participants.remove(participant.getDisplayName());
+
+ fireParticipantPresenceEvent(participant,
+ AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_LEFT, null);
+ }
+
+ /**
+ * Adds a participant to the ad-hoc chat room participant list.
+ * @param participant The participant, who should be added to the ad-hoc
+ * chat room participant list.
+ */
+ public void addChatRoomParticipant(Contact participant)
+ {
+ if (participant == null)
+ return;
+
+ if (!participants.containsKey(participant.getDisplayName()))
+ {
+ participants.put(participant.getDisplayName(), participant);
+
+ fireParticipantPresenceEvent(participant,
+ AdHocChatRoomParticipantPresenceChangeEvent.CONTACT_JOINED,
+ null);
+ }
+ }
+
+ /**
+ * Returns the yahoo conference model of this chat room.
+ * @return The yahoo conference.
+ */
+ public YahooConference getYahooConference()
+ {
+ return yahooConference;
+ }
+
+ /**
+ * Utility method throwing an exception if the stack is not properly
+ * initialized.
+ * @throws java.lang.IllegalStateException if the underlying stack is
+ * not registered and initialized.
+ */
+ private void assertConnected() throws IllegalStateException
+ {
+ if (provider == null)
+ throw new IllegalStateException(
+ "The provider must be non-null and signed on the "
+ +"service before being able to communicate.");
+ if (!provider.isRegistered())
+ throw new IllegalStateException(
+ "The provider must be signed on the service before "
+ +"being able to communicate.");
+ }
+
+ /**
+ * Determines whether this chat room should be stored in the configuration
+ * file or not. If the chat room is persistent it still will be shown after a
+ * restart in the chat room list. A non-persistent chat room will be only in
+ * the chat room list until the the program is running.
+ *
+ * @return true if this chat room is persistent, false otherwise
+ */
+ public boolean isPersistent()
+ {
+ return false;
+ }
+}

Removed: trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ChatRoomInvitationYahooImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ChatRoomInvitationYahooImpl.java?view=auto&rev=5963

Removed: trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ChatRoomMemberYahooImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ChatRoomMemberYahooImpl.java?view=auto&rev=5963

Removed: trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ChatRoomYahooImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ChatRoomYahooImpl.java?view=auto&rev=5963

Added: trunk/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetAdHocMultiUserChatYahooImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetAdHocMultiUserChatYahooImpl.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetAdHocMultiUserChatYahooImpl.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,776 @@
+package net.java.sip.communicator.impl.protocol.yahoo;
+
+import java.io.*;
+import java.util.*;
+
+import ymsg.network.*;
+import ymsg.network.event.*;
+import ymsg.support.MessageDecoder;
+
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.event.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * A Yahoo implementation of the ad-hoc multi user chat operation set.
+ *
+ * @author Rupert Burchardi
+ * @author Valentin Martinet
+ */
+public class OperationSetAdHocMultiUserChatYahooImpl
+ implements OperationSetAdHocMultiUserChat
+{
+ private static final Logger logger = Logger
+ .getLogger(OperationSetAdHocMultiUserChatYahooImpl.class);
+ /**
+ * A list of listeners subscribed for invitations multi user chat events.
+ */
+ private Vector<AdHocChatRoomInvitationListener> invitationListeners
+ = new Vector<AdHocChatRoomInvitationListener>();
+
+ /**
+ * A list of listeners subscribed for events indicating rejection of a multi
+ * user chat invitation sent by us.
+ */
+ private Vector<AdHocChatRoomInvitationRejectionListener>
+ invitationRejectionListeners
+ = new Vector<AdHocChatRoomInvitationRejectionListener>();
+
+ /**
+ * Listeners that will be notified of changes in our status in the room such
+ * as us being kicked, banned, or granted admin permissions.
+ */
+ private Vector<LocalUserAdHocChatRoomPresenceListener> presenceListeners
+ = new Vector<LocalUserAdHocChatRoomPresenceListener>();
+
+ /**
+ * A list of the rooms that are currently open by this account.
+ */
+ private Hashtable<String, AdHocChatRoomYahooImpl> chatRoomCache
+ = new Hashtable<String, AdHocChatRoomYahooImpl>();
+
+ /**
+ * The currently valid Yahoo protocol provider service implementation.
+ */
+ private ProtocolProviderServiceYahooImpl yahooProvider = null;
+
+ /**
+ * The operation set for the basic instant messaging, provides some
+ * message format functions.
+ */
+ private OperationSetBasicInstantMessagingYahooImpl opSetBasic = null;
+
+ /**
+ * Message decoder allows to convert Yahoo formated messages, which can
+ * contains some specials characters, to HTML or to plain text.
+ */
+ private MessageDecoder messageDecoder = new MessageDecoder();
+
+ /**
+ * Contacts who have been invited to a chat room during his creation (when a
+ * Yahoo! chat room is created with contacts, an invitation to this chat room
+ * is sent to each of them). These contacts are stored here in order to avoid
+ * them to be invited again after room's creation.
+ */
+ private Vector<String> alreadyInvitedContactAddresses = new Vector<String>();
+
+ /**
+ * Instantiates the user operation set with a currently valid instance of
+ * the Yahoo protocol provider.
+ *
+ * @param yahooProvider
+ * a currently valid instance of
+ * ProtocolProviderServiceYahooImpl.
+ */
+ OperationSetAdHocMultiUserChatYahooImpl(
+ ProtocolProviderServiceYahooImpl yahooProvider)
+ {
+ this.yahooProvider = yahooProvider;
+
+ yahooProvider.addRegistrationStateChangeListener(
+ new RegistrationStateListener());
+
+ opSetBasic = (OperationSetBasicInstantMessagingYahooImpl) yahooProvider
+ .getOperationSet(OperationSetBasicInstantMessaging.class);
+ }
+
+ /**
+ * Adds a listener to invitation notifications.
+ *
+ * @param listener
+ * An invitation listener.
+ */
+ public void addInvitationListener(AdHocChatRoomInvitationListener listener)
+ {
+ synchronized (invitationListeners)
+ {
+ if (!invitationListeners.contains(listener))
+ invitationListeners.add(listener);
+ }
+ }
+
+ /**
+ * Removes a listener that was being notified of changes in our status in a
+ * room such as us being kicked, banned or dropped.
+ *
+ * @param listener
+ * the<tt>LocalUserAdHocChatRoomPresenceListener</tt>.
+ */
+ public void removeInvitationListener(
+ AdHocChatRoomInvitationListener listener)
+ {
+ synchronized (invitationListeners)
+ {
+ invitationListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Subscribes<tt>listener</tt> so that it would receive events indicating
+ * rejection of a multi user chat invitation that we've sent earlier.
+ *
+ * @param listener
+ * the listener that we'll subscribe for invitation rejection
+ * events.
+ */
+
+ public void addInvitationRejectionListener(
+ AdHocChatRoomInvitationRejectionListener listener)
+ {
+ synchronized (invitationRejectionListeners)
+ {
+ if (!invitationRejectionListeners.contains(listener))
+ invitationRejectionListeners.add(listener);
+ }
+ }
+
+ /**
+ * Removes<tt>listener</tt> from the list of invitation listeners
+ * registered to receive invitation rejection events.
+ *
+ * @param listener
+ * the invitation listener to remove.
+ */
+ public void removeInvitationRejectionListener(
+ AdHocChatRoomInvitationRejectionListener listener)
+ {
+ synchronized (invitationRejectionListeners)
+ {
+ invitationRejectionListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Adds a listener that will be notified of changes in our status in a chat
+ * room such as us being kicked, banned or dropped.
+ *
+ * @param listener
+ * the<tt>LocalUserAdHocChatRoomPresenceListener</tt>.
+ */
+ public void addPresenceListener(
+ LocalUserAdHocChatRoomPresenceListener listener)
+ {
+ synchronized (presenceListeners)
+ {
+ if (!presenceListeners.contains(listener))
+ presenceListeners.add(listener);
+ }
+ }
+
+ /**
+ * Removes a listener that was being notified of changes in our status in a
+ * room such as us being kicked, banned or dropped.
+ *
+ * @param listener
+ * the<tt>LocalUserChatRoomPresenceListener</tt>.
+ */
+ public void removePresenceListener(
+ LocalUserAdHocChatRoomPresenceListener listener)
+ {
+ synchronized (presenceListeners)
+ {
+ presenceListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Creates a room with the named<tt>roomName</tt> and according to the
+ * specified<tt>roomProperties</tt> on the server that this protocol
+ * provider is currently connected to. Note the roomProperties also contain
+ * users that we like to invite to the chatRoom, this is required in the
+ * yahoo protocol.
+ *
+ * @param roomName
+ * the name of the<tt>AdHocChatRoom</tt> to create.
+ * @param roomProperties
+ * properties specifying how the room should be created.
+ *
+ * @throws OperationFailedException
+ * if the room couldn't be created for some reason (e.g. room
+ * already exists; user already joined to an existent room or
+ * user has no permissions to create a chat room).
+ * @throws OperationNotSupportedException
+ * if chat room creation is not supported by this server
+ *
+ * @return ChatRoom the chat room that we've just created.
+ */
+ public AdHocChatRoom createAdHocChatRoom(String roomName,
+ Map<String, Object> roomProperties)
+ throws OperationFailedException,
+ OperationNotSupportedException
+ {
+ AdHocChatRoom chatRoom = null;
+
+ try
+ {
+ YahooConference conference = yahooProvider.getYahooSession()
+ .createConference(
+ new String[]{}, //users invited to this conference
+ "", //invite message / topic
+ yahooProvider.getYahooSession().getLoginIdentity());
+
+ chatRoom = findRoom(conference);
+ }
+ catch (Exception e)
+ {
+ logger.debug("Failed to create the chat Room" + e);
+ }
+ return chatRoom;
+ }
+
+ /**
+ * Creates an ad-hoc room with the named<tt>adHocRoomName</tt> and in
+ * including to the specified<tt>contacts</tt>. When the method
+ * returns the ad-hoc room the local user will not have joined it and thus
+ * will not receive messages on it until the<tt>AdHocChatRoom.join()</tt>
+ * method is called.
+ *
+ * @param adHocRoomName the name of the room to be created
+ * @param contacts the list of contacts
+ */
+ public AdHocChatRoom createAdHocChatRoom(String adHocRoomName,
+ List<Contact> contacts)
+ {
+ AdHocChatRoom chatRoom = null;
+ String[] invitedContacts = null; // parameter used for room's creation
+ int contactsIndex = 0;
+
+ if(contacts != null)
+ {
+ invitedContacts = new String[contacts.size()];
+ for(Contact contact : contacts)
+ {
+ ContactYahooImpl newContact = (ContactYahooImpl)contact;
+ invitedContacts[contactsIndex] = newContact.getAddress();
+
+ // contact's address is stored here in order to avoid this
+ // contact to be invited again in the chat room implementation:
+ this.alreadyInvitedContactAddresses.add(newContact.getAddress());
+ contactsIndex++;
+ }
+ }
+
+ try
+ {
+ YahooConference conference = yahooProvider.getYahooSession()
+ .createConference(
+ invitedContacts, //users invited to this conference
+ "", //invite message / topic
+ yahooProvider.getYahooSession().getLoginIdentity());
+
+ chatRoom = findRoom(conference);
+
+ }
+ catch (Exception e)
+ {
+ logger.debug("Failed to create the chat Room" + e);
+ }
+ return chatRoom;
+ }
+
+ /**
+ * Returns a reference to a chatRoom named<tt>roomName</tt> or null.
+ *
+ * @param roomName
+ * the name of the<tt>AdHocChatRoom</tt> that we're looking for.
+ * @return the<tt>ChatRoom</tt> named<tt>roomName</tt> or null if no such
+ * room exists on the server that this provider is currently
+ * connected to.
+ * @throws OperationFailedException
+ * if an error occurs while trying to discover the room on the
+ * server.
+ * @throws OperationNotSupportedException
+ * if the server does not support multi user chat
+ */
+ public AdHocChatRoom findRoom(String roomName)
+ throws OperationFailedException,
+ OperationNotSupportedException
+ {
+ AdHocChatRoom room = (AdHocChatRoom) chatRoomCache.get(roomName);
+
+ return room;
+ }
+
+ /**
+ * Returns a reference to a chatRoom based on the YahooConference, or
+ * creates a chatRoom with it.
+ *
+ * @param yahooConference
+ * The yahoo conference model for a chat room
+ * @return the<tt>ChatRoom</tt> with the name that is in the yahoo
+ * conference specified.
+ * @throws OperationFailedException
+ * if an error occurs while trying to discover the room on the
+ * server.
+ * @throws OperationNotSupportedException
+ * if the server does not support multi user chat
+ */
+ public AdHocChatRoom findRoom(YahooConference yahooConference)
+ throws OperationFailedException, OperationNotSupportedException
+ {
+ AdHocChatRoomYahooImpl room =
+ chatRoomCache.get(yahooConference.getName());
+
+ if (room == null)
+ {
+ room = createLocalChatRoomInstance(yahooConference);
+ chatRoomCache.put(yahooConference.getName(), room);
+ }
+ room.join();
+ return room;
+ }
+
+ /**
+ * Creates a<tt>AdHocChatRoom</tt> instance from the specified Yahoo
+ * conference.
+ *
+ * @param yahooConference
+ * The chat room model from the yahoo lib.
+ *
+ * @return AdHocChatRoom the chat room that we've just created.
+ */
+ private AdHocChatRoomYahooImpl
+ createLocalChatRoomInstance(YahooConference yahooConference)
+ {
+ synchronized (chatRoomCache)
+ {
+ AdHocChatRoomYahooImpl newChatRoom
+ = new AdHocChatRoomYahooImpl(yahooConference, yahooProvider);
+
+ return newChatRoom;
+ }
+ }
+
+ /**
+ * Returns true if<tt>contact</tt> supports multi user chat sessions.
+ *
+ * @param contact
+ * reference to the contact whose support for chat rooms we are
+ * currently querying.
+ * @return a boolean indicating whether<tt>contact</tt> supports chatrooms.
+ * @todo Implement this
+ * net.java.sip.communicator.service.protocol.OperationSetMultiUserChat
+ * method
+ */
+ public boolean isMultiChatSupportedByContact(Contact contact)
+ {
+ if (contact.getProtocolProvider().getOperationSet(
+ OperationSetAdHocMultiUserChat.class) != null)
+ return true;
+
+ return false;
+ }
+
+ /**
+ * Informs the sender of an invitation that we decline their invitation.
+ *
+ * @param invitation
+ * the connection to use for sending the rejection.
+ * @param rejectReason
+ * the reason to reject the given invitation
+ */
+ public void rejectInvitation(AdHocChatRoomInvitation invitation,
+ String rejectReason)
+ {
+ AdHocChatRoomYahooImpl chatRoom = (AdHocChatRoomYahooImpl) invitation
+ .getTargetAdHocChatRoom();
+
+ try
+ {
+ yahooProvider.getYahooSession().declineConferenceInvite(
+ chatRoom.getYahooConference(), rejectReason);
+
+ }
+ catch (IOException e)
+ {
+ logger.debug("Failed to reject Invitation: " + e);
+ }
+ }
+
+ /**
+ * Delivers a<tt>AdHocChatRoomInvitationReceivedEvent</tt> to all registered
+ *<tt>AdHocChatRoomInvitationListener</tt>s.
+ *
+ * @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)
+ {
+ AdHocChatRoomInvitationYahooImpl invitation =
+ new AdHocChatRoomInvitationYahooImpl(
+ targetChatRoom, inviter, reason);
+
+ AdHocChatRoomInvitationReceivedEvent evt =
+ new AdHocChatRoomInvitationReceivedEvent(
+ this, invitation, new Date(System.currentTimeMillis()));
+
+ Iterator<AdHocChatRoomInvitationListener> listeners = null;
+ synchronized (invitationListeners)
+ {
+ listeners = new ArrayList<AdHocChatRoomInvitationListener>(
+ invitationListeners).iterator();
+ }
+
+ while (listeners.hasNext())
+ {
+ AdHocChatRoomInvitationListener listener
+ = (AdHocChatRoomInvitationListener) listeners.next();
+
+ listener.invitationReceived(evt);
+ }
+ }
+
+ /**
+ * Delivers a<tt>AdHocChatRoomInvitationRejectedEvent</tt> to all registered
+ *<tt>AdHocChatRoomInvitationRejectionListener</tt>s.
+ *
+ * @param sourceChatRoom
+ * the room that invitation refers to
+ * @param invitee
+ * the name of the invitee that rejected the invitation
+ * @param reason
+ * the reason of the rejection
+ */
+ public void fireInvitationRejectedEvent(AdHocChatRoom sourceChatRoom,
+ String invitee, String reason)
+ {
+ AdHocChatRoomInvitationRejectedEvent evt =
+ new AdHocChatRoomInvitationRejectedEvent(
+ (OperationSetAdHocMultiUserChat) this,
+ sourceChatRoom,
+ invitee,
+ reason,
+ new Date(System.currentTimeMillis()));
+
+ Iterator<AdHocChatRoomInvitationRejectionListener> listeners = null;
+ synchronized (invitationRejectionListeners)
+ {
+ listeners = new ArrayList<AdHocChatRoomInvitationRejectionListener>(
+ invitationRejectionListeners).iterator();
+ }
+
+ while (listeners.hasNext())
+ {
+ AdHocChatRoomInvitationRejectionListener listener
+ = (AdHocChatRoomInvitationRejectionListener) listeners.next();
+
+ listener.invitationRejected(evt);
+ }
+ }
+
+ /**
+ * Delivers a<tt>LocalUserAdHocChatRoomPresenceChangeEvent</> to all
+ * registered<tt>LocalUserAdHocChatRoomPresenceListener</tt>s.
+ *
+ * @param chatRoom
+ * the<tt>ChatRoom</tt> which has been joined, left, etc.
+ * @param eventType
+ * the type of this event; one of LOCAL_USER_JOINED,
+ * LOCAL_USER_LEFT, etc.
+ * @param reason
+ * the reason
+ */
+ public void fireLocalUserPresenceEvent( AdHocChatRoom chatRoom,
+ String eventType,
+ String reason)
+ {
+ LocalUserAdHocChatRoomPresenceChangeEvent evt
+ = new LocalUserAdHocChatRoomPresenceChangeEvent(
+ (OperationSetAdHocMultiUserChat) this,
+ chatRoom,
+ eventType,
+ reason);
+
+ Iterator<LocalUserAdHocChatRoomPresenceListener> listeners = null;
+ synchronized (presenceListeners)
+ {
+ listeners = new ArrayList<LocalUserAdHocChatRoomPresenceListener>(
+ presenceListeners).iterator();
+ }
+
+ while (listeners.hasNext())
+ {
+ LocalUserAdHocChatRoomPresenceListener listener
+ = (LocalUserAdHocChatRoomPresenceListener) listeners.next();
+
+ listener.localUserAdHocPresenceChanged(evt);
+ }
+ }
+
+ /**
+ * Returns the Vector of addresses of the contacts invited during a chat room
+ * creation.
+ *
+ * @return Vector<String> contact addresses
+ */
+ public Vector<String> getAlreadyInvitedContactAddresses() {
+ return alreadyInvitedContactAddresses;
+ }
+
+ /**
+ * Create a Message instance for sending arbitrary MIME-encoding content.
+ *
+ * @param content content value
+ * @param contentType the MIME-type for<tt>content</tt>
+ * @param contentEncoding encoding used for<tt>content</tt>
+ * @param subject a<tt>String</tt> subject or<tt>null</tt> for now subject.
+ * @return the newly created message.
+ */
+ public Message createMessage(byte[] content, String contentType,
+ String contentEncoding, String subject)
+ {
+ return new MessageYahooImpl(new String(content), contentType,
+ contentEncoding, subject);
+ }
+
+ /**
+ * Creates a message by a given message text.
+ *
+ * @param messageText
+ * The message text.
+ * @return the newly created message.
+ */
+ public Message createMessage(String messageText)
+ {
+ return new MessageYahooImpl(messageText,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_ENCODING, null);
+ }
+
+ /**
+ * Our listener that will tell us when we're registered to yahoo network.
+ *
+ */
+ private class RegistrationStateListener implements
+ RegistrationStateChangeListener
+ {
+ /**
+ * The method is called by a ProtocolProvider implementation whenever a
+ * change in the registration state of the corresponding provider had
+ * occurred.
+ *
+ * @param evt
+ * ProviderStatusChangeEvent the event describing the status
+ * change.
+ */
+ public void registrationStateChanged(RegistrationStateChangeEvent evt)
+ {
+ if (evt.getNewState() == RegistrationState.REGISTERED)
+ {
+ yahooProvider.getYahooSession().addSessionListener(
+ new YahooMessageListener());
+ }
+ }
+ }
+
+ /**
+ * Our group chat message listener, it extends the SessionAdapter from the
+ * the yahoo library.
+ *
+ */
+ private class YahooMessageListener extends SessionAdapter
+ {
+
+ public void conferenceInviteDeclinedReceived(SessionConferenceEvent ev)
+ {
+ logger.debug("Group Chat invite declined received. "
+ + ev.toString());
+ try
+ {
+ AdHocChatRoom chatRoom = findRoom(ev.getRoom());
+
+ fireInvitationRejectedEvent(chatRoom, ev.getFrom(), ev
+ .getMessage());
+ }
+ catch (Exception e)
+ {
+ logger.debug("Error: " + e);
+ }
+ }
+
+ public void conferenceInviteReceived(SessionConferenceEvent ev)
+ {
+ logger.debug("Conference Invite Received: " + ev.toString());
+
+ try
+ {
+ AdHocChatRoom chatRoom = findRoom(ev.getRoom().getName());
+ if (chatRoom != null)
+ {
+ chatRoom.join();
+ } else
+ {
+ chatRoom = findRoom(ev.getRoom());
+ fireInvitationEvent(chatRoom, ev.getFrom(), ev.getMessage());
+ }
+
+ }
+ catch (Exception e)
+ {
+ logger.debug("Error: " + e);
+ }
+ }
+
+ public void conferenceLogoffReceived(SessionConferenceEvent ev)
+ {
+ logger.debug("Conference Logoff Received: " + ev.toString());
+
+ try
+ {
+ AdHocChatRoomYahooImpl chatRoom =
+ (AdHocChatRoomYahooImpl) findRoom(ev
+ .getRoom().getName());
+
+ if (chatRoom != null)
+ {
+ Contact participant = chatRoom
+ .findParticipantForAddress(ev.getFrom());
+ chatRoom.removeChatRoomParticipant(participant);
+ }
+ }
+ catch (Exception e)
+ {
+ logger.debug("Failed to remove a user from the chat room. " + e);
+ }
+ }
+
+ public void conferenceLogonReceived(SessionConferenceEvent ev)
+ {
+ logger.debug("Conference Logon Received: " + ev.toString());
+
+ try
+ {
+ AdHocChatRoomYahooImpl chatRoom =
+ (AdHocChatRoomYahooImpl) findRoom(ev
+ .getRoom().getName());
+
+ if (chatRoom != null)
+ {
+ OperationSetPersistentPresenceYahooImpl presenceOpSet
+ = (OperationSetPersistentPresenceYahooImpl) chatRoom
+ .getParentProvider().getOperationSet(
+ OperationSetPersistentPresence.class);
+
+ Contact participant
+ = presenceOpSet.findContactByID(ev.getFrom());
+
+ if(alreadyInvitedContactAddresses.contains(
+ participant.getAddress()))
+ {
+ alreadyInvitedContactAddresses.remove(
+ participant.getAddress());
+ }
+
+ chatRoom.addChatRoomParticipant(participant);
+ }
+ }
+ catch (Exception e)
+ {
+ logger.debug("Failed to add a user to the chat room. " + e);
+ }
+ }
+
+ public void conferenceMessageReceived(SessionConferenceEvent ev)
+ {
+ logger.debug("Conference Message Received: " + ev.toString());
+
+ try
+ {
+ String formattedMessage = ev.getMessage();
+ logger.debug("original message received : " + formattedMessage);
+
+ // if the message is decorated by Yahoo, we try to "decode" it
+ // first.
+ if (formattedMessage.startsWith("\u001b"))
+ {
+ formattedMessage = opSetBasic.processLinks(messageDecoder
+ .decodeToHTML(formattedMessage));
+ } else
+ {
+ formattedMessage = opSetBasic
+ .processLinks(formattedMessage);
+ }
+
+ // now, we try to fix a wrong usage of the size attribute in the
+ //<font> HTML element
+ // here, the zero 0 correspond to 10px
+ formattedMessage = formattedMessage.replaceAll(
+ "(<font) (.*) size=\"0\">", "$1 $2 size=\"10\">");
+ formattedMessage = formattedMessage.replaceAll(
+ "(<font) (.*) size=\"(\\d+)\">",
+ "$1 $2 style=\"font-size: $3px;\">");
+
+ logger.debug("formatted Message : " + formattedMessage);
+ // As no indications in the protocol is it html or not. No harm
+ // to set all messages html - doesn't affect the appearance of
+ // the gui
+
+ Message newMessage = createMessage(formattedMessage.getBytes(),
+ OperationSetBasicInstantMessaging.HTML_MIME_TYPE,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_ENCODING,
+ null);
+
+ AdHocChatRoomYahooImpl chatRoom =
+ (AdHocChatRoomYahooImpl) findRoom(ev
+ .getRoom().getName());
+
+ if (chatRoom != null)
+ {
+ Contact member = chatRoom.findParticipantForAddress(
+ ev.getFrom());
+
+ AdHocChatRoomMessageReceivedEvent msgReceivedEvent
+ = new AdHocChatRoomMessageReceivedEvent(
+ chatRoom,
+ member,
+ System.currentTimeMillis(),
+ newMessage,
+ AdHocChatRoomMessageReceivedEvent
+ .CONVERSATION_MESSAGE_RECEIVED);
+
+ chatRoom.fireMessageEvent(msgReceivedEvent);
+ }
+ }
+ catch (Exception e)
+ {
+ logger.debug("Error while receiving a multi user chat message: "
+ + e);
+ }
+
+ }
+
+ public void connectionClosed(SessionEvent ev)
+ {
+ logger.debug("Connection Closed: " + ev.toString());
+ }
+ }
+}

Removed: trunk/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetMultiUserChatYahooImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetMultiUserChatYahooImpl.java?view=auto&rev=5963

Modified: trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolProviderServiceYahooImpl.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolProviderServiceYahooImpl.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolProviderServiceYahooImpl.java&p2=trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolProviderServiceYahooImpl.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolProviderServiceYahooImpl.java (original)
+++ trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolProviderServiceYahooImpl.java 2009-09-14 15:51:47+0000
@@ -342,11 +342,12 @@
                 basicInstantMessaging);

            //initialize the multi user chat operation set
- OperationSetMultiUserChatYahooImpl multiUserChatOpSet =
- new OperationSetMultiUserChatYahooImpl(this);
+ OperationSetAdHocMultiUserChatYahooImpl multiUserChatOpSet =
+ new OperationSetAdHocMultiUserChatYahooImpl(this);

- supportedOperationSets.put(OperationSetMultiUserChat.class.getName(),
- multiUserChatOpSet);
+ supportedOperationSets.put(
+ OperationSetAdHocMultiUserChat.class.getName(),
+ multiUserChatOpSet);

             //initialize the typing notifications operation set
             typingNotifications =

Modified: trunk/src/net/java/sip/communicator/plugin/chatalerter/ChatAlerterActivator.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/plugin/chatalerter/ChatAlerterActivator.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/plugin/chatalerter/ChatAlerterActivator.java&p2=trunk/src/net/java/sip/communicator/plugin/chatalerter/ChatAlerterActivator.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/plugin/chatalerter/ChatAlerterActivator.java (original)
+++ trunk/src/net/java/sip/communicator/plugin/chatalerter/ChatAlerterActivator.java 2009-09-14 15:51:47+0000
@@ -31,7 +31,9 @@
                 ServiceListener,
                 MessageListener,
                 ChatRoomMessageListener,
- LocalUserChatRoomPresenceListener
+ AdHocChatRoomMessageListener,
+ LocalUserChatRoomPresenceListener,
+ LocalUserAdHocChatRoomPresenceListener
{
     /**
      * The logger for this class.
@@ -106,6 +108,7 @@
                 this.handleProviderAdded(provider);
             }
         }
+
     }

     public void stop(BundleContext bc) throws Exception
@@ -336,4 +339,59 @@
             break;
         }
     }
+
+ public void messageDelivered(AdHocChatRoomMessageDeliveredEvent evt)
+ {
+ // do nothing
+ }
+
+ public void messageDeliveryFailed(
+ AdHocChatRoomMessageDeliveryFailedEvent evt)
+ {
+ // do nothing
+ }
+
+ public void messageReceived(AdHocChatRoomMessageReceivedEvent evt)
+ {
+ try
+ {
+ ExportedWindow win =
+ uiService.getExportedWindow(ExportedWindow.CHAT_WINDOW);
+
+ if(win == null || win.getSource() == null ||
+ !(win.getSource() instanceof JFrame))
+ return;
+
+ JFrame fr = (JFrame)win.getSource();
+
+ if(fr != null)
+ Alerter.newInstance().alert(fr);
+ }
+ catch (Exception ex)
+ {
+ logger.error("Cannot alert chat window!");
+ }
+ }
+
+ /**
+ * Called to notify interested parties that a change in our presence in
+ * an ad-hoc chat room has occurred. Changes may include us being join,
+ * left.
+ * @param evt the<tt>LocalUserAdHocChatRoomPresenceChangeEvent</tt>
+ * instance containing the ad-hoc chat room and the type, and reason of the
+ * change
+ */
+ public void localUserAdHocPresenceChanged(
+ LocalUserAdHocChatRoomPresenceChangeEvent evt)
+ {
+ if(evt.getEventType() ==
+ LocalUserAdHocChatRoomPresenceChangeEvent.LOCAL_USER_JOINED)
+ {
+ evt.getAdHocChatRoom().addMessageListener(this);
+ }
+ else
+ {
+ evt.getAdHocChatRoom().removeMessageListener(this);
+ }
+ }
}

Modified: trunk/src/net/java/sip/communicator/plugin/contactinfo/resources/personPhoto.png
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/plugin/contactinfo/resources/personPhoto.png?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/plugin/contactinfo/resources/personPhoto.png&p2=trunk/src/net/java/sip/communicator/plugin/contactinfo/resources/personPhoto.png&r1=5963&r2=5964

Binary files. No diff available.

Modified: trunk/src/net/java/sip/communicator/plugin/contactinfo/resources/userInfo16x16.png
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/plugin/contactinfo/resources/userInfo16x16.png?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/plugin/contactinfo/resources/userInfo16x16.png&p2=trunk/src/net/java/sip/communicator/plugin/contactinfo/resources/userInfo16x16.png&r1=5963&r2=5964

Binary files. No diff available.

Modified: trunk/src/net/java/sip/communicator/plugin/facebookaccregwizz/FacebookAccountRegistrationWizard.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/plugin/facebookaccregwizz/FacebookAccountRegistrationWizard.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/plugin/facebookaccregwizz/FacebookAccountRegistrationWizard.java&p2=trunk/src/net/java/sip/communicator/plugin/facebookaccregwizz/FacebookAccountRegistrationWizard.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/plugin/facebookaccregwizz/FacebookAccountRegistrationWizard.java (original)
+++ trunk/src/net/java/sip/communicator/plugin/facebookaccregwizz/FacebookAccountRegistrationWizard.java 2009-09-14 15:51:47+0000
@@ -143,7 +143,7 @@
      */
     public ProtocolProviderService signin(String userName, String password)
     {
- firstWizardPage = null;
+ firstWizardPage = null;
         ProtocolProviderFactory factory
             = FacebookAccRegWizzActivator.getFacebookProtocolProviderFactory();

@@ -342,8 +342,8 @@
         return false;
     }

- public Object getSimpleForm() {
- firstWizardPage = new FirstWizardPage(this);
+ public Object getSimpleForm() {
+ firstWizardPage = new FirstWizardPage(this);
         return firstWizardPage.getSimpleForm();
- }
+ }
}

Modified: trunk/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java&p2=trunk/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java&r1=5963&r2=5964

--- trunk/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java (original)
+++ trunk/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java 2009-09-14 15:51:47+0000
@@ -128,11 +128,11 @@
     }

     enum MessageEventType{
- None,
- MessageDelivered,
- MessageReceived,
- MessageDeliveryFailed,
- MessageDeliveryPending,
+ None,
+ MessageDelivered,
+ MessageReceived,
+ MessageDeliveryFailed,
+ MessageDeliveryPending,
     }

     /**
@@ -157,21 +157,21 @@
         MessageEventType eventType = MessageEventType.None;
         if (evt instanceof MessageDeliveredEvent)
         {
- eventType = MessageEventType.MessageDelivered;
+ eventType = MessageEventType.MessageDelivered;
         }
         else if (evt instanceof MessageReceivedEvent)
         {
- eventType = MessageEventType.MessageReceived;
+ eventType = MessageEventType.MessageReceived;
         }
         else if (evt instanceof MessageDeliveryFailedEvent)
         {
- eventType = MessageEventType.MessageDeliveryFailed;
+ eventType = MessageEventType.MessageDeliveryFailed;
         }

         // Transform the event.
         evt = messageTransform(evt, eventType);
         if (evt == null)
- return;
+ return;

         for (Iterator<MessageListener> listenerIter = listeners.iterator(); listenerIter
             .hasNext():wink:
@@ -179,15 +179,15 @@
             MessageListener listener = listenerIter.next();
             switch (eventType){
             case MessageDelivered:
- listener.messageDelivered((MessageDeliveredEvent) evt);
- break;
+ listener.messageDelivered((MessageDeliveredEvent) evt);
+ break;
             case MessageDeliveryFailed:
- listener
+ listener
                 .messageDeliveryFailed((MessageDeliveryFailedEvent) evt);
- break;
+ break;
             case MessageReceived:
- listener.messageReceived((MessageReceivedEvent) evt);
- break;
+ listener.messageReceived((MessageReceivedEvent) evt);
+ break;
             }
         }
     }
@@ -221,35 +221,35 @@
     }

     public MessageDeliveredEvent messageDeliveryPendingTransform(MessageDeliveredEvent evt){
- return (MessageDeliveredEvent)messageTransform(evt, MessageEventType.MessageDeliveryPending);
+ return (MessageDeliveredEvent)messageTransform(evt, MessageEventType.MessageDeliveryPending);
     }

     private EventObject messageTransform(EventObject evt, MessageEventType eventType){
-
- ProtocolProviderService protocolProvider;
- switch (eventType){
- case MessageDelivered:
- protocolProvider = ((MessageDeliveredEvent)evt).getDestinationContact().getProtocolProvider();
- break;
- case MessageDeliveryFailed:
- protocolProvider = ((MessageDeliveryFailedEvent)evt).getDestinationContact().getProtocolProvider();
- break;
- case MessageDeliveryPending:
- protocolProvider = ((MessageDeliveredEvent)evt).getDestinationContact().getProtocolProvider();
- break;
- case MessageReceived:
- protocolProvider = ((MessageReceivedEvent)evt).getSourceContact().getProtocolProvider();
- break;
- default:
- return evt;
- }
-
- OperationSetInstantMessageTransformImpl opSetMessageTransform =
+
+ ProtocolProviderService protocolProvider;
+ switch (eventType){
+ case MessageDelivered:
+ protocolProvider = ((MessageDeliveredEvent)evt).getDestinationContact().getProtocolProvider();
+ break;
+ case MessageDeliveryFailed:
+ protocolProvider = ((MessageDeliveryFailedEvent)evt).getDestinationContact().getProtocolProvider();
+ break;
+ case MessageDeliveryPending:
+ protocolProvider = ((MessageDeliveredEvent)evt).getDestinationContact().getProtocolProvider();
+ break;
+ case MessageReceived:
+ protocolProvider = ((MessageReceivedEvent)evt).getSourceContact().getProtocolProvider();
+ break;
+ default:
+ return evt;
+ }
+
+ OperationSetInstantMessageTransformImpl opSetMessageTransform =
             (OperationSetInstantMessageTransformImpl)protocolProvider.getOperationSet(OperationSetInstantMessageTransform.class);

- if (opSetMessageTransform == null)
- return evt;
-
+ if (opSetMessageTransform == null)
+ return evt;
+
         for (Map.Entry<Integer, Vector<TransformLayer>> entry
                 : opSetMessageTransform.transformLayers.entrySet())
         {

Added: trunk/src/net/java/sip/communicator/service/protocol/AdHocChatRoom.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/AdHocChatRoom.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/AdHocChatRoom.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,144 @@
+/*
+ * 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.service.protocol;
+
+import java.util.List;
+
+import net.java.sip.communicator.service.protocol.event.*;
+
+/**
+ * Represents an ad-hoc rendez-vous point where multiple chat users could
+ * communicate together. This interface describes the main methods used by some
+ * protocols for multi user chat, without useless methods (such as kicking a
+ * participant) which aren't supported by these protocols (MSN, ICQ, Yahoo!,
+ * etc.).
+ *
+ *<tt>AdHocChatRoom</tt> acts like a simplified<tt>ChatRoom</tt>.
+ *
+ * @author Valentin Martinet
+ */
+public interface AdHocChatRoom
+{
+ /**
+ * Returns the name of this<tt>AdHocChatRoom</tt>. The name can't be
+ * changed until the<tt>AdHocChatRoom</tt> is ended.
+ *
+ * @return a<tt>String</tt> containing the name
+ */
+ public String getName();
+
+ /**
+ * Returns the identifier of this<tt>AdHocChatRoom</tt>. The identifier of
+ * the ad-hoc chat room would have the following syntax:
+ * [adHocChatRoomName]@[adHocChatRoomServer]@[accountID]
+ *
+ * @return a<tt>String</tt> containing the identifier of this
+ *<tt>AdHocChatRoom</tt>.
+ */
+ public String getIdentifier();
+
+ /**
+ * Adds a listener that will be notified of changes in our participation in
+ * the ad-hoc room such as us being join, left...
+ *
+ * @param listener a member participation listener.
+ */
+ public void addParticipantPresenceListener(
+ AdHocChatRoomParticipantPresenceListener listener);
+
+ /**
+ * Removes a participant presence listener.
+ *
+ * @param listener a member participation listener.
+ */
+ public void removeParticipantPresenceListener(
+ AdHocChatRoomParticipantPresenceListener listener);
+
+ /**
+ * Registers<tt>listener</tt> so that it would receive events every time a
+ * new message is received on this ad-hoc chat room.
+ *
+ * @param listener a<tt>MessageListener</tt> that would be notified every
+ * time a new message is received on this ad-hoc chat room.
+ */
+ public void addMessageListener(AdHocChatRoomMessageListener listener);
+
+ /**
+ * Removes<tt>listener</tt> so that it won't receive any further message
+ * events from this ad-hoc room.
+ *
+ * @param listener the<tt>MessageListener</tt> to remove from this ad-hoc
+ * room
+ */
+ public void removeMessageListener(AdHocChatRoomMessageListener listener);
+
+ /**
+ * Invites another<tt>Contact</tt> to this ad-hoc chat room.
+ *
+ * @param userAddress the address of the<tt>Contact</tt> of the user to
+ * invite to the ad-hoc room.
+ * @param reason a reason, subject, or welcome message that would tell
+ * users why they are being invited.
+ */
+ public void invite(String userAddress, String reason);
+
+ /**
+ * Returns a<tt>List</tt> of<tt>Contact</tt>s corresponding to all
+ * participants currently participating in this room.
+ *
+ * @return a<tt>List</tt> of<tt>Contact</tt>s instances
+ * corresponding to all room members.
+ * @throws OperationFailedException if we fail retrieving the list of room
+ * participants.
+ */
+ public List<Contact> getParticipants();
+
+ /**
+ * Returns the number of participants that are currently in this ad-hoc
+ * chat room.
+ * @return int the number of<tt>Contact</tt>s, currently participating in
+ * this ad-hoc room.
+ */
+ public int getParticipantsCount();
+
+ /**
+ * Create a<tt>Message</tt> instance for sending a simple text messages
+ * with default (text/plain) content type and encoding.
+ *
+ * @param messageText the string content of the message.
+ * @return Message the newly created message
+ */
+ public Message createMessage(String messageText);
+
+ /**
+ * Sends the<tt>Message</tt> to this ad-hoc chat room.
+ *
+ * @param message the<tt>Message</tt> to send.
+ * @throws OperationFailedException if sending the message fails for some
+ * reason.
+ */
+ public void sendMessage(Message message)
+ throws OperationFailedException;
+
+ /**
+ * Returns a reference to the provider that created this room.
+ *
+ * @return a reference to the<tt>ProtocolProviderService</tt> instance
+ * that created this ad-hoc room.
+ */
+ public ProtocolProviderService getParentProvider();
+
+ /**
+ * Joins this ad-hoc chat room with the nickname of the local user so that
+ * the user would start receiving events and messages for it.
+ *
+ * @throws OperationFailedException with the corresponding code if an error
+ * occurs while joining the ad-hoc room.
+ */
+ public void join()
+ throws OperationFailedException;
+}

Added: trunk/src/net/java/sip/communicator/service/protocol/AdHocChatRoomInvitation.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/AdHocChatRoomInvitation.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/AdHocChatRoomInvitation.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,43 @@
+/*
+ * 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.service.protocol;
+
+/**
+ * This interface represents an invitation, which is send from an ad-hoc chat
+ * room participant to another user in order to invite this user to join the
+ * ad-hoc chat room.
+ *
+ * @author Valentin Martinet
+ */
+public interface AdHocChatRoomInvitation
+{
+ /**
+ * Returns the<tt>AdHocChatRoom</tt>, which is the target of this
+ * invitation.
+ * The ad-hoc chat room returned by this method will be the room to which
+ * the user
+ * is invited to join to.
+ *
+ * @return the<tt>AdHocChatRoom</tt>, which is the target of this
+ * invitation
+ */
+ public AdHocChatRoom getTargetAdHocChatRoom();
+
+ /**
+ * Returns the<tt>Contact</tt> that sent this invitation.
+ *
+ * @return the<tt>Contact</tt> that sent this invitation.
+ */
+ public String getInviter();
+
+ /**
+ * Returns the reason of this invitation, or null if there is no reason.
+ *
+ * @return the reason of this invitation, or null if there is no reason
+ */
+ public String getReason();
+}

Added: trunk/src/net/java/sip/communicator/service/protocol/OperationSetAdHocMultiUserChat.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/OperationSetAdHocMultiUserChat.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/OperationSetAdHocMultiUserChat.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,143 @@
+/*
+ * 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.service.protocol;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.protocol.event.*;
+
+/**
+ * Allows creating, configuring, joining and administering of individual
+ * text-based ad-hoc conference rooms.
+ *
+ * @author Valentin Martinet
+ */
+public interface OperationSetAdHocMultiUserChat
+ extends OperationSet
+{
+ /**
+ * Creates an ad-hoc room with the named<tt>adHocRoomName</> and
+ * according to the specified<tt>adHocRoomProperties</tt>. When the method
+ * returns the ad-hoc room the local user will not have joined it and thus
+ * will not receive messages on it until the<tt>AdHocChatRoom.join()</tt>
+ * method is called.
+ *<p>
+ *
+ * @param adHocRoomName
+ * the name of the<tt>AdHocChatRoom</tt> to create.
+ * @param adHocRoomProperties
+ * properties specifying how the ad-hoc room should be created;
+ *<tt>null</tt> for no properties just like an empty
+ *<code>Map</code>
+ * @throws OperationFailedException
+ * if the ad-hoc room couldn't be created for some reason.
+ * @throws OperationNotSupportedException
+ * if chat room creation is not supported by this server
+ *
+ * @return the newly created<tt>AdHocChatRoom</tt> named<tt>roomName</tt>.
+ */
+ public AdHocChatRoom createAdHocChatRoom(String adHocRoomName,
+ Map<String, Object> adHocRoomProperties)
+ throws OperationFailedException, OperationNotSupportedException;
+
+ /**
+ * Creates an ad-hoc room with the named<tt>adHocRoomName</> and in
+ * including to the specified<tt>contacts</tt>. When the method
+ * returns the ad-hoc room the local user will not have joined it and thus
+ * will not receive messages on it until the<tt>AdHocChatRoom.join()</tt>
+ * method is called.
+ *<p>
+ *
+ * @param adHocRoomName
+ * the name of the<tt>AdHocChatRoom</tt> to create.
+ * @param contacts
+ * the contacts who are added to the room when it's created;
+ *<tt>null</tt> for no contacts
+ * @throws OperationFailedException
+ * if the ad-hoc room couldn't be created for some reason.
+ * @throws OperationNotSupportedException
+ * if chat room creation is not supported by this server
+ *
+ * @return the newly created<tt>AdHocChatRoom</tt> named<tt>roomName</tt>.
+ */
+ public AdHocChatRoom createAdHocChatRoom(String adHocRoomName,
+ List<Contact> contacts)
+ throws OperationFailedException, OperationNotSupportedException;
+
+ /**
+ * Returns a reference to an AdHocChatRoom named<tt>adHocRoomName</tt> or
+ * null if no ad-hoc room with the given name exist on the server.
+ *<p>
+ * @param adHocRroomName the name of the<tt>AdHocChatRoom</> that we're
+ * looking for.
+ * @return the<tt>AdHocChatRoom</tt> named<tt>adHocRoomName</> if it
+ * exists, null otherwise.
+ *
+ * @throws OperationFailedException if an error occurs while trying to
+ * discover the ad-hoc room on the server.
+ * @throws OperationNotSupportedException if the server does not support
+ * multi-user chat
+ */
+ public AdHocChatRoom findRoom(String adHocRoomName)
+ throws OperationFailedException, OperationNotSupportedException;
+
+ /**
+ * Returns true if<tt>contact</tt> supports multi-user chat sessions.
+ *
+ * @param contact reference to the contact whose support for ad-hoc chat
+ * rooms we are currently querying.
+ * @return a boolean indicating whether<tt>contact</tt> supports ad-hoc
+ * chat rooms.
+ */
+ public boolean isMultiChatSupportedByContact(Contact contact);
+
+ /**
+ * Adds a listener that will be notified of changes in our participation in
+ * an ad-hoc chat room such as us being joined, left.
+ *
+ * @param listener a local user participation listener.
+ */
+ public void addPresenceListener(
+ LocalUserAdHocChatRoomPresenceListener listener);
+
+ /**
+ * Removes a listener that was being notified of changes in our
+ * participation in an ad-hoc room such as us being joined, left.
+ *
+ * @param listener a local user participation listener.
+ */
+ public void removePresenceListener(
+ LocalUserAdHocChatRoomPresenceListener listener);
+
+ /**
+ * Adds the given<tt>listener</tt> to the list of
+ *<tt>AdHocChatRoomInvitationListener</tt>-s that would be notified when
+ * an add-hoc chat room invitation has been received.
+ *
+ * @param listener the<tt>AdHocChatRoomInvitationListener</> to add
+ */
+ public void addInvitationListener(AdHocChatRoomInvitationListener listener);
+
+ /**
+ * Adds the given<tt>listener</tt> to the list of
+ *<tt>AdHocChatRoomInvitationRejectionListener</tt>-s that would be
+ * notified when an add-hoc chat room invitation has been rejected.
+ *
+ * @param listener the<tt>AdHocChatRoomInvitationListener</> to add
+ */
+ public void addInvitationRejectionListener(
+ AdHocChatRoomInvitationRejectionListener listener);
+
+ /**
+ * Informs the sender of an invitation that we decline their invitation.
+ *
+ * @param invitation the invitation we are rejecting.
+ * @param rejectReason the reason to reject the invitation (optional)
+ */
+ public void rejectInvitation( AdHocChatRoomInvitation invitation,
+ String rejectReason);
+}

Added: trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomCreatedEvent.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomCreatedEvent.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomCreatedEvent.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,59 @@
+/*
+ * 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.service.protocol.event;
+
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * The event that occurs when an ad-hoc chat room has been created.
+ *
+ * @author Valentin Martinet
+ */
+public class AdHocChatRoomCreatedEvent
+{
+ /**
+ * The ad-hoc room that has been created.
+ */
+ private AdHocChatRoom adHocChatRoom;
+
+ /**
+ * The<tt>Contact</tt> who created the ad-hoc room.
+ */
+ private Contact by;
+
+ /**
+ * Initializes an<tt>AdHocChatRoomCreatedEvent</tt> with the creator (<tt>
+ * by</tt>) and the ad-hoc room<tt>adHocChatRoom</tt>.
+ *
+ * @param adHocChatRoom the<tt>AdHocChatRoom</tt>
+ * @param by the<tt>Contact</tt> who created this ad-hoc room
+ */
+ public AdHocChatRoomCreatedEvent(AdHocChatRoom adHocChatRoom, Contact by)
+ {
+ this.adHocChatRoom = adHocChatRoom;
+ this.by = by;
+ }
+
+ /**
+ * Returns the<tt>Contact</tt> who created the room.
+ *
+ * @return<tt>Contact</tt>
+ */
+ public Contact getBy()
+ {
+ return this.by;
+ }
+
+ /**
+ * Returns the ad-hoc room concerned by this event.
+ *
+ * @return<tt>AdHocChatRoom</tt>
+ */
+ public AdHocChatRoom getAdHocCreatedRoom()
+ {
+ return this.adHocChatRoom;
+ }
+}

Added: trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomDestroyedEvent.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomDestroyedEvent.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomDestroyedEvent.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,59 @@
+/*
+ * 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.service.protocol.event;
+
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * The event that occurs when an ad-hoc chat room has been created.
+ *
+ * @author Valentin Martinet
+ */
+public class AdHocChatRoomDestroyedEvent
+{
+ /**
+ * The ad-hoc room that has been created.
+ */
+ private AdHocChatRoom adHocChatRoom;
+
+ /**
+ * The<tt>Contact</tt> who created the ad-hoc room.
+ */
+ private Contact by;
+
+ /**
+ * Initializes an<tt>AdHocChatRoomDestroyedEvent</tt> with the creator
+ * (<tt> by</tt>) and the ad-hoc room<tt>adHocChatRoom</tt>.
+ *
+ * @param adHocChatRoom the<tt>AdHocChatRoom</tt>
+ * @param by the<tt>Contact</tt> who created this ad-hoc room
+ */
+ public AdHocChatRoomDestroyedEvent(AdHocChatRoom adHocChatRoom, Contact by)
+ {
+ this.adHocChatRoom = adHocChatRoom;
+ this.by = by;
+ }
+
+ /**
+ * Returns the<tt>Contact</tt> who created the room.
+ *
+ * @return<tt>Contact</tt>
+ */
+ public Contact getBy()
+ {
+ return this.by;
+ }
+
+ /**
+ * Returns the ad-hoc room concerned by this event.
+ *
+ * @return<tt>AdHocChatRoom</tt>
+ */
+ public AdHocChatRoom getAdHocDestroyedRoom()
+ {
+ return this.adHocChatRoom;
+ }
+}

Added: trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationListener.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationListener.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationListener.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,26 @@
+/*
+ * 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.service.protocol.event;
+
+/**
+ * A listener that dispatches events notifying that an invitation to join an
+ * ad-hoc MUC room is received.
+ *
+ * @author Valentin Martinet
+ */
+public interface AdHocChatRoomInvitationListener
+{
+ /**
+ * Called when we receive an invitation to join an existing
+ *<tt>AdHocChatRoom</tt>.
+ *<p>
+ * @param evt the<tt>AdHocChatRoomInvitationReceivedEvent</> that
+ * contains the newly received invitation and its source provider.
+ */
+ public abstract void invitationReceived(
+ AdHocChatRoomInvitationReceivedEvent evt);
+}

Added: trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationReceivedEvent.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationReceivedEvent.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationReceivedEvent.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,85 @@
+/*
+ * 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.service.protocol.event;
+
+import java.util.*;
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ *<tt>AdHocChatRoomInvitationReceivedEvent</tt>s indicate reception of an
+ * invitation to join an ad-hoc chat room.
+ *
+ * @author Valentin Martinet
+ */
+@SuppressWarnings("serial")
+public class AdHocChatRoomInvitationReceivedEvent
+ extends EventObject
+{
+ /**
+ * The invitation corresponding to this event.
+ */
+ private final AdHocChatRoomInvitation invitation;
+
+ /**
+ * A timestamp indicating the exact date when the event occurred.
+ */
+ private final Date timestamp;
+
+ /**
+ * Creates an<tt>InvitationReceivedEvent</tt> representing reception of
+ * the<tt>source</tt> invitation received from the specified
+ *<tt>from</tt> ad-hoc chat room participant.
+ *
+ * @param adHocMultiUserChatOpSet the
+ *<tt>OperationSetAdHocMultiUserChat</tt>, which dispatches this event
+ * @param invitation the<tt>AdHocChatRoomInvitation</tt> that this event is
+ * for
+ * @param timestamp the exact date when the event occurred.
+ */
+ public AdHocChatRoomInvitationReceivedEvent(
+ OperationSetAdHocMultiUserChat adHocMultiUserChatOpSet,
+ AdHocChatRoomInvitation invitation,
+ Date timestamp)
+ {
+ super(adHocMultiUserChatOpSet);
+
+ this.invitation = invitation;
+ this.timestamp = timestamp;
+ }
+
+ /**
+ * Returns the ad-hoc multi user chat operation set that dispatches this
+ * event.
+ *
+ * @return the ad-hoc multi user chat operation set that dispatches this
+ * event.
+ */
+ public OperationSetAdHocMultiUserChat getSourceOperationSet()
+ {
+ return (OperationSetAdHocMultiUserChat) getSource();
+ }
+
+ /**
+ * Returns the<tt>AdHocChatRoomInvitation</tt> that this event is for.
+ *
+ * @return the<tt>AdHocChatRoomInvitation</tt> that this event is for.
+ */
+ public AdHocChatRoomInvitation getInvitation()
+ {
+ return invitation;
+ }
+
+ /**
+ * A timestamp indicating the exact date when the event ocurred.
+ *
+ * @return a Date indicating when the event ocurred.
+ */
+ public Date getTimestamp()
+ {
+ return timestamp;
+ }
+}

Added: trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationRejectedEvent.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationRejectedEvent.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationRejectedEvent.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,123 @@
+/*
+ * 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.service.protocol.event;
+
+import java.util.*;
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ *<tt>AdHocChatRoomInvitationRejectedEvent</tt>s indicates the reception of a
+ * rejection of an invitation.
+ *
+ * @author Valentin Martinet
+ */
+@SuppressWarnings("serial")
+public class AdHocChatRoomInvitationRejectedEvent
+ extends EventObject
+{
+ /**
+ * The<tt>AdHocChatRoom</tt> for which the initial invitation was.
+ */
+ private AdHocChatRoom adHocChatRoom;
+
+ /**
+ * The invitee that rejected the invitation.
+ */
+ private String invitee;
+
+ /**
+ * The reason why this invitation is rejected or null if there is no reason
+ * specified.
+ */
+ private String reason;
+
+ /**
+ * The exact date at which this event occured.
+ */
+ private Date timestamp;
+
+ /**
+ * Creates a<tt>AdHocChatRoomInvitationRejectedEvent</tt> representing the
+ * rejection of an invitation, rejected by the given<tt>invitee</tt>.
+ *
+ * @param source the<tt>OperationSetAdHocMultiUserChat</tt> that dispatches
+ * this
+ * event
+ * @param adHocChatRoom the<tt>AdHocChatRoom</tt> for which the initial
+ * invitation was
+ * @param invitee the name of the invitee that rejected the invitation
+ * @param reason the reason of the rejection
+ * @param timestamp the exact date when the event ocurred
+ */
+ public AdHocChatRoomInvitationRejectedEvent(
+ OperationSetAdHocMultiUserChat source,
+ AdHocChatRoom adHocChatRoom,
+ String invitee,
+ String reason,
+ Date timestamp)
+ {
+ super(source);
+
+ this.adHocChatRoom = adHocChatRoom;
+ this.invitee = invitee;
+ this.reason = reason;
+ this.timestamp = timestamp;
+ }
+
+ /**
+ * Returns the ad-hoc multi user chat operation set that dispatches this
+ * event.
+ *
+ * @return the ad-hoc multi user chat operation set that dispatches this
+ * event
+ */
+ public OperationSetAdHocMultiUserChat getSourceOperationSet()
+ {
+ return (OperationSetAdHocMultiUserChat)getSource();
+ }
+
+ /**
+ * Returns the<tt>AdHocChatRoom</tt> for which the initial invitation was.
+ *
+ * @return the<tt>AdHocChatRoom</tt> for which the initial invitation was
+ */
+ public AdHocChatRoom getChatRoom()
+ {
+ return adHocChatRoom;
+ }
+
+ /**
+ * Returns the name of the invitee that rejected the invitation.
+ *
+ * @return the name of the invitee that rejected the invitation
+ */
+ public String getInvitee()
+ {
+ return invitee;
+ }
+
+ /**
+ * Returns the reason for which the<tt>AdHocChatRoomInvitation</tt> is
+ * rejected.
+ *
+ * @return the reason for which the<tt>AdHocChatRoomInvitation</tt> is
+ * rejected.
+ */
+ public String getReason()
+ {
+ return reason;
+ }
+
+ /**
+ * A timestamp indicating the exact date when the event occurred.
+ * @return a Date indicating when the event occurred.
+ */
+ public Date getTimestamp()
+ {
+ return timestamp;
+ }
+}

Added: trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationRejectionListener.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationRejectionListener.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationRejectionListener.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,26 @@
+/*
+ * 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.service.protocol.event;
+
+/**
+ * A listener that dispatches events notifying that an invitation which was
+ * sent earlier has been rejected by the invitee.
+ *
+ * @author Valentin Martinet
+ */
+public interface AdHocChatRoomInvitationRejectionListener
+{
+ /**
+ * Called when an invitee rejects an invitation previously sent by us.
+ *
+ * @param evt the instance of the<tt>AdHocChatRoomInvitationRejectedEvent
+ *</tt>
+ * containing the rejected ad-hoc chat room invitation as well as the source
+ * provider where this happened.
+ */
+ public void invitationRejected(AdHocChatRoomInvitationRejectedEvent evt);
+}

Added: trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomListener.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomListener.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomListener.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,29 @@
+/*
+ * 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.service.protocol.event;
+
+/**
+ * A listener which dispatches events notifying ad-hoc chat rooms who have been
+ * created, joined and destroyed.
+ *
+ * @author Valentin Martinet
+ */
+public interface AdHocChatRoomListener
+{
+ /**
+ * Called when we receive an<tt>AdHocChatRoomCreatedEvent</tt>.
+ *
+ * @param evt the<tt>AdHocChatRoomCreatedEvent</tt>
+ */
+ public void adHocChatRoomCreated(AdHocChatRoomCreatedEvent evt);
+
+ /**
+ * Called when we receive an<tt>AdHocChatRoomDestroyedEvent</>.
+ *
+ * @param evt the<tt>AdHocChatRoomDestroyedEvent</tt>
+ */
+ public void adHocChatRoomDestroyed(AdHocChatRoomDestroyedEvent evt);
+}

Added: trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageDeliveredEvent.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageDeliveredEvent.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageDeliveredEvent.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,119 @@
+/*
+ * 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.service.protocol.event;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ *<tt>MessageDeliveredEvent</tt>s confirm successful delivery of an instant
+ * message. Here, it's applied to an<tt>AdHocChatRoom</tt>.
+ *
+ * @author Valentin Martinet
+ */
+@SuppressWarnings("serial")
+public class AdHocChatRoomMessageDeliveredEvent
+ extends EventObject
+{
+ /**
+ * An event type indicating that the message being received is a standard
+ * conversation message sent by another participant of the ad-hoc chat room
+ * to all current participants.
+ */
+ public static final int CONVERSATION_MESSAGE_DELIVERED = 1;
+
+ /**
+ * An event type indicating that the message being received is a special
+ * message that sent by either another participant or the server itself,
+ * indicating that some kind of action (other than the delivery of a
+ * conversation message) has occurred. Action messages are widely used
+ * in IRC through the /action and /me commands
+ */
+ public static final int ACTION_MESSAGE_DELIVERED = 2;
+
+ /**
+ * A timestamp indicating the exact date when the event occurred.
+ */
+ private final long timestamp;
+
+ /**
+ * The received<tt>Message</tt>.
+ */
+ private Message message = null;
+
+ /**
+ * The type of message event that this instance represents.
+ */
+ private int eventType = -1;
+
+ /**
+ * Creates a<tt>MessageDeliveredEvent</tt> representing delivery of the
+ *<tt>source</tt> message to the specified<tt>to</tt> contact.
+ *
+ * @param source the<tt>AdHocChatRoom</tt> which triggered this event.
+ * @param timestamp a date indicating the exact moment when the event
+ * occurred
+ * @param message the message that triggered this event.
+ * @param eventType indicating the type of the delivered event. It's
+ * either an ACTION_MESSAGE_DELIVERED or a CONVERSATION_MESSAGE_DELIVERED.
+ */
+ public AdHocChatRoomMessageDeliveredEvent( AdHocChatRoom source,
+ long timestamp,
+ Message message,
+ int eventType)
+ {
+ super(source);
+
+ this.timestamp = timestamp;
+ this.message = message;
+ this.eventType = eventType;
+ }
+
+ /**
+ * Returns the received message.
+ *
+ * @return the<tt>Message</tt> that triggered this event.
+ */
+ public Message getMessage()
+ {
+ return this.message;
+ }
+
+ /**
+ * A timestamp indicating the exact date when the event occurred.
+ *
+ * @return a Date indicating when the event occurred.
+ */
+ public long getTimestamp()
+ {
+ return this.timestamp;
+ }
+
+ /**
+ * Returns the<tt>AdHocChatRoom</tt> that triggered this event.
+ *
+ * @return the<tt>AdHocChatRoom</tt> that triggered this event.
+ */
+ public AdHocChatRoom getSourceAdHocChatRoom()
+ {
+ return (AdHocChatRoom) this.getSource();
+ }
+
+ /**
+ * Returns the type of message event represented by this event instance.
+ * Message event type is one of the XXX_MESSAGE_DELIVERED fields of this
+ * class.
+ *
+ * @return one of the XXX_MESSAGE_DELIVERED fields of this
+ * class indicating the type of this event.
+ */
+ public int getEventType()
+ {
+ return this.eventType;
+ }
+}

Added: trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageDeliveryFailedEvent.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageDeliveryFailedEvent.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageDeliveryFailedEvent.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,149 @@
+/*
+ * 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.service.protocol.event;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ *<tt>AdHocChatRoomMessageDeliveredEvent</tt>s confirm successful delivery of
+ * an instant message.
+ *
+ * @author Valentin Martinet
+ */
+@SuppressWarnings("serial")
+public class AdHocChatRoomMessageDeliveryFailedEvent
+ extends EventObject
+{
+ /**
+ * The ad-hoc chat room participant that this message has been sent to.
+ */
+ private Contact to = null;
+
+ /**
+ * Set when no other error code can describe the exception that occurred.
+ */
+ public static final int UNKNOWN_ERROR = 1;
+
+ /**
+ * Set when delivery fails due to a failure in network communications or
+ * a transport error.
+ */
+ public static final int NETWORK_FAILURE = 2;
+
+ /**
+ * Set to indicate that delivery has failed because the provider was not
+ * registered.
+ */
+ public static final int PROVIDER_NOT_REGISTERED = 3;
+
+ /**
+ * Set when delivery fails for implementation specific reasons.
+ */
+ public static final int INTERNAL_ERROR = 4;
+
+ /**
+ * Set when delivery fails because we're trying to send a message to a
+ * contact that is currently offline and the server does not support
+ * offline messages.
+ */
+ public static final int OFFLINE_MESSAGES_NOT_SUPPORTED = 5;
+
+ /**
+ * An error code indicating the reason for the failure of this delivery.
+ */
+ private int errorCode = UNKNOWN_ERROR;
+
+ /**
+ * A timestamp indicating the exact date when the event occurred.
+ */
+ private Date timestamp = null;
+
+ /**
+ * The received<tt>Message</tt>.
+ */
+ private Message message = null;
+
+ /**
+ * Creates an<tt>AdHocChatRoomMessageDeliveryFailedEvent</> indicating
+ * failure of delivery of the<tt>source</tt> message to the specified
+ *<tt>to</tt> contact.
+ *
+ * @param source the<tt>Message</tt> whose delivery this event represents.
+ * @param to the<tt>Contact</tt> that this message was sent to.
+ * @param errorCode an errorCode indicating the reason of the failure.
+ * @param timestamp the exact Date when it was determined that delivery
+ * had failed.
+ * @param message the received<tt>Message</tt>.
+ */
+ public AdHocChatRoomMessageDeliveryFailedEvent(AdHocChatRoom source,
+ Contact to,
+ int errorCode,
+ Date timestamp,
+ Message message)
+ {
+ super(source);
+
+ this.to = to;
+ this.errorCode = errorCode;
+ this.timestamp = timestamp;
+ this.message = message;
+ }
+ /**
+ * Returns a reference to the<tt>Contact</tt> that the source
+ * (failed)<tt>Message</tt> was sent to.
+ *
+ * @return a reference to the<tt>Contact</tt> that the source failed
+ *<tt>Message</tt> was sent to.
+ */
+ public Contact getDestinationParticipant()
+ {
+ return to;
+ }
+
+ /**
+ * Returns the received message.
+ * @return the<tt>Message</tt> that triggered this event.
+ */
+ public Message getMessage()
+ {
+ return message;
+ }
+
+ /**
+ * Returns an error code descibing the reason for the failure of the
+ * message delivery.
+ * @return an error code descibing the reason for the failure of the
+ * message delivery.
+ */
+ public int getErrorCode()
+ {
+ return errorCode;
+ }
+
+ /**
+ * A timestamp indicating the exact date when the event ocurred (in this
+ * case it is the moment when it was determined that message delivery
+ * has failed).
+ * @return a Date indicating when the event ocurred.
+ */
+ public Date getTimestamp()
+ {
+ return timestamp;
+ }
+
+ /**
+ * Returns the<tt>AdHocChatRoom</tt> that triggered this event.
+ * @return the<tt>AdHocChatRoom</tt> that triggered this event.
+ */
+ public AdHocChatRoom getSourceChatRoom()
+ {
+ return (AdHocChatRoom) getSource();
+ }
+}

Added: trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageListener.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageListener.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageListener.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,46 @@
+/*
+ * 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.service.protocol.event;
+
+import java.util.*;
+
+/**
+ * A listener that registers for<tt>AdHocChatRoomMessageEvent</>s issued by a
+ * particular<tt>AdHocChatRoom</tt>.
+ *
+ * @author Valentin Martinet
+ */
+public interface AdHocChatRoomMessageListener
+ extends EventListener
+{
+ /**
+ * Called when a new incoming<tt>Message</tt> has been received.
+ * @param evt the<tt>AdHocChatRoomMessageReceivedEvent</tt> containing the
+ * newly received message, its sender and other details.
+ */
+ public void messageReceived(AdHocChatRoomMessageReceivedEvent evt);
+
+ /**
+ * Called when the underlying implementation has received an indication
+ * that a message, sent earlier has been successfully received by the
+ * destination.
+ * @param evt the<tt>AdHocChatRoomMessageDeliveredEvent</tt> containing the
+ * id of the message that has caused the event.
+ */
+ public void messageDelivered(AdHocChatRoomMessageDeliveredEvent evt);
+
+ /**
+ * Called to indicate that delivery of a message sent earlier to the chat
+ * room has failed. Reason code and phrase are contained by the
+ *<tt>MessageFailedEvent</tt>
+ * @param evt the<tt>AdHocChatroomMessageDeliveryFailedEvent</>
+ * containing the ID of the message whose delivery has failed.
+ */
+ public void messageDeliveryFailed(
+ AdHocChatRoomMessageDeliveryFailedEvent evt);
+}

Added: trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageReceivedEvent.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageReceivedEvent.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageReceivedEvent.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,144 @@
+/*
+ * 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.service.protocol.event;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ *<tt>MessageReceivedEvent</tt>s indicate reception of an instant message.
+ * (for an ad-hoc chat room; see<tt>AdHocChatRoom</tt>)
+ *
+ * @author Valentin Martinet
+ */
+@SuppressWarnings("serial")
+public class AdHocChatRoomMessageReceivedEvent
+ extends EventObject
+{
+ /**
+ * An event type indicating that the message being received is a standard
+ * conversation message sent by another member of the chatroom to all
+ * current participants.
+ */
+ public static final int CONVERSATION_MESSAGE_RECEIVED = 1;
+
+ /**
+ * An event type indicating that the message being received is a special
+ * message that sent by either another member or the server itself,
+ * indicating that some kind of action (other than the delivery of a
+ * conversation message) has occurred. Action messages are widely used
+ * in IRC through the /action and /me commands
+ */
+ public static final int ACTION_MESSAGE_RECEIVED = 2;
+
+ /**
+ * An event type indicting that the message being received is a system
+ * message being sent by the server or a system administrator, possibly
+ * notifying us of something important such as ongoing maintenance
+ * activities or server downtime.
+ */
+ public static final int SYSTEM_MESSAGE_RECEIVED = 3;
+
+ /**
+ * The ccontact that has sent this message.
+ */
+ private final Contact from;
+
+ /**
+ * A timestamp indicating the exact date when the event occurred.
+ */
+ private final long timestamp;
+
+ /**
+ * The received<tt>Message</tt>.
+ */
+ private final Message message;
+
+ /**
+ * The type of message event that this instance represents.
+ */
+ private final int eventType;
+
+ /**
+ * Creates a<tt>MessageReceivedEvent</tt> representing reception of the
+ *<tt>source</tt> message received from the specified<tt>from</tt>
+ * contact.
+ *
+ * @param source the<tt>AdHocChatRoom</tt> for which the message is
+ * received.
+ * @param from the<tt>Contact</tt> that has sent this message.
+ * @param timestamp the exact date when the event occurred.
+ * @param message the received<tt>Message</tt>.
+ * @param eventType the type of message event that this instance represents
+ * (one of the XXX_MESSAGE_RECEIVED static fields).
+ */
+ public AdHocChatRoomMessageReceivedEvent(AdHocChatRoom source,
+ Contact from,
+ long timestamp,
+ Message message,
+ int eventType)
+ {
+ super(source);
+
+ this.from = from;
+ this.timestamp = timestamp;
+ this.message = message;
+ this.eventType = eventType;
+ }
+
+ /**
+ * Returns a reference to the<tt>Contact</tt> that has send the
+ *<tt>Message</tt> whose reception this event represents.
+ *
+ * @return a reference to the<tt>Contact</tt> that has send the
+ *<tt>Message</tt> whose reception this event represents.
+ */
+ public Contact getSourceChatRoomParticipant()
+ {
+ return from;
+ }
+
+ /**
+ * Returns the received message.
+ * @return the<tt>Message</tt> that triggered this event.
+ */
+ public Message getMessage()
+ {
+ return message;
+ }
+
+ /**
+ * A timestamp indicating the exact date when the event occurred.
+ * @return a Date indicating when the event occurred.
+ */
+ public long getTimestamp()
+ {
+ return timestamp;
+ }
+
+ /**
+ * Returns the<tt>AdHocChatRoom</tt> that triggered this event.
+ * @return the<tt>AdHocChatRoom</tt> that triggered this event.
+ */
+ public AdHocChatRoom getSourceChatRoom()
+ {
+ return (AdHocChatRoom) getSource();
+ }
+
+ /**
+ * Returns the type of message event represented by this event instance.
+ * Message event type is one of the XXX_MESSAGE_RECEIVED fields of this
+ * class.
+ * @return one of the XXX_MESSAGE_RECEIVED fields of this
+ * class indicating the type of this event.
+ */
+ public int getEventType()
+ {
+ return eventType;
+ }
+}

Added: trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomParticipantPresenceChangeEvent.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomParticipantPresenceChangeEvent.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomParticipantPresenceChangeEvent.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,157 @@
+/*
+ * 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.service.protocol.event;
+
+import java.util.*;
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * Dispatched to notify interested parties that a change in the presence of an
+ * ad-hoc chat room participant has occurred. Changes may include the
+ * participant being join, left...
+ *
+ * @author Valentin Martinet
+ */
+@SuppressWarnings("serial")
+public class AdHocChatRoomParticipantPresenceChangeEvent
+ extends EventObject
+{
+ /**
+ * Indicates that this event was triggered as a result of the participant
+ * joining the source ad-hoc chat room.
+ */
+ public static final String CONTACT_JOINED = "ContactJoined";
+
+ /**
+ * Indicates that this event was triggered as a result of the participant
+ * leaving the source ad-hoc chat room.
+ */
+ public static final String CONTACT_LEFT = "ContactLeft";
+
+ /**
+ * Indicates that this event was triggered as a result of the participant
+ * being disconnected from the server brutally, or due to a ping timeout.
+ */
+ public static final String CONTACT_QUIT = "ContactQuit";
+
+ /**
+ * The well-known reason for a
+ *<code>AdHocChatRoomParticipantPresenceChangeEvent</code> to occur as part
+ * of an operation which lists all users in an<code>AdHocChatRoom</code>.
+ */
+ public static final String REASON_USER_LIST = "ReasonUserList";
+
+ /**
+ * The ad-hoc chat room participant that the event relates to.
+ */
+ private final Contact sourceParticipant;
+
+ /**
+ * The type of this event. Values can be any of the CONTACT_XXX fields.
+ */
+ private final String eventType;
+
+ /**
+ * An optional String indicating a possible reason as to why the event
+ * might have occurred.
+ */
+ private final String reason;
+
+ /**
+ * Creates an<tt>AdHocChatRoomParticipantPresenceChangeEvent</>
+ * representing that a change in the presence of an<tt>Contact</tt>
+ * has occurred. Changes may include the participant being join, left, etc.
+ *
+ * @param sourceAdHocRoom the<tt>AdHocChatRoom</tt> that produced this
+ * event
+ * @param sourceParticipant the<tt>Contact</tt> that this event is about
+ * @param eventType the event type; one of the CONTACT_XXX constants
+ * @param reason the reason explaining why this event might have occurred
+ */
+ public AdHocChatRoomParticipantPresenceChangeEvent(
+ AdHocChatRoom sourceAdHocRoom,
+ Contact sourceParticipant,
+ String eventType,
+ String reason )
+ {
+ super(sourceAdHocRoom);
+ this.sourceParticipant = sourceParticipant;
+ this.eventType = eventType;
+ this.reason = reason;
+ }
+
+ /**
+ * Returns the ad-hoc chat room that produced this event.
+ *
+ * @return the<tt>AdHocChatRoom</tt> that produced this event
+ */
+ public AdHocChatRoom getAdHocChatRoom()
+ {
+ return (AdHocChatRoom)getSource();
+ }
+
+ /**
+ * Returns the participant that this event is about.
+ *
+ * @return the<tt>Contact</tt> that this event is about.
+ */
+ public Contact getParticipant()
+ {
+ return this.sourceParticipant;
+ }
+
+ /**
+ * A reason String indicating a human readable reason for this event.
+ *
+ * @return a human readable String containing the reason for this event,
+ * or null if no particular reason was specified.
+ */
+ public String getReason()
+ {
+ return this.reason;
+ }
+
+ /**
+ * Gets the indicator which determines whether this event has occurred with
+ * the well-known reason of listing all users in a<code>ChatRoom</code>.
+ *
+ * @return<tt>true</tt> if this event has occurred with the well-known
+ * reason of listing all users in a<code>ChatRoom</code> i.e.
+ * {@link #getReason()} returns a value of {@link #REASON_USER_LIST};
+ * otherwise,<tt>false</tt>
+ */
+ public boolean isReasonUserList()
+ {
+ return REASON_USER_LIST.equals(getReason());
+ }
+
+ /**
+ * Returns the type of this event which could be one of the MEMBER_XXX
+ * member field values.
+ *
+ * @return one of the MEMBER_XXX member field values indicating the type
+ * of this event.
+ */
+ public String getEventType()
+ {
+ return eventType;
+ }
+
+ /**
+ * Returns a String representation of this event.
+ */
+ public String toString()
+ {
+ return "AdHocChatRoomParticipantPresenceChangeEvent[type="
+ + getEventType()
+ + " sourceAdHocRoom="
+ + getAdHocChatRoom().toString()
+ + " member="
+ + getParticipant().toString()
+ + "]";
+ }
+}

Added: trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomParticipantPresenceListener.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomParticipantPresenceListener.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomParticipantPresenceListener.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,32 @@
+/*
+ * 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.service.protocol.event;
+
+import java.util.*;
+
+/**
+ * A listener that will be notified of changes in the presence of a participant
+ * in a particular ad-hoc chat room. Changes may include member being join,
+ * left, etc.
+ *
+ * @author Valentin Martinet
+ */
+public interface AdHocChatRoomParticipantPresenceListener
+ extends EventListener
+{
+ /**
+ * Called to notify interested parties that a change in the presence of a
+ * participant in a particular ad-hoc chat room has occurred. Changes may
+ * include participant being join, left.
+ *
+ * @param evt the<tt>AdHocChatRoomParticipantPresenceChangeEvent</tt>
+ * instance containing the source chat room and type, and reason of the
+ * presence change
+ */
+ public void participantPresenceChanged(
+ AdHocChatRoomParticipantPresenceChangeEvent evt);
+}
\ No newline at end of file

Added: trunk/src/net/java/sip/communicator/service/protocol/event/LocalUserAdHocChatRoomPresenceChangeEvent.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/event/LocalUserAdHocChatRoomPresenceChangeEvent.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/event/LocalUserAdHocChatRoomPresenceChangeEvent.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,145 @@
+/*
+ * 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.service.protocol.event;
+
+import java.util.*;
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * Dispatched to notify interested parties that a change in our presence in
+ * the source ad-hoc chat room has occurred. Changes may include us being join,
+ * left, etc.
+ *
+ * @author Valentin Martinet
+ */
+@SuppressWarnings("serial")
+public class LocalUserAdHocChatRoomPresenceChangeEvent
+ extends EventObject
+{
+ /**
+ * Indicates that this event was triggered as a result of the local
+ * participant joining an ad-hoc chat room.
+ */
+ public static final String LOCAL_USER_JOINED = "LocalUserJoined";
+
+ /**
+ * Indicates that this event was triggered as a result of the local
+ * participant failed to join an ad-hoc chat room.
+ */
+ public static final String LOCAL_USER_JOIN_FAILED = "LocalUserJoinFailed";
+
+ /**
+ * Indicates that this event was triggered as a result of the local
+ * participant leaving an ad-hoc chat room.
+ */
+ public static final String LOCAL_USER_LEFT = "LocalUserLeft";
+
+ /**
+ * Indicates that this event was triggered as a result of the local
+ * participant being disconnected from the server brutally, or ping timeout.
+ */
+ public static final String LOCAL_USER_DROPPED = "LocalUserDropped";
+
+ /**
+ * The<tt>AdHocChatRoom</tt> to which the change is related.
+ */
+ private AdHocChatRoom adHocChatRoom = null;
+
+ /**
+ * The type of this event.
+ */
+ private String eventType = null;
+
+ /**
+ * An optional String indicating a possible reason as to why the event
+ * might have occurred.
+ */
+ private String reason = null;
+
+ /**
+ * Creates an<tt>AdHocChatRoomLocalUserPresenceChangeEvent</tt>
+ * representing that a change in local participant presence in the source
+ * ad-hoc chat room has occurred.
+ *
+ * @param _source the<tt>OperationSetAdHocMultiUserChat</tt>, which
+ * produced this event
+ * @param _adHocChatRoom the<tt>AdHocChatRoom</tt> that this event is about
+ * @param _eventType the type of this event.
+ * @param _reason the reason explaining why this event might have occurred
+ */
+ public LocalUserAdHocChatRoomPresenceChangeEvent(
+ OperationSetAdHocMultiUserChat source,
+ AdHocChatRoom adHocChatRoom,
+ String eventType,
+ String reason)
+ {
+ super(source);
+
+ this.adHocChatRoom = adHocChatRoom;
+ this.eventType = eventType;
+ this.reason = reason;
+ }
+
+ /**
+ * Returns the<tt>OperationSetAdHocMultiUserChat</tt>, where this event has
+ * occurred.
+ *
+ * @return the<tt>OperationSetAdHocMultiUserChat</tt>, where this event has
+ * occurred
+ */
+ public OperationSetAdHocMultiUserChat getAdHocMultiUserChatOpSet()
+ {
+ return (OperationSetAdHocMultiUserChat) getSource();
+ }
+
+ /**
+ * Returns the<tt>AdHocChatRoom</tt>, that this event is about.
+ *
+ * @return the<tt>AdHocChatRoom</tt>, that this event is about
+ */
+ public AdHocChatRoom getAdHocChatRoom()
+ {
+ return this.adHocChatRoom;
+ }
+
+ /**
+ * A reason string indicating a human readable reason for this event.
+ *
+ * @return a human readable String containing the reason for this event,
+ * or null if no particular reason was specified
+ */
+ public String getReason()
+ {
+ return this.reason;
+ }
+
+ /**
+ * Returns the type of this event which could be one of the LOCAL_USER_XXX
+ * member fields.
+ *
+ * @return one of the LOCAL_USER_XXX fields indicating the type of this
+ * event.
+ */
+ public String getEventType()
+ {
+ return this.eventType;
+ }
+
+ /**
+ * Returns a String representation of this event.
+ *
+ * @return a<tt>String</tt> for representing this event.
+ */
+ public String toString()
+ {
+ return "AdHocChatRoomLocalUserPresenceChangeEvent[type="
+ + getEventType()
+ + " \nsourceAdHocRoom="
+ + getAdHocChatRoom().toString()
+ + "]";
+ }
+}

Added: trunk/src/net/java/sip/communicator/service/protocol/event/LocalUserAdHocChatRoomPresenceListener.java
Url: https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/service/protocol/event/LocalUserAdHocChatRoomPresenceListener.java?view=auto&rev=5964

--- (empty file)
+++ trunk/src/net/java/sip/communicator/service/protocol/event/LocalUserAdHocChatRoomPresenceListener.java 2009-09-14 15:51:47+0000
@@ -0,0 +1,30 @@
+ /*
+ * 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.service.protocol.event;
+
+import java.util.*;
+
+/**
+ * A listener that will be notified of changes in our presence in the chat
+ * room such as us being kicked, join, left.
+ *
+ * @author Valentin Martinet
+ */
+public interface LocalUserAdHocChatRoomPresenceListener
+ extends EventListener
+{
+ /**
+ * Called to notify interested parties that a change in our presence in
+ * an ad-hoc chat room has occurred. Changes may include us being join,
+ * left.
+ * @param _evt the<tt>LocalUserAdHocChatRoomPresenceChangeEvent</tt>
+ * instance containing the ad-hoc chat room and the type, and reason of the
+ * change
+ */
+ public void localUserAdHocPresenceChanged(
+ LocalUserAdHocChatRoomPresenceChangeEvent evt);
+}

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@sip-communicator.dev.java.net
For additional commands, e-mail: dev-help@sip-communicator.dev.java.net

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@sip-communicator.dev.java.net
For additional commands, e-mail: dev-help@sip-communicator.dev.java.net


#3

Hello again,

I couldn't shake the feeling of deja vu when I was reading the new code. I think a noticeable deal of the ad-hoc work involved the tedious task of taking exising ChatRoom-related code and prefixing it with AdHoc (obviously, I'm exaggerating here). But let's start from the beginning.

So there is ChatRoom and there is AdHocChatRoom. These are distinct interfaces so one would think that they describe very different things. Actually, just going by their names I'd think AdHocChatRoom is a ChatRoom but this is such a quick and basic reaction that I'm not surprised that it may be wrong. Looking at the interface methods though, it seems that these two both have getIdentifier(), getName(), getParentProvider(), add/removeMessageListener and, most importantly, join(), invite(String userAddress, String reason), createMessage(String), sendMessage(Message). So I guess these two distinct names don't describe such different things but rather chat rooms which one can join, invite other people in and send messages to the people in the room.

Of course, when these interfaces are different, they have their own different followers such as numerous listener and event types. I still don't understand why there are MessageReceivedEvent, ChatRoomMessageReceivedEvent and AdHocChatRoomMessageReceivedEvent which share no common super as if mesasge receipt isn't the common subject of them all.

The separation appears to feel unnatural also to the UI which tries to unite the two back to one. Try comparing ConferenceChatTransport to AdHocConferenceChatTransport, ChatRoomProviderWrapper to AdHocChatRoomProviderWrapper, ChatRoomList to AdHocChatRoomList.

Anyway, I'm not very clear on the distinction of the real-world chat rooms and ad-hoc chat rooms so I accept that I may be wildly wrong.

There is also a continuation of another repetition. There are 13 methods in AdHocChatRoom and there are 3 implementations of that interface yet these 3 implementations have no common super. As if add/removeMessageListener, add/removeParticipantPresenceListener and their associated event firing methods will be different... In fact the duplication in these implementations is much more than these specific methods. As is the duplication in the 3 implementations of OperationSetAdHocMultiUserChat.

Best regards,
Lubomir

···

On 15.09.2009 12:28, Yana Stamcheva wrote:

Hi Lubo,

You're absolutely right. Thanks for taking care of this!

Cheers,
Yana

On Sep 15, 2009, at 10:26 AM, Lubomir Marinov wrote:

Hello Valentin and Yana,

Congratulations on the great work! I do mean not only the large amount
of code written but also the continuous dedication which was expressed
on this mailing list in the respective thread. You rock!

I hope you will not mind me sharing a few observations while reviewing
r5964.

I still haven't finished the review so I'll just start with
ChatAlerterActivator and its new method
#messageReceived(AdHocChatRoomMessageReceivedEvent). The problem is
that the implementation of this method is anything but new. This same
implementation was already found in two separate methods in this same
class and I replaced the duplication with #alertChatWindow(). I
imagine the copy was made while there was still a duplication in trunk
(which turns out to be called triplication) but it's still not a
reason to do it. Please note that having three methods that do one and
the same thing makes a class larger than necessary, hinders
maintenance because changes to it has to be performed multiple times
(you may notice that I've spared two null checks in
#alertChatWindow()) and, most importantly, each of them needs to pass
the JIT compiler invocation threshold before the decision is taken for
them to be compiled into native code (in contrast replacing these
three methods with #alertChatWindow() provides an optimization for all
three regardless of which one is called the most often).

Best regards,
Lubomir

On 14.09.2009 18:51, yanas@dev.java.net wrote:

Author: yanas
Date: 2009-09-14 15:51:47+0000
New Revision: 5964

Added:
trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocChatRoomProviderWrapper.java

trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocChatRoomWrapper.java

trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocConferenceChatContact.java

trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocConferenceChatSession.java

trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/AdHocConferenceChatTransport.java

trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/AdHocChatRoomList.java

trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/AdHocChatRoomListChangeEvent.java

trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/AdHocChatRoomListChangeListener.java

trunk/src/net/java/sip/communicator/impl/protocol/icq/AdHocChatRoomIcqImpl.java

trunk/src/net/java/sip/communicator/impl/protocol/icq/AdHocChatRoomInvitationIcqImpl.java

trunk/src/net/java/sip/communicator/impl/protocol/icq/OperationSetAdHocMultiUserChatIcqImpl.java

trunk/src/net/java/sip/communicator/impl/protocol/msn/AdHocChatRoomInvitationMsnImpl.java
(contents, props changed)
- copied, changed from r5898,
/trunk/src/net/java/sip/communicator/impl/protocol/msn/ChatRoomInvitationMsnImpl.java

trunk/src/net/java/sip/communicator/impl/protocol/msn/AdHocChatRoomMsnImpl.java

trunk/src/net/java/sip/communicator/impl/protocol/msn/OperationSetAdHocMultiUserChatMsnImpl.java

trunk/src/net/java/sip/communicator/impl/protocol/yahoo/AdHocChatRoomInvitationYahooImpl.java

trunk/src/net/java/sip/communicator/impl/protocol/yahoo/AdHocChatRoomYahooImpl.java

trunk/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetAdHocMultiUserChatYahooImpl.java

trunk/src/net/java/sip/communicator/service/protocol/AdHocChatRoom.java
trunk/src/net/java/sip/communicator/service/protocol/AdHocChatRoomInvitation.java

trunk/src/net/java/sip/communicator/service/protocol/OperationSetAdHocMultiUserChat.java

trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomCreatedEvent.java

trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomDestroyedEvent.java

trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationListener.java

trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationReceivedEvent.java

trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationRejectedEvent.java

trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomInvitationRejectionListener.java

trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomListener.java

trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageDeliveredEvent.java

trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageDeliveryFailedEvent.java

trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageListener.java

trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomMessageReceivedEvent.java

trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomParticipantPresenceChangeEvent.java

trunk/src/net/java/sip/communicator/service/protocol/event/AdHocChatRoomParticipantPresenceListener.java

trunk/src/net/java/sip/communicator/service/protocol/event/LocalUserAdHocChatRoomPresenceChangeEvent.java

trunk/src/net/java/sip/communicator/service/protocol/event/LocalUserAdHocChatRoomPresenceListener.java

Removed:
trunk/src/net/java/sip/communicator/impl/protocol/icq/ChatRoomIcqImpl.java

trunk/src/net/java/sip/communicator/impl/protocol/icq/ChatRoomInvitationIcqImpl.java

trunk/src/net/java/sip/communicator/impl/protocol/icq/ChatRoomMemberIcqImpl.java

trunk/src/net/java/sip/communicator/impl/protocol/icq/OperationSetMultiUserChatIcqImpl.java

trunk/src/net/java/sip/communicator/impl/protocol/msn/ChatRoomInvitationMsnImpl.java

trunk/src/net/java/sip/communicator/impl/protocol/msn/ChatRoomMemberMsnImpl.java

trunk/src/net/java/sip/communicator/impl/protocol/msn/ChatRoomMsnImpl.java

trunk/src/net/java/sip/communicator/impl/protocol/msn/OperationSetMultiUserChatMsnImpl.java

trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ChatRoomInvitationYahooImpl.java

trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ChatRoomMemberYahooImpl.java

trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ChatRoomYahooImpl.java

trunk/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetMultiUserChatYahooImpl.java

Modified:
trunk/src/net/java/sip/communicator/impl/gui/main/MainFrame.java
trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java
trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindow.java
trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindowManager.java

trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatContact.java

trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatManager.java

trunk/src/net/java/sip/communicator/impl/gui/main/chat/conference/InvitationReceivedDialog.java

trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomList.java

trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/ChatRoomListUI.java

trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/createforms/CreateChatRoomDialog.java

trunk/src/net/java/sip/communicator/impl/gui/main/chatroomslist/createforms/CreateChatRoomWizard.java

trunk/src/net/java/sip/communicator/impl/gui/main/login/LoginManager.java

trunk/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java

trunk/src/net/java/sip/communicator/impl/protocol/facebook/FacebookUser.java

trunk/src/net/java/sip/communicator/impl/protocol/icq/ProtocolProviderServiceIcqImpl.java

trunk/src/net/java/sip/communicator/impl/protocol/msn/OperationSetBasicInstantMessagingMsnImpl.java

trunk/src/net/java/sip/communicator/impl/protocol/msn/ProtocolProviderServiceMsnImpl.java

trunk/src/net/java/sip/communicator/impl/protocol/sip/SipLogger.java
trunk/src/net/java/sip/communicator/impl/protocol/yahoo/ProtocolProviderServiceYahooImpl.java

trunk/src/net/java/sip/communicator/plugin/chatalerter/ChatAlerterActivator.java

trunk/src/net/java/sip/communicator/plugin/contactinfo/resources/personPhoto.png

trunk/src/net/java/sip/communicator/plugin/contactinfo/resources/userInfo16x16.png

trunk/src/net/java/sip/communicator/plugin/facebookaccregwizz/FacebookAccountRegistrationWizard.java

trunk/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java

Log:
Ongoing work on issue #725 ( Sepperate operation set for ad-hoc like
chat rooms (Msn, Icq, Yahoo)) provided by Valentin Martinet.
Introduces all the interfaces needed to represent an ad-hoc chat room
and the corresponding implementations for Msn, Yahoo and Icq.

Also turns some tabs to spaces in the facebookaccregwizz and
chatalerter plugins.

Modified:
trunk/src/net/java/sip/communicator/impl/gui/main/MainFrame.java
Url:
https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/MainFrame.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/gui/main/MainFrame.java&p2=trunk/src/net/java/sip/communicator/impl/gui/main/MainFrame.java&r1=5963&r2=5964

==============================================================================

--- trunk/src/net/java/sip/communicator/impl/gui/main/MainFrame.java
(original)
+++ trunk/src/net/java/sip/communicator/impl/gui/main/MainFrame.java
2009-09-14 15:51:47+0000
@@ -386,6 +386,21 @@
multiUserChat.addPresenceListener(conferenceManager);
}

+ // Obtain the ad-hoc multi user chat operation set.
+ OperationSetAdHocMultiUserChat adHocMultiChatOpSet =
+ (OperationSetAdHocMultiUserChat) protocolProvider
+ .getOperationSet(OperationSetAdHocMultiUserChat.class);
+
+ if (adHocMultiChatOpSet != null)
+ {
+ ConferenceChatManager conferenceManager
+ = GuiActivator.getUIService().getConferenceChatManager();
+
+ adHocMultiChatOpSet.addInvitationListener(conferenceManager);
+ adHocMultiChatOpSet.addInvitationRejectionListener(conferenceManager);
+ adHocMultiChatOpSet.addPresenceListener(conferenceManager);
+ }
+
// Obtain file transfer operation set.
OperationSetFileTransfer fileTransferOpSet
= (OperationSetFileTransfer) protocolProvider
@@ -586,6 +601,26 @@
*
* @param protocolProvider The protocol provider for which the multi user
* chat operation set is about.
+ * @return OperationSetAdHocMultiUserChat The telephony operation
+ * set for the given protocol provider.
+ */
+ public OperationSetAdHocMultiUserChat getAdHocMultiUserChatOpSet(
+ ProtocolProviderService protocolProvider)
+ {
+ OperationSet opSet
+ = protocolProvider.getOperationSet(
+ OperationSetAdHocMultiUserChat.class);
+
+ return (opSet instanceof OperationSetAdHocMultiUserChat)
+ ? (OperationSetAdHocMultiUserChat) opSet
+ : null;
+ }
+
+ /**
+ * Returns the multi user chat operation set for the given protocol
provider.
+ *
+ * @param protocolProvider The protocol provider for which the multi
user
+ * chat operation set is about.
* @return OperationSetMultiUserChat The telephony operation
* set for the given protocol provider.
*/

Modified:
trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java
Url:
https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java&p2=trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java&r1=5963&r2=5964

==============================================================================

---
trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java
(original)
+++
trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java
2009-09-14 15:51:47+0000
@@ -780,7 +780,8 @@
/**
* Pastes the content of the clipboard to the write area.
*/
- public void paste(){
+ public void paste()
+ {
JEditorPane editorPane = this.writeMessagePanel.getEditorPane();

editorPane.paste();
@@ -1808,11 +1809,18 @@
ChatTransport currentChatTransport
= chatSession.getCurrentChatTransport();

- if (currentChatTransport.getProtocolProvider()
- .getOperationSet(OperationSetMultiUserChat.class) != null)
+ ProtocolProviderService protocolProvider
+ = currentChatTransport.getProtocolProvider();
+
+ // We choose between OpSets for multi user chat...
+ if (protocolProvider.getOperationSet(
+ OperationSetMultiUserChat.class) != null
+ || protocolProvider.getOperationSet(
+ OperationSetAdHocMultiUserChat.class) != null)
{
return chatSession.getCurrentChatTransport();
}
+
else
{
Iterator<ChatTransport> chatTransportsIter
@@ -1838,7 +1846,7 @@
Collection<String> chatContacts,
String reason)
{
- ChatSession conferenceChatSession;
+ ChatSession conferenceChatSession = null;

if (chatSession instanceof MetaContactChatSession)
{
@@ -1849,14 +1857,31 @@
ConferenceChatManager conferenceChatManager
= GuiActivator.getUIService().getConferenceChatManager();

- ChatRoomWrapper chatRoomWrapper
- = conferenceChatManager.createChatRoom(newChatName,
- inviteChatTransport.getProtocolProvider());
+ // the chat session is set regarding to which OpSet is used for MUC
+ if(inviteChatTransport.getProtocolProvider().
+ getOperationSet(OperationSetMultiUserChat.class) != null)
+ {
+ ChatRoomWrapper chatRoomWrapper
+ = conferenceChatManager.createChatRoom(newChatName,
+ inviteChatTransport.getProtocolProvider(), chatContacts);

- conferenceChatSession
- = new ConferenceChatSession(this, chatRoomWrapper);
+ conferenceChatSession
+ = new ConferenceChatSession(this, chatRoomWrapper);
+ }
+ else if (inviteChatTransport.getProtocolProvider().
+ getOperationSet(OperationSetAdHocMultiUserChat.class) != null)
+ {
+ AdHocChatRoomWrapper chatRoomWrapper
+ = conferenceChatManager.createAdHocChatRoom(newChatName,
+ inviteChatTransport.getProtocolProvider(),
+ chatContacts);
+
+ conferenceChatSession
+ = new AdHocConferenceChatSession(this, chatRoomWrapper);
+ }

- this.setChatSession(conferenceChatSession);
+ if (conferenceChatSession != null)
+ this.setChatSession(conferenceChatSession);
}
// We're already in a conference chat.
else

Modified:
trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindow.java
Url:
https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindow.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindow.java&p2=trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindow.java&r1=5963&r2=5964

==============================================================================

---
trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindow.java (original)

+++
trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindow.java 2009-09-14
15:51:47+0000
@@ -460,7 +460,7 @@
mainToolBar.changeHistoryButtonsState(chatPanel);

chatPanel.requestFocusInWriteArea();
-
+
for (ChatChangeListener l : this.chatChangeListeners)
{
l.chatChanged(chatPanel);

Modified:
trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindowManager.java

Url:
https://sip-communicator.dev.java.net/source/browse/sip-communicator/trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindowManager.java?view=diff&rev=5964&p1=trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindowManager.java&p2=trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindowManager.java&r1=5963&r2=5964

==============================================================================

---
trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindowManager.java
(original)
+++
trunk/src/net/java/sip/communicator/impl/gui/main/chat/ChatWindowManager.java
2009-09-14 15:51:47+0000
@@ -23,6 +23,7 @@
* Manages chat windows and panels.
*
* @author Yana Stamcheva
+ * @author Valentin Martinet
*/
public class ChatWindowManager
{
@@ -123,6 +124,27 @@
&& getChat(chatSession).isShown());
}
+
+ /**
+ * Returns TRUE if there is an opened<tt>ChatPanel</tt> for the given
+ *<tt>AdHocChatRoom</tt>.
+ * @param chatRoomWrapper the<tt>AdHocChatRoomWrapper</tt>, for
which the
+ * ad-hoc chat is about
+ * @return TRUE if there is an opened<tt>ChatPanel</tt> for the given
+ *<tt>AdHocChatRoom</tt>
+ */
+ public boolean isChatOpenedForAdHocChatRoom(
+ AdHocChatRoomWrapper adHocChatRoomWrapper)
+ {
+ synchronized (syncChat)
+ {
+ ChatSession chatSession
+ = findChatSessionForDescriptor(adHocChatRoomWrapper);
+
+ return (chatSession != null
+&& getChat(chatSession).isShown());
+ }

/**
* Returns TRUE if there is an opened<tt>ChatPanel</tt> for the given
@@ -178,6 +200,43 @@
return false;
}
+
+ /**
+ * Returns TRUE if there is an opened<tt>ChatPanel</tt> for the given
+ *<tt>AdHocChatRoom</tt>.
+ *
+ * @param adHocChatRoom the<tt>AdHocChatRoom</tt>, for which the ad-hoc
+ * chat is about
+ * @return TRUE if there is an opened<tt>ChatPanel</tt> for the given
+ *<tt>AdHocChatRoom</tt>
+ */
+ public boolean isChatOpenedForAdHocChatRoom(AdHocChatRoom
adHocChatRoom)
+ {
+ synchronized (syncChat)
+ {
+ for (ChatPanel chatPanel : chatPanels)
+ {
+ ChatSession chatSession = chatPanel.getChatSession();
+
+ Object descriptor = chatSession.getDescriptor();
+
+ if(descriptor instanceof AdHocChatRoomWrapper)
+ {
+ AdHocChatRoomWrapper chatRoomWrapper
+ = (AdHocChatRoomWrapper) descriptor;
+
+ if(chatRoomWrapper.getAdHocChatRoomID()
+ .equals(adHocChatRoom.getIdentifier())
+&& getChat(chatSession).isShown())
+ {
+ return true;
+ }
+
+ return false;
+ }

/**
* Closes the given chat panel.
@@ -252,6 +311,11 @@
closeChatPanel(chatPanel);
}
+ else if (chatPanel.getChatSession() instanceof
+ AdHocConferenceChatSession)
+ {
+ // TODO: close the chat room before closing the window!!!
+ }
else
{
closeChatPanel(chatPanel);
@@ -476,7 +540,7 @@
synchronized (syncChat)
{
ChatSession chatSession
- = findChatSessionForDescriptor(chatRoomWrapper);
+ = findChatSessionForDescriptor(chatRoomWrapper);

if(chatSession != null)
{
@@ -484,8 +548,42 @@
}
else
return createChat(chatRoomWrapper);
+ }
+
+ /**
+ * Returns the chat panel corresponding to the given chat room wrapper.
+ *
+ * @param chatRoomWrapper the ad-hoc chat room wrapper,
corresponding to the
+ * ad-hoc chat room for which the chat panel is about
+ * @return the chat panel corresponding to the given chat room
+ */
+ public ChatPanel getAdHocMultiChat(AdHocChatRoomWrapper
chatRoomWrapper)
+ {
+ synchronized (syncChat)
+ {
+ ChatSession chatSession
+ = findChatSessionForDescriptor(chatRoomWrapper);
+
+ if(chatSession != null)
+ {
+ return getChat(chatSession);
}
+ else
+ return createChat(chatRoomWrapper);
}
+ }
+
+ /**
+ * Returns the chat panel corresponding to the given ad-hoc chat room.
+ *
+ * @param adHocChatRoom the chat room, for which the chat panel is
about
+ * @return the chat panel corresponding to the given ad-hoc chat room
+ */
+ public ChatPanel getAdHocMultiChat(AdHocChatRoom adHocChatRoom)
+ {
+ return getAdHocMultiChat(adHocChatRoom, null);
+ }

/**
* Returns the chat panel corresponding to the given chat room.
@@ -543,6 +641,51 @@
}

/**
+ * Returns the chat panel corresponding to the given ad-hoc chat room.
+ *
+ * @param chatRoom the ad-hoc chat room, for which the chat panel is
about
+ * @param escapedMessageID the message ID of the message that should be
+ * excluded from the history when the last one is loaded in the chat
+ * @return the chat panel corresponding to the given ad-hoc chat room
+ */
+ public ChatPanel getAdHocMultiChat( AdHocChatRoom chatRoom,
+ String escapedMessageID)
+ {
+ synchronized (syncChat)
+ {
+ AdHocChatRoomList chatRoomList = GuiActivator.getUIService()
+ .getConferenceChatManager().getAdHocChatRoomList();
+
+ // Search in the chat room's list for a chat room that correspond
+ // to the given one.
+ AdHocChatRoomWrapper chatRoomWrapper
+ = chatRoomList.findChatRoomWrapperFromAdHocChatRoom(chatRoom);
+
+ if (chatRoomWrapper == null)
+ {
+ AdHocChatRoomProviderWrapper parentProvider
+ = chatRoomList.findServerWrapperFromProvider(
+ chatRoom.getParentProvider());
+
+ chatRoomWrapper =
+ new AdHocChatRoomWrapper(parentProvider, chatRoom);
+
+ chatRoomList.addAdHocChatRoom(chatRoomWrapper);
+ }
+
+ ChatSession chatSession
+ = findChatSessionForDescriptor(chatRoomWrapper);
+
+ if (chatSession != null)
+ {
+ return getChat(chatSession);
+ }
+
+ return createChat(chatRoomWrapper, escapedMessageID);
+ }
+
+ /**
* Returns all open<code>ChatPanel</code>s.
*
* @return A list of<code>ChatPanel</code>s
@@ -710,10 +853,24 @@
* Creates a<tt>ChatPanel</tt> for the given<tt>ChatRoom</tt> and
saves it
* in the list of created<tt>ChatPanel</tt>s.
*
- * @param chatRoomWrapper the<tt>ChatRoom</tt>, for which the chat
will be created
+ * @param chatRoomWrapper the<tt>ChatRoom</tt>, for which the chat
will be
+ * created
+ * @return The<code>ChatPanel</code> newly created.
+ */
+ private ChatPanel createChat(ChatRoomWrapper chatRoomWrapper)
+ {
+ return createChat(chatRoomWrapper, null);
+ }
+
+ /**
+ * Creates a<tt>ChatPanel</tt> for the given<tt>AdHocChatRoom</tt> and
+ * saves it in the list of created<tt>ChatPanel</tt>s.
+ *
+ * @param chatRoomWrapper the<tt>AdHocChatRoom</tt>, for which the chat
+ * will be created
* @return The<code>ChatPanel</code> newly created.
*/
- private ChatPanel createChat( ChatRoomWrapper chatRoomWrapper)
+ private ChatPanel createChat(AdHocChatRoomWrapper chatRoomWrapper)
{
return createChat(chatRoomWrapper, null);
}
@@ -722,7 +879,8 @@
* Creates a<tt>ChatPanel</tt> for the given<tt>ChatRoom</tt> and
saves it
* in the list of created<tt>ChatPanel</tt>s.
*
- * @param chatRoomWrapper the<tt>ChatRoom</tt>, for which the chat
will be created
+ * @param chatRoomWrapper the<tt>ChatRoom</tt>, for which the chat
will be
+ * created
* @param escapedMessageID the message ID of the message that should be
* excluded from the history when the last one is loaded in the chat.
* @return The<code>ChatPanel</code> newly created.
@@ -780,6 +938,67 @@
}

/**
+ * Creates a<tt>ChatPanel</tt> for the given<tt>AdHocChatRoom</tt> and
+ * saves it in the list of created<tt>ChatPanel</tt>s.
+ *
+ * @param chatRoomWrapper the<tt>AdHocChatRoom</tt>, for which the chat
+ * will be created
+ * @param escapedMessageID the message ID of the message that should be
+ * excluded from the history when the last one is loaded in the chat.
+ * @return The<code>ChatPanel</code> newly created.
+ */
+ private ChatPanel createChat( AdHocChatRoomWrapper chatRoomWrapper,
+ String escapedMessageID)
+ {
+ ChatWindow chatWindow;
+
+ if(ConfigurationManager.isMultiChatWindowEnabled())
+ {
+ Iterator<ChatPanel> chatPanelsIter = chatPanels.iterator();
+
+ // If we're in a tabbed window we're looking for the chat window
+ // through one of the already created chats.
+ if(chatPanelsIter.hasNext())
+ {
+ chatWindow = chatPanelsIter.next().getChatWindow();
+ }
+ else
+ {
+ chatWindow = new ChatWindow();
+<