diff --git a/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java b/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java index b24388c4c..d78d271e6 100644 --- a/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java +++ b/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java @@ -33,7 +33,9 @@ public class MessageHistoryServiceImpl implements MessageHistoryService, MessageListener, - ServiceListener + ChatRoomMessageListener, + ServiceListener, + LocalUserChatRoomPresenceListener { /** * The logger for this class. @@ -213,7 +215,6 @@ public Collection findByPeriod(MetaContact contact, throws RuntimeException { return findByPeriod(contact, startDate, endDate, keywords, false); - } /** @@ -341,7 +342,6 @@ public Collection findFirstMessagesAfter(MetaContact contact, Date date, startIndex = 0; return resultAsList.subList(startIndex, resultAsList.size()); - } /** @@ -424,6 +424,71 @@ private History getHistory(Contact localContact, Contact remoteContact) return retVal; } + + /** + * Returns the history by specified local contact + * (if is null the default is used) + * and by the chat room + * + * @param room The chat room + * @return History the history - created if not existing + * @throws IOException + */ + private History getHistoryForMultiChat( + Contact localContact, + ChatRoom 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 + * (if is null the default is used) + * and by accountUniqueID, channel and server + * used by the multichat account. + * + * @param localContact Contact + * @param account The account UniqueID + * @param server the server used by the account + * @param channel the channel history we are searching for + * @return History the history - created if not existing + * @throws IOException + */ + private History getHistoryForMultiChat( + Contact localContact, + String account, + String server, + String channel) + throws IOException + { + History retVal = null; + + String localId = localContact == null ? "default" : localContact + .getAddress(); + + HistoryID historyId = HistoryID.createFromID( + new String[] { "messages", + localId, + account, + channel + "@" + server }); + + if (this.historyService.isHistoryExisting(historyId)) + { + retVal = this.historyService.getHistory(historyId); + } else { + retVal = this.historyService.createHistory(historyId, + recordStructure); + } + + return retVal; + } /** * Used to convert HistoryRecord in MessageDeliveredEvent or MessageReceivedEvent @@ -466,6 +531,56 @@ private Object convertHistoryRecordToMessageEvent(HistoryRecord hr, Contact cont contact, timestamp); } + + /** + * Used to convert HistoryRecord in ChatRoomMessageDeliveredEvent or + * ChatRoomMessageReceivedEvent + * which are returned by the finder methods + * + * @param hr HistoryRecord + * @param contact Contact + * @return Object + */ + private Object convertHistoryRecordToMessageEvent( + HistoryRecord hr, ChatRoom room) + { + MessageImpl msg = new MessageImpl(hr); + Date timestamp = null; + + // 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 + if(msg.getMessageReceivedDate() != null) + { + if(msg.getMessageReceivedDate().after(hr.getTimestamp()) && + (msg.getMessageReceivedDate().getTime() - + hr.getTimestamp().getTime()) > 86400000) // 24*60*60*1000 + timestamp = hr.getTimestamp(); + else + timestamp = msg.getMessageReceivedDate(); + } + else + timestamp = hr.getTimestamp(); + + // 5 is the index of the subject in the structure + String fromStr = hr.getPropertyValues()[5]; + + ChatRoomMember from = new ChatRoomMemberImpl(fromStr, room, null); + + if(msg.isOutgoing) + { + return new ChatRoomMessageDeliveredEvent( + room, + timestamp, + msg); + } + else + return new ChatRoomMessageReceivedEvent( + room, + from, + timestamp, + msg); + } /** * starts the service. Check the current registerd protocol providers @@ -571,13 +686,52 @@ public void messageDelivered(MessageDeliveredEvent evt) public void messageDeliveryFailed(MessageDeliveryFailedEvent evt) { } + + // ////////////////////////////////////////////////////////////////////////// + // ChatRoomMessageListener implementation methods + + public void messageReceived(ChatRoomMessageReceivedEvent evt) + { + try + { + History history = this.getHistoryForMultiChat( + null, + evt.getSourceChatRoom()); + + writeMessage(history, "in", evt.getSourceChatRoomMember(), + evt.getMessage(), evt.getTimestamp()); + } catch (IOException e) + { + logger.error("Could not add message to history", e); + } + } + + public void messageDelivered(ChatRoomMessageDeliveredEvent evt) + { + try + { + History history = this. + getHistoryForMultiChat( + null, + evt.getSourceChatRoom()); + + writeMessage(history, "out", evt.getMessage(), evt.getTimestamp()); + } catch (IOException e) + { + logger.error("Could not add message to history", e); + } + } + public void messageDeliveryFailed(ChatRoomMessageDeliveryFailedEvent evt) + { + } + /** - * - * @param direction String - * @param source Contact - * @param destination Contact - * @param message Message + * Writes message to the history + * @param direction String direction of the message + * @param source The source Contact + * @param destination The destiantion Contact + * @param message Message message to be written * @param messageTimestamp Date this is the timestamp when was message received * that came from the protocol provider */ @@ -586,6 +740,25 @@ private void writeMessage(String direction, Contact source, { try { History history = this.getHistory(source, destination); + + writeMessage(history, direction, message, messageTimestamp); + } catch (IOException e) + { + logger.error("Could not add message to history", e); + } + } + + /** + * Writes 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, + Message message, Date messageTimestamp) + { + try { HistoryWriter historyWriter = history.getWriter(); historyWriter.addRecord(new String[] { direction, message.getContent(), message.getContentType(), @@ -597,6 +770,32 @@ private void writeMessage(String direction, Contact source, logger.error("Could not add message to history", e); } } + + /** + * Writes 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, + ChatRoomMember from, + Message message, Date messageTimestamp) + { + try { + HistoryWriter historyWriter = history.getWriter(); + historyWriter.addRecord(new String[] { direction, + message.getContent(), message.getContentType(), + message.getEncoding(), message.getMessageUID(), + from.getContactAddress(), + String.valueOf(messageTimestamp.getTime()) }, + new Date()); // this date is when the history record is written + } catch (IOException e) + { + logger.error("Could not add message to history", e); + } + } + // ////////////////////////////////////////////////////////////////////////// /** @@ -691,6 +890,29 @@ private void handleProviderAdded(ProtocolProviderService provider) { logger.trace("Service did not have a im op. set."); } + + OperationSetMultiUserChat opSetMultiUChat + = (OperationSetMultiUserChat) provider + .getSupportedOperationSets().get( + OperationSetMultiUserChat.class.getName()); + + if (opSetMultiUChat != null) + { + Iterator iter = + opSetMultiUChat.getCurrentlyJoinedChatRooms().iterator(); + + while(iter.hasNext()) + { + ChatRoom room = (ChatRoom)iter.next(); + room.addMessageListener(this); + } + + opSetMultiUChat.addPresenceListener(this); + } + else + { + logger.trace("Service did not have a multi im op. set."); + } } /** @@ -710,6 +932,43 @@ private void handleProviderRemoved(ProtocolProviderService provider) { opSetIm.removeMessageListener(this); } + + OperationSetMultiUserChat opSetMultiUChat + = (OperationSetMultiUserChat) provider + .getSupportedOperationSets().get( + OperationSetMultiUserChat.class.getName()); + + if (opSetMultiUChat != null) + { + Iterator iter = + opSetMultiUChat.getCurrentlyJoinedChatRooms().iterator(); + + while(iter.hasNext()) + { + ChatRoom room = (ChatRoom)iter.next(); + room.removeMessageListener(this); + } + } + } + + /** + * Called to notify interested parties that a change in our presence in + * a chat room has occured. Changes may include us being kicked, join, + * left. + * @param evt the LocalUserChatRoomPresenceChangeEvent instance + * containing the chat room and the type, and reason of the change + */ + public void localUserPresenceChanged(LocalUserChatRoomPresenceChangeEvent evt) + { + if(evt.getEventType() == + LocalUserChatRoomPresenceChangeEvent.CHAT_ROOM_JOINED) + { + evt.getChatRoom().addMessageListener(this); + } + else + { + evt.getChatRoom().removeMessageListener(this); + } } /** @@ -951,6 +1210,422 @@ private Hashtable getHistoryReaders(MetaContact contact) } return readers; } + + /** + * Returns all the messages exchanged in the supplied + * chat room after the given date + * + * @param room The chat room + * @param startDate Date the start date of the conversations + * @return Collection of MessageReceivedEvents or MessageDeliveredEvents + * @throws RuntimeException + */ + public Collection findByStartDate(ChatRoom room, Date startDate) + throws RuntimeException + { + TreeSet result = new TreeSet(new ChatRoomMessageEventComparator()); + try + { + // get the readers for this room + HistoryReader reader = + this.getHistoryForMultiChat(null, room).getReader(); + + // add the progress listeners + addHistorySearchProgressListeners(reader, 1); + + Iterator recs = reader.findByStartDate(startDate); + while (recs.hasNext()) + { + result.add(convertHistoryRecordToMessageEvent( + (HistoryRecord)recs.next(), room)); + } + + removeHistorySearchProgressListeners(reader); + } catch (IOException e) + { + logger.error("Could not read history", e); + } + + return result; + } + + /** + * Returns all the messages exchanged + * in the supplied chat room before the given date + * + * @param room The chat room + * @param endDate Date the end date of the conversations + * @return Collection of MessageReceivedEvents or MessageDeliveredEvents + * @throws RuntimeException + */ + public Collection findByEndDate(ChatRoom room, Date endDate) + throws RuntimeException + { + TreeSet result = new TreeSet(new ChatRoomMessageEventComparator()); + try + { + // get the readers for this room + HistoryReader reader = + this.getHistoryForMultiChat(null, room).getReader(); + + // add the progress listeners + addHistorySearchProgressListeners(reader, 1); + + Iterator recs = reader.findByEndDate(endDate); + while (recs.hasNext()) + { + result.add(convertHistoryRecordToMessageEvent( + (HistoryRecord)recs.next(), room)); + } + + removeHistorySearchProgressListeners(reader); + } catch (IOException e) + { + logger.error("Could not read history", e); + } + + return result; + } + + /** + * Returns all the messages exchanged + * in the supplied chat room between the given dates + * + * @param room The chat room + * @param startDate Date the start date of the conversations + * @param endDate Date the end date of the conversations + * @return Collection of MessageReceivedEvents or MessageDeliveredEvents + * @throws RuntimeException + */ + public Collection findByPeriod(ChatRoom room, Date startDate, Date endDate) + throws RuntimeException + { + TreeSet result = new TreeSet(new ChatRoomMessageEventComparator()); + try + { + // get the readers for this room + HistoryReader reader = + this.getHistoryForMultiChat(null, room).getReader(); + + // add the progress listeners + addHistorySearchProgressListeners(reader, 1); + + Iterator recs = reader.findByPeriod(startDate, endDate); + while (recs.hasNext()) + { + result.add(convertHistoryRecordToMessageEvent( + (HistoryRecord)recs.next(), room)); + } + + removeHistorySearchProgressListeners(reader); + } catch (IOException e) + { + logger.error("Could not read history", e); + } + + return result; + } + + /** + * Returns all the messages exchanged + * in the supplied chat room between the given dates and having the given + * keywords + * + * @param room The chat room + * @param startDate Date the start date of the conversations + * @param endDate Date the end date of the conversations + * @param keywords array of keywords + * @return Collection of MessageReceivedEvents or MessageDeliveredEvents + * @throws RuntimeException + */ + public Collection findByPeriod(ChatRoom room, + Date startDate, Date endDate, String[] keywords) + throws RuntimeException + { + return findByPeriod(room, startDate, endDate, keywords, false); + } + + /** + * Returns all the messages exchanged + * in the supplied chat room between the given dates and having the given + * keywords + * + * @param room The chat room + * @param startDate Date the start date of the conversations + * @param endDate Date the end date of the conversations + * @param keywords array of keywords + * @param caseSensitive is keywords search case sensitive + * @return Collection of MessageReceivedEvents or MessageDeliveredEvents + * @throws RuntimeException + */ + public Collection findByPeriod(ChatRoom room, Date startDate, Date endDate, + String[] keywords, boolean caseSensitive) + throws RuntimeException + { + TreeSet result = new TreeSet(new ChatRoomMessageEventComparator()); + try + { + // get the readers for this room + HistoryReader reader = + this.getHistoryForMultiChat(null, room).getReader(); + + // add the progress listeners + addHistorySearchProgressListeners(reader, 1); + + Iterator recs = reader.findByPeriod(startDate, endDate, keywords, + SEARCH_FIELD, caseSensitive); + while (recs.hasNext()) + { + result.add(convertHistoryRecordToMessageEvent( + (HistoryRecord)recs.next(), room)); + } + + removeHistorySearchProgressListeners(reader); + } catch (IOException e) + { + logger.error("Could not read history", e); + } + + return result; + } + + /** + * Returns all the messages exchanged + * in the supplied room having the given keyword + * + * @param room The Chat room + * @param keyword keyword + * @return Collection of MessageReceivedEvents or MessageDeliveredEvents + * @throws RuntimeException + */ + public Collection findByKeyword(ChatRoom room, String keyword) + throws RuntimeException + { + return findByKeyword(room, keyword, false); + } + + /** + * Returns all the messages exchanged + * in the supplied chat room having the given keyword + * + * @param room The chat room + * @param keyword keyword + * @param caseSensitive is keywords search case sensitive + * @return Collection of MessageReceivedEvents or MessageDeliveredEvents + * @throws RuntimeException + */ + public Collection findByKeyword(ChatRoom room, String keyword, + boolean caseSensitive) + throws RuntimeException + { + TreeSet result = new TreeSet(new ChatRoomMessageEventComparator()); + try + { + // get the readers for this room + HistoryReader reader = + this.getHistoryForMultiChat(null, room).getReader(); + + // add the progress listeners + addHistorySearchProgressListeners(reader, 1); + + Iterator recs = reader. + findByKeyword(keyword, SEARCH_FIELD, caseSensitive); + while (recs.hasNext()) + { + result.add(convertHistoryRecordToMessageEvent( + (HistoryRecord)recs.next(), room)); + } + + removeHistorySearchProgressListeners(reader); + } catch (IOException e) + { + logger.error("Could not read history", e); + } + + return result; + } + + /** + * Returns all the messages exchanged + * in the supplied chat room having the given keywords + * + * @param room The chat room + * @param keywords keyword + * @return Collection of MessageReceivedEvents or MessageDeliveredEvents + * @throws RuntimeException + */ + public Collection findByKeywords(ChatRoom room, String[] keywords) + throws RuntimeException + { + return findByKeywords(room, keywords, false); + } + + /** + * Returns all the messages exchanged + * in the supplied chat room having the given keywords + * + * @param room The chat room + * @param keywords keyword + * @param caseSensitive is keywords search case sensitive + * @return Collection of MessageReceivedEvents or MessageDeliveredEvents + * @throws RuntimeException + */ + public Collection findByKeywords(ChatRoom room, String[] keywords, + boolean caseSensitive) + throws RuntimeException + { + TreeSet result = new TreeSet(new ChatRoomMessageEventComparator()); + try + { + // get the readers for this room + HistoryReader reader = + this.getHistoryForMultiChat(null, room).getReader(); + + // add the progress listeners + addHistorySearchProgressListeners(reader, 1); + + Iterator recs = reader. + findByKeywords(keywords, SEARCH_FIELD, caseSensitive); + while (recs.hasNext()) + { + result.add(convertHistoryRecordToMessageEvent( + (HistoryRecord)recs.next(), room)); + } + + removeHistorySearchProgressListeners(reader); + } catch (IOException e) + { + logger.error("Could not read history", e); + } + + return result; + } + + /** + * Returns the supplied number of recent messages exchanged + * in the supplied chat room + * + * @param room The chat room + * @param count messages count + * @return Collection of MessageReceivedEvents or MessageDeliveredEvents + * @throws RuntimeException + */ + public Collection findLast(ChatRoom room, int count) + throws RuntimeException + { + TreeSet result = new TreeSet(new ChatRoomMessageEventComparator()); + + try + { + // get the readers for this room + HistoryReader reader = + this.getHistoryForMultiChat(null, room).getReader(); + Iterator recs = reader.findLast(count); + while (recs.hasNext()) + { + result.add( + convertHistoryRecordToMessageEvent( + (HistoryRecord)recs.next(), + room)); + + } + } catch (IOException e) + { + logger.error("Could not read history", e); + } + + LinkedList resultAsList = new LinkedList(result); + int startIndex = resultAsList.size() - count; + + if(startIndex < 0) + startIndex = 0; + + return resultAsList.subList(startIndex, resultAsList.size()); + } + + /** + * Returns the supplied number of recent messages after the given date + * exchanged in the supplied chat room + * + * @param room The chat room + * @param date messages after date + * @param count messages count + * @return Collection of MessageReceivedEvents or MessageDeliveredEvents + * @throws RuntimeException + */ + public Collection findFirstMessagesAfter(ChatRoom room, Date date, int count) + throws RuntimeException + { + TreeSet result = new TreeSet(new ChatRoomMessageEventComparator()); + + try + { + HistoryReader reader = + this.getHistoryForMultiChat(null, room).getReader(); + Iterator recs = reader.findFirstRecordsAfter(date, count); + while (recs.hasNext()) + { + result.add( + convertHistoryRecordToMessageEvent( + (HistoryRecord)recs.next(), + room)); + + } + } catch (IOException e) + { + logger.error("Could not read history", e); + } + + LinkedList resultAsList = new LinkedList(result); + int startIndex = resultAsList.size() - count; + + if(startIndex < 0) + startIndex = 0; + + return resultAsList.subList(startIndex, resultAsList.size()); + } + + /** + * Returns the supplied number of recent messages before the given date + * exchanged in the supplied chat room + * + * @param room The chat room + * @param date messages before date + * @param count messages count + * @return Collection of MessageReceivedEvents or MessageDeliveredEvents + * @throws RuntimeException + */ + public Collection findLastMessagesBefore(ChatRoom room, Date date, int count) + throws RuntimeException + { + TreeSet result = new TreeSet(new ChatRoomMessageEventComparator()); + + try + { + HistoryReader reader = + this.getHistoryForMultiChat(null, room).getReader(); + Iterator recs = reader.findLastRecordsBefore(date, count); + while (recs.hasNext()) + { + result.add( + convertHistoryRecordToMessageEvent( + (HistoryRecord)recs.next(), + room)); + + } + } catch (IOException e) + { + logger.error("Could not read history", e); + } + + LinkedList resultAsList = new LinkedList(result); + int startIndex = resultAsList.size() - count; + + if(startIndex < 0) + startIndex = 0; + + return resultAsList.subList(startIndex, resultAsList.size()); + } /** * A wrapper around HistorySearchProgressListener @@ -1145,4 +1820,79 @@ else if(o2 instanceof MessageReceivedEvent) return date1.compareTo(date2); } } -} + + /** + * Used to compare ChatRoomMessageDeliveredEvent + * or ChatRoomMessageReceivedEvent + * and to be ordered in TreeSet according their timestamp + */ + private class ChatRoomMessageEventComparator + implements Comparator + { + public int compare(Object o1, Object o2) + { + Date date1 = null; + Date date2 = null; + + if(o1 instanceof ChatRoomMessageDeliveredEvent) + date1 = ((ChatRoomMessageDeliveredEvent)o1).getTimestamp(); + else if(o1 instanceof ChatRoomMessageReceivedEvent) + date1 = ((ChatRoomMessageReceivedEvent)o1).getTimestamp(); + else + return 0; + + if(o2 instanceof ChatRoomMessageDeliveredEvent) + date2 = ((ChatRoomMessageDeliveredEvent)o2).getTimestamp(); + else if(o2 instanceof ChatRoomMessageReceivedEvent) + date2 = ((ChatRoomMessageReceivedEvent)o2).getTimestamp(); + else + return 0; + + return date1.compareTo(date2); + } + } + + /** + * Simple ChatRoomMember implementation. + */ + class ChatRoomMemberImpl + implements ChatRoomMember + { + private ChatRoom chatRoom; + private String name; + private ChatRoomMemberRole role; + + public ChatRoomMemberImpl(String name, ChatRoom chatRoom, + ChatRoomMemberRole role) + { + this.chatRoom = chatRoom; + this.name = name; + this.role = role; + } + + public ChatRoom getChatRoom() + { + return chatRoom; + } + + public ProtocolProviderService getProtocolProvider() + { + return chatRoom.getParentProvider(); + } + + public String getContactAddress() + { + return name; + } + + public String getName() + { + return name; + } + + public ChatRoomMemberRole getRole() + { + return role; + } + } +} \ No newline at end of file diff --git a/src/net/java/sip/communicator/impl/protocol/mock/MockBasicInstantMessaging.java b/src/net/java/sip/communicator/impl/protocol/mock/MockBasicInstantMessaging.java index 192f4eb33..405d0453f 100644 --- a/src/net/java/sip/communicator/impl/protocol/mock/MockBasicInstantMessaging.java +++ b/src/net/java/sip/communicator/impl/protocol/mock/MockBasicInstantMessaging.java @@ -77,7 +77,7 @@ public void addMessageListener(MessageListener listener) public Message createMessage(byte[] content, String contentType, String contentEncoding, String subject) { - return new MessageImpl(new String(content), contentType + return new MockMessage(new String(content), contentType , contentEncoding, subject); } @@ -90,7 +90,7 @@ public Message createMessage(byte[] content, String contentType, */ public Message createMessage(String messageText) { - return new MessageImpl(messageText, DEFAULT_MIME_TYPE, + return new MockMessage(messageText, DEFAULT_MIME_TYPE, DEFAULT_MIME_ENCODING, null); } @@ -187,69 +187,4 @@ public void deliverMessage(String to, Message msg) listener.messageReceived(msgReceivedEvt); } } - - public class MessageImpl - implements Message - { - private String textContent = null; - - private String contentType = null; - - private String contentEncoding = null; - - private String messageUID = null; - - private String subject = null; - - public MessageImpl(String content, - String contentType, - String contentEncoding, - String subject) - { - this.textContent = content; - this.contentType = contentType; - this.contentEncoding = contentEncoding; - this.subject = subject; - - //generate the uid - this.messageUID = String.valueOf( System.currentTimeMillis()) - + String.valueOf(hashCode()); - - } - - public String getContent() - { - return textContent; - } - - public String getContentType() - { - return contentType; - } - - public String getEncoding() - { - return contentEncoding; - } - - public String getMessageUID() - { - return messageUID; - } - - public byte[] getRawData() - { - return getContent().getBytes(); - } - - public int getSize() - { - return getContent().length(); - } - - public String getSubject() - { - return subject; - } - } -} +} \ No newline at end of file diff --git a/src/net/java/sip/communicator/impl/protocol/mock/MockChatRoom.java b/src/net/java/sip/communicator/impl/protocol/mock/MockChatRoom.java new file mode 100644 index 000000000..14ab0a0f6 --- /dev/null +++ b/src/net/java/sip/communicator/impl/protocol/mock/MockChatRoom.java @@ -0,0 +1,1205 @@ +/* + * 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.mock; + +import java.util.*; +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.service.protocol.event.*; + +/** + * + * @author Damian Minkov + */ +public class MockChatRoom + implements ChatRoom +{ + private MockProvider provider; + + private MockMultiUserChat parentOpSet = null; + + private String name; + + private String subject; + + private String nickname; + + private String roomPassword; + + private boolean joined = false; + + private int userLimit = Integer.MAX_VALUE; + + private List members = new Vector(); + + private Vector banMasks = new Vector(); + + /** + * Currently registered member presence listeners. + */ + private Vector memberPresenceListeners = new Vector(); + + /** + * Currently registered local user role listeners. + */ + private Vector localUserRoleListeners = new Vector(); + + /** + * Currently registered member role listeners. + */ + private Vector memberRoleListeners = new Vector(); + + /** + * Currently registered property change listeners. + */ + private Vector propertyChangeListeners = new Vector(); + + /** + * Currently registered message listeners. + */ + private Vector messageListeners = new Vector(); + + /** + * Currently registered join chatroom listeners. + */ + private Vector chatRoomJoinListeners = new Vector(); + + + public MockChatRoom( + MockProvider provider, + MockMultiUserChat parentOpSet, + String roomName) + { + this.provider = provider; + this.name = roomName; + this.parentOpSet = parentOpSet; + } + + /** + * Returns the name of this ChatRoom. + * + * @return a String containing the name of this ChatRoom. + */ + public String getName() + { + return name; + } + + /** + * 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 + { + joinAs(null, null); + } + + /** + * Joins this chat room so that the user would start receiving events and + * messages for it. The method uses the nickname of the local user and the + * specified password in order to enter the chatroom. + * + * @param password the password to use when authenticating on the chatroom. + * @throws OperationFailedException with the corresponding code if an error + * occurs while joining the room. + */ + public void join(byte[] password) + throws OperationFailedException + { + joinAs(null, password); + } + + /** + * Joins this chat room with the specified nickname so that the user would + * start receiving events and messages for it. If the chatroom already + * contains a user with this nickname, the method would throw an + * OperationFailedException with code IDENTIFICATION_CONFLICT. + * + * @param nickname the nickname to use. + * @throws OperationFailedException with the corresponding code if an error + * occurs while joining the room. + */ + public void joinAs(String nickname) + throws OperationFailedException + { + joinAs(nickname, null); + } + + /** + * Joins this chat room with the specified nickname and password so that the + * user would start receiving events and messages for it. If the chatroom + * already contains a user with this nickname, the method would throw an + * OperationFailedException with code IDENTIFICATION_CONFLICT. + * + * @param nickname the nickname to use. + * @param password a password necessary to authenticate when joining the + * room. + * @throws OperationFailedException with the corresponding code if an error + * occurs while joining the room. + */ + public void joinAs(String nickname, byte[] password) + throws OperationFailedException + { + if(nickname == null) + nickname = getParentProvider().getAccountID().getUserID(); + + this.nickname = nickname; + this.joined = true; + + MockChatRoomMember newMember = + new MockChatRoomMember(nickname, this, ChatRoomMemberRole.MEMBER); + + members.add(newMember); + + ChatRoomJoinedEvent event = + new ChatRoomJoinedEvent(this); + + Iterator iter = chatRoomJoinListeners.iterator(); + while(iter.hasNext()) + { + ChatRoomJoinListener elem = + (ChatRoomJoinListener)iter.next(); + + elem.chatRoomJoined(event); + } + + LocalUserChatRoomPresenceChangeEvent evt = + new LocalUserChatRoomPresenceChangeEvent( + parentOpSet, + this, + LocalUserChatRoomPresenceChangeEvent.CHAT_ROOM_JOINED, + null); + parentOpSet.fireLocalUserChatRoomPresenceChangeEvent(evt); + } + + /** + * Returns true if the local user is currently in the multi user chat + * (after calling one of the {@link #join()} methods). + * + * @return true if currently we're currently in this chat room and false + * otherwise. + */ + public boolean isJoined() + { + return joined; + } + + /** + * 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() + { + + } + + /** + * Returns the last known room subject/theme or null if the user + * hasn't joined the room or the room does not have a subject yet. + *
+ * To be notified every time the room's subject change you should add a + * ChatRoomChangelistener to this room. + * {@link #addPropertyChangeListener(ChatRoomPropertyChangeListener)} + *
+ * To change the room's subject use {@link #setSubject(String)}. + * + * @return the room subject or null if the user hasn't joined the + * room or the room does not have a subject yet. + */ + public String getSubject() + { + return subject; + } + + /** + * Sets the subject of this chat room. If the user does not have the right + * to change the room subject, or the protocol does not support this, or + * the operation fails for some other reason, the method throws an + * OperationFailedException with the corresponding code. + * + * @param subject the new subject that we'd like this room to have + * @throws OperationFailedException + */ + public void setSubject(String subject) + throws OperationFailedException + { + this.subject = subject; + } + + /** + * Returns the local user's nickname in the context of this chat room or + * null 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() + { + return nickname; + } + + /** + * Changes the the local user's nickname in the context of this chatroom. + * If the operation is not supported by the underlying implementation, the + * method throws an OperationFailedException with the corresponding code. + * + * @param nickname the new nickname within the room. + * + * @throws OperationFailedException if the setting the new nickname changes + * for some reason. + */ + public void setNickname(String nickname) + throws OperationFailedException + { + this.nickname = nickname; + } + + /** + * Adds a listener that will be notified of changes in our participation in + * the room such as us being kicked, join, left... + * + * @param listener a member participation listener. + */ + public void addMemberPresenceListener( + ChatRoomMemberPresenceListener listener) + { + if(!memberPresenceListeners.contains(listener)) + memberPresenceListeners.add(listener); + } + + /** + * Removes a listener that was being notified of changes in the + * participation of other chat room participants such as users being kicked, + * join, left. + * + * @param listener a member participation listener. + */ + public void removeMemberPresenceListener( + ChatRoomMemberPresenceListener listener) + { + memberPresenceListeners.remove(listener); + } + + /** + * Adds a listener that will be notified of changes in our role in the room + * such as us being granded operator. + * + * @param listener a local user role listener. + */ + public void addLocalUserRoleListener(ChatRoomLocalUserRoleListener listener) + { + if(!localUserRoleListeners.contains(listener)) + localUserRoleListeners.add(listener); + } + + /** + * Removes a listener that was being notified of changes in our role in this + * chat room such as us being granded operator. + * + * @param listener a local user role listener. + */ + public void removelocalUserRoleListener( + ChatRoomLocalUserRoleListener listener) + { + localUserRoleListeners.remove(listener); + } + + /** + * Adds a listener that will be notified of changes of a member role in the + * room such as being granded operator. + * + * @param listener a member role listener. + */ + public void addMemberRoleListener(ChatRoomMemberRoleListener listener) + { + if(!memberRoleListeners.contains(listener)) + memberRoleListeners.add(listener); + } + + /** + * Removes a listener that was being notified of changes of a member role in + * this chat room such as us being granded operator. + * + * @param listener a member role listener. + */ + public void removeMemberRoleListener(ChatRoomMemberRoleListener listener) + { + memberRoleListeners.remove(listener); + } + + /** + * Adds a listener that will be notified of changes in the property of the + * room such as the subject being change or the room state being changed. + * + * @param listener a property change listener. + */ + public void addPropertyChangeListener( + ChatRoomPropertyChangeListener listener) + { + if(!propertyChangeListeners.contains(listener)) + propertyChangeListeners.add(listener); + } + + /** + * Removes a listener that was being notified of changes in the property of + * the chat room such as the subject being change or the room state being + * changed. + * + * @param listener a property change listener. + */ + public void removePropertyChangeListener( + ChatRoomPropertyChangeListener listener) + { + propertyChangeListeners.remove(listener); + } + + /** + * Invites another user to this room. + *
+ * If the room is password-protected, the invitee will receive a password to
+ * use to join the room. If the room is members-only, the the invitee may
+ * be added to the member list.
+ *
+ * @param userAddress the address of the user to invite to the room.(one
+ * may also invite users not on their contact list).
+ * @param reason a reason, subject, or welcome message that would tell the
+ * the user why they are being invited.
+ */
+ public void invite(String userAddress, String reason)
+ {
+
+ }
+
+ /**
+ * Returns a List of ChatRoomMembers corresponding to all
+ * members currently participating in this room.
+ *
+ * @return a List of ChatRoomMember instances
+ * corresponding to all room members.
+ */
+ public List getMembers()
+ {
+ return members;
+ }
+
+ /**
+ * Returns the number of participants that are currently in this chat room.
+ * @return int the number of Contacts, currently participating in
+ * this room.
+ */
+ public int getMembersCount()
+ {
+ return members.size();
+ }
+
+ /**
+ * Registers listener so that it would receive events every time a
+ * new message is received on this chat room.
+ * @param listener a MessageListener that would be notified every
+ * time a new message is received on this chat room.
+ */
+ public void addMessageListener(ChatRoomMessageListener listener)
+ {
+ if(!messageListeners.contains(listener))
+ messageListeners.add(listener);
+ }
+
+ /**
+ * Removes listener so that it won't receive any further message
+ * events from this room.
+ * @param listener the MessageListener to remove from this room
+ */
+ public void removeMessageListener(ChatRoomMessageListener listener)
+ {
+ messageListeners.remove(listener);
+ }
+
+ /**
+ * Create a Message instance for sending arbitrary MIME-encoding content.
+ *
+ * @param content content value
+ * @param contentType the MIME-type for content
+ * @param contentEncoding encoding used for content
+ * @param subject a String subject or null for now subject.
+ * @return the newly created message.
+ */
+ public Message createMessage(byte[] content, String contentType,
+ String contentEncoding, String subject)
+ {
+ return new MockMessage(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)
+ {
+ return new MockMessage(messageText);
+ }
+
+ /**
+ * Sends the message to the destination indicated by the
+ * to contact.
+ * @param message the Message to send.
+ * @throws OperationFailedException if sending the message fails for some
+ * reason.
+ */
+ public void sendMessage(Message message)
+ throws OperationFailedException
+ {
+ ChatRoomMessageDeliveredEvent evt =
+ new ChatRoomMessageDeliveredEvent(
+ this,
+ new Date(),
+ message);
+
+ Iterator iter = messageListeners.iterator();
+ while(iter.hasNext())
+ {
+ ChatRoomMessageListener elem =
+ (ChatRoomMessageListener)iter.next();
+
+ elem.messageDelivered(evt);
+ }
+ }
+
+ /**
+ * Returns a reference to the provider that created this room.
+ *
+ * @return a reference to the ProtocolProviderService instance
+ * that created this room.
+ */
+ public ProtocolProviderService getParentProvider()
+ {
+ return provider;
+ }
+
+ /**
+ * Sets the password of this chat room. If the user does not have the right
+ * to change the room password, or the protocol does not support this, or
+ * the operation fails for some other reason, the method throws an
+ * OperationFailedException with the corresponding code.
+ *
+ * @param password the new password that we'd like this room to have
+ * @throws OperationFailedException if the user does not have the right to
+ * change the room password, or the protocol does not support
+ * this, or the operation fails for some other reason
+ */
+ public void setPassword(String password)
+ throws OperationFailedException
+ {
+ roomPassword = password;
+ }
+
+ /**
+ * Returns the password of this chat room or null if the room doesn't have
+ * password.
+ * @return the password of this chat room or null if the room doesn't have
+ * password
+ */
+ public String getPassword()
+ {
+ return roomPassword;
+ }
+
+ /**
+ * Adds a ban mask to the list of ban masks of this chat room. The ban mask
+ * defines a group of users that will be banned. This property is meant to
+ * be used mainly by IRC implementations. If the user does not have the
+ * right to change the room ban list, or the protocol does not support this,
+ * or the operation fails for some other reason, the method throws an
+ * OperationFailedException with the corresponding code.
+ *
+ * @param banMask the new ban mask that we'd like to add to the room ban
+ * list
+ * @throws OperationFailedException if the user does not have the right to
+ * change the room ban list, or the protocol does not support this, or the
+ * operation fails for some other reason
+ */
+ public void addBanMask(String banMask)
+ throws OperationFailedException
+ {
+ if(!banMasks.contains(banMask))
+ banMasks.add(banMask);
+ }
+
+ /**
+ * Remove a ban mask from the list of ban masks of this chat room. If the
+ * user does not have the right to change the room ban list, or the protocol
+ * does not support this, or the operation fails for some other reason, the
+ * method throws an OperationFailedException with the
+ * corresponding code.
+ *
+ * @param banMask the ban mask that we'd like to remove from this room ban
+ * list
+ * @throws OperationFailedException if the user does not have the right to
+ * change the room ban list, or the protocol does not support this, or the
+ * operation fails for some other reason
+ */
+ public void removeBanMask(String banMask)
+ throws OperationFailedException
+ {
+ banMasks.remove(banMask);
+ }
+
+ /**
+ * Sets the user limit of this chat room. The user limit is the maximum
+ * number of users, who could enter this chat room at a time. If the user
+ * does not have the right to change the room user limit, or the protocol
+ * does not support this, or the operation fails for some other reason, the
+ * method throws an OperationFailedException with the
+ * corresponding code.
+ *
+ * @param userLimit the new user limit that we'd like this room to have
+ * @throws OperationFailedException if the user does not have the right to
+ * change the room user limit, or the protocol does not support this, or the
+ * operation fails for some other reason
+ */
+ public void setUserLimit(int userLimit)
+ throws OperationFailedException
+ {
+ this.userLimit = userLimit;
+ }
+
+ /**
+ * Returns the limit of user for this chat room. The user limit is the
+ * maximum number of users, who could enter this chat room at a time.
+ *
+ * @return int the limit of user for this chat room
+ */
+ public int getUserLimit()
+ {
+ return userLimit;
+ }
+
+ /**
+ * Returns an Iterator over a set of ChatRoomConfigParams. Each
+ * element in the set is one of the ChatRoomConfigParams.CHAT_ROOM_XXX
+ * configuration params. This method is meant to be used by other bundles,
+ * before trying to change ChatRoom configurations, in order to
+ * check which are the supported configurations by the current
+ * implementation.
+ *
+ * @return an Iterator over a set of ChatRoomConfigParams
+ */
+ public Iterator getSupportedConfigParams()
+ {
+ return new Vector().iterator();
+ }
+
+ /**
+ * Returns an Iterator over a set of ChatRoomConfigParams,
+ * containing the current configuration of this chat room. This method is
+ * meant to be used by bundles interested in what are the specific chat room
+ * configurations.
+ *
+ * @return an Iterator over a set of ChatRoomConfigParams,
+ * containing the current configuration of this chat room
+ */
+ public Iterator getConfiguration()
+ {
+ return new Vector().iterator();
+ }
+
+ /**
+ * Returns an Iterator over a set of ban masks for this chat room. The ban
+ * mask defines a group of users that will be banned. The ban list is a list
+ * of all such ban masks defined for this chat room.
+ *
+ * @return an Iterator over a set of ban masks for this chat room
+ */
+ public Iterator getBanList()
+ {
+ return new Vector().iterator();
+ }
+
+ /**
+ * Methods for manipulating mock operation set as
+ * deliver(receive) messageop
+ *
+ * @param msg the message that we are to deliver.
+ */
+ public void deliverMessage(Message msg, String from)
+ {
+ ChatRoomMember fromMember = null;
+ Iterator iter = members.iterator();
+ while(iter.hasNext())
+ {
+ ChatRoomMember elem = (ChatRoomMember)iter.next();
+ if(elem.getName().equals(from))
+ {
+ fromMember = elem;
+ break;
+ }
+ }
+
+ if(fromMember == null)
+ return;
+
+ ChatRoomMessageReceivedEvent evt =
+ new ChatRoomMessageReceivedEvent(
+ this,
+ fromMember,
+ new Date(),
+ msg);
+
+ iter = messageListeners.iterator();
+ while(iter.hasNext())
+ {
+ ChatRoomMessageListener elem =
+ (ChatRoomMessageListener)iter.next();
+
+ elem.messageReceived(evt);
+ }
+ }
+
+ /**
+ * Changes the the local user's nickname in the context of this chatroom.
+ * If the operation is not supported by the underlying implementation, the
+ * method throws an OperationFailedException with the corresponding code.
+ *
+ * @param nickname the new nickname within the room.
+ *
+ * @throws OperationFailedException if the setting the new nickname changes
+ * for some reason.
+ */
+ public void setUserNickname(String nickname) throws OperationFailedException
+ {
+ this.nickname = nickname;
+ }
+
+ /**
+ * Indicates if this ChatRoom is visible to everyone and everyone
+ * could join it. If the ChatRoom is NOT visible, it cannot be seen
+ * without knowing the exact name.
+ *
+ * @return true if this ChatRoom is visible to
+ * everyone, otherwise - false.
+ */
+ public boolean isVisible()
+ {
+ return true;
+ }
+
+ /**
+ * Sets the property indicating if this ChatRoom is visible to
+ * everyone and everyone could join it. If the ChatRoom is NOT
+ * visible, it cannot be seen without knowing the exact name.
+ *
+ * @param isVisible indicates if this ChatRoom should be visible or
+ * not
+ */
+ public void setVisible(boolean isVisible)
+ {
+ }
+
+ /**
+ * Indicates if this ChatRoom requires a password to be joined.
+ *
+ * @return true if this ChatRoom requires a password
+ * to be joined, otherwise - false
+ */
+ public boolean isPasswordRequired()
+ {
+ return false;
+ }
+
+ /**
+ * Sets the property indicating if this ChatRoom requires a
+ * password to be joined.
+ *
+ * @param isPasswordRequired indicates if this ChatRoom requires a
+ * password to be joined.
+ */
+ public void setPasswordRequired(boolean isPasswordRequired)
+ {
+ }
+
+ /**
+ * Indicates if this ChatRoom requires an invitation. If the
+ * chat room requires invitation, the user could not join it without being
+ * invited.
+ *
+ * @return true if this ChatRoom requires invitation
+ * to joined, otherwise - false.
+ */
+ public boolean isInvitationRequired()
+ {
+ return false;
+ }
+
+ /**
+ * Sets the property indicating if this ChatRoom requires an
+ * invitation to be joined. If the chat room requires invitation, the user
+ * could not join it without being invited.
+ *
+ * @param isInvitationRequired indicates if this ChatRoom requires
+ * invitation to be joined
+ */
+ public void setInvitationRequired(boolean isInvitationRequired)
+ {
+ }
+
+ /**
+ * Indicates if this ChatRoom has a limit on number of users who
+ * could join it.
+ *
+ * @return true if the number of users who could join this
+ * ChatRoom is limited, otherwise - false
+ */
+ public boolean isMemberNumberLimited()
+ {
+ return false;
+ }
+
+ /**
+ * Sets the property inficating if this ChatRoom has a limit on
+ * number of users who could join it.
+ *
+ * @param isMemberNumberLimited indicates if this ChatRoom has a
+ * limit on number of users who could join it
+ */
+ public void setMemberNumberLimited(boolean isMemberNumberLimited)
+ {
+ }
+
+ /**
+ * Indicates if this ChatRoom is in a mute mode. If a
+ * ChatRoom is muted no messages could be obtained from it.
+ *
+ * @return true if this ChatRoom is in a mute mode,
+ * otherwise - false
+ */
+ public boolean isMute()
+ {
+ return false;
+ }
+
+ /**
+ * Sets the property indicating if this ChatRoom is in a mute mode.
+ * If a ChatRoom is muted no messages could be obtained from it.
+ *
+ * @param isMute indicates if this ChatRoom should be in a mute
+ * mode or not
+ */
+ public void setMute(boolean isMute)
+ {
+ }
+
+ /**
+ * Indicates if it's possible for someone to send messages to this
+ * ChatRoom even if they are not present inside the chat room.
+ *
+ * @return true if this ChatRoom allows external
+ * messages, otherwise - false
+ */
+ public boolean isAllowExternalMessages()
+ {
+ return false;
+ }
+
+ /**
+ * Sets the property indicating if it's possible for someone to send
+ * messages to this ChatRoom even if they are not present inside
+ * the chat room.
+ *
+ * @param isAllowExternalMessages indicates if this ChatRoom should
+ * allow external messages or not
+ */
+ public void setAllowExternalMessages(boolean isAllowExternalMessages)
+ {
+ }
+
+ /**
+ * Indicates if this ChatRoom is registered.
+ *
+ * @return true if this ChatRoom is registered,
+ * otherwise - false
+ */
+ public boolean isRegistered()
+ {
+ return false;
+ }
+
+ /**
+ * Sets the property indicating if this ChatRoom is registered or
+ * not.
+ *
+ * @param isRegistered indicates if this ChatRoom is registered
+ */
+ public void setRegistered(boolean isRegistered)
+ {
+ }
+
+ /**
+ * Indicates if the subject of this ChatRoom could be changed by
+ * non admin users. If the subject is locked only admin users could change
+ * it.
+ *
+ * @return true if only admin user could change the subject of
+ * this ChatRoom, otherwise - false
+ */
+ public boolean isSubjectLocked()
+ {
+ return true;
+ }
+
+ /**
+ * Sets the property indicating if the subject of this ChatRoom
+ * could be changed only by admin users.
+ *
+ * @param isSubjectLocked indicates if the subject of this ChatRoom
+ * is locked
+ */
+ public void setSubjectLocked(boolean isSubjectLocked)
+ {
+ }
+
+ /**
+ * Indicates if the message format in this ChatRoom could be
+ * modified. If the message formatting is allowed - we could have colored,
+ * underlined, etc. messages.
+ *
+ * @return true if message formatting in this ChatRoom
+ * is allowed, otherwise - false
+ */
+ public boolean isAllowMessageFormatting()
+ {
+ return false;
+ }
+
+ /**
+ * Sets the property indicating if the message format in this
+ * ChatRoom could be modified. If the message formatting is
+ * allowed - we could have colored, underlined, etc. messages.
+ *
+ * @param isAllowMessageFormatting indicates if the message formatting in
+ * this ChatRoom is allowed
+ */
+ public void setAllowMessageFormatting(boolean isAllowMessageFormatting)
+ {
+ }
+
+ /**
+ * Indicates is this ChatRoom room is currently in a message
+ * formatting filtered mode. The message formatting filtered mode means that
+ * all formatted messages (colored, underlined, etc.) are seen in standard
+ * format by other users.
+ *
+ * @return true if this ChatRoom is in message
+ * formatting filtered mode, otherwise - false
+ */
+ public boolean isFilterMessageFormatting()
+ {
+ return false;
+ }
+
+ /**
+ * Sets the property indicating if this ChatRoom room is currently
+ * in a message formatting filtered mode. The message formatting filtered
+ * mode means that all formatted messages (colored, underlined, etc.) are
+ * seen in standard format by other users.
+ *
+ * @param isFilterMessageFormatting indicates if this ChatRoom
+ * is currently is a message formatting filtered mode
+ */
+ public void setFilterMessageFormatting(boolean isFilterMessageFormatting)
+ {
+ }
+
+ /**
+ * Indicates if users can only join this ChatRoom in a specified
+ * interval of X seconds or the time of join is unlimited.
+ *
+ * @return true if this ChatRoom could be joined only
+ * in a specified interval of X seconds, otherwise - false
+ */
+ public boolean isJoinTimeLimited()
+ {
+ return false;
+ }
+
+ /**
+ * Sets the property indicating if users can only join this ChatRoom
+ * in a specified interval of X seconds or the time of join is unlimited.
+ *
+ * @param isJoinTimeLimited indicates if users can only join this
+ * ChatRoom in a specified interval of X seconds or the time of
+ * join is unlimited.
+ */
+ public void setJoinTimeLimited(boolean isJoinTimeLimited)
+ {
+ }
+
+ /**
+ * Indicates if sending invitation request is allowed in this
+ * ChatRoom.
+ *
+ * @return true if user is allowed to send invitation request
+ * from this ChatRoom, otherwise - false
+ */
+ public boolean isAllowInvitationSend()
+ {
+ return false;
+ }
+
+ /**
+ * Sets the property indicating if sending invitation request is allowed in
+ * this ChatRoom.
+ *
+ * @param isAllowInvitationSend indicates if sending invitation request is
+ * allowed in this ChatRoom
+ */
+ public void setAllowInvitationSend(boolean isAllowInvitationSend)
+ {
+ }
+
+ /**
+ * Indicates if receiving invitation request is allowed in this
+ * ChatRoom.
+ *
+ * @return true if user is allowed to receive invitation request
+ * in this ChatRoom, otherwise - false
+ */
+ public boolean isAllowInvitationReceive()
+ {
+ return false;
+ }
+
+ /**
+ * Sets the property indicating if receiving invitation request is allowed
+ * in this ChatRoom.
+ *
+ * @param isAllowInvitationReceive indicates if receiving invitation request
+ * is allowed in this ChatRoom
+ */
+ public void setAllowInvitationReceive(boolean isAllowInvitationReceive)
+ {
+ }
+
+ /**
+ * Indicates if users which join this ChatRoom are redirected to
+ * another one.
+ *
+ * @return true if users are redirected, otherwise -
+ * false
+ */
+ public boolean isUserRedirected()
+ {
+ return false;
+ }
+
+ /**
+ * Sets the property indicating if users in this ChatRoom are
+ * redirected to another one.
+ *
+ * @param isRedirected indicates if users in this ChatRoom are
+ * redirected to another one.
+ */
+ public void setUserRedirected(boolean isRedirected)
+ {
+ }
+
+ /**
+ * Indicates if users in this ChatRoom can or cannot change their
+ * nickname.
+ *
+ * @return true if users in this ChatRoom can NOT
+ * change their nickname, otherwise - false
+ */
+ public boolean isUserNicknameLocked()
+ {
+ return false;
+ }
+
+ /**
+ * Sets the property indicating if users in this ChatRoom can or
+ * cannot change their nickname.
+ *
+ * @param isUserNicknameLocked indicates if nicknames in this
+ * ChatRoom are locked and could not be changed by users or users
+ * are free to modify their nick as they want
+ */
+ public void setUserNicknameLocked(boolean isUserNicknameLocked)
+ {
+ }
+
+ /**
+ * Indicates if kicks are allowed in this ChatRoom. A kick tells the
+ * server to force a user to leave the chat room. Kick is a term inspired of
+ * the IRC protocol.
+ *
+ * @return true if kicks are allowed in this ChatRoom,
+ * otherwise - false
+ */
+ public boolean isAllowKick()
+ {
+ return false;
+ }
+
+ /**
+ * Sets the property indicating if kicks are allowed in this
+ * ChatRoom. A kick tells the server to force a user to leave the
+ * chat room. Kick is a term inspired of the IRC protocol.
+ *
+ * @param isAllowKick indicates if kicks are allowed in this
+ * ChatRoom
+ */
+ public void setAllowKick(boolean isAllowKick)
+ {
+ }
+
+ /**
+ * Indicates if only registered users can join this ChatRoom or
+ * it's opened for everyone.
+ *
+ * @return true if only registered users could join this
+ * ChatRoom, otherwise - false
+ */
+ public boolean isRegisteredUserOnly()
+ {
+ return false;
+ }
+
+ /**
+ * Sets the property indicating if only registered users can join this
+ * ChatRoom or it's opened for everyone.
+ *
+ * @param isRegisteredUserOnly indicates if only registered users can join
+ * this ChatRoom or it's opened for everyone.
+ */
+ public void setRegisteredUserOnly(boolean isRegisteredUserOnly)
+ {
+ }
+
+ /**
+ * Indicates if this ChatRoom allows special messages.
+ *
+ * @return true if special messages are allowed in this
+ * ChatRoom, otherwise - false
+ */
+ public boolean isAllowSpecialMessage()
+ {
+ return false;
+ }
+
+ /**
+ * Sets the property indicating if this ChatRoom allows special
+ * messages.
+ *
+ * @param isAllowSpecialMessage indicates this ChatRoom should
+ * allow special messages
+ */
+ public void setAllowSpecialMessage(boolean isAllowSpecialMessage)
+ {
+ }
+
+ /**
+ * Indicates if the list of nicknames in this chat room is currently
+ * visible.
+ *
+ * @return true if the list of nicknames in this
+ * ChatRoom is visible, otherwise - false
+ */
+ public boolean isNicknameListVisible()
+ {
+ return false;
+ }
+
+ /**
+ * Sets the property indicating if the list of nicknames in this chat room
+ * is currently visible.
+ *
+ * @param isNicknameListVisible indicates if the list of nicknames in this
+ * chat room should be visible.
+ */
+ public void setNicknameListVisible(boolean isNicknameListVisible)
+ {
+ }
+
+ /**
+ * Adds a configuration property to the configuration list of this chat
+ * room. If the user does not have the right to change the room
+ * configuration, or the protocol does not support this, or the operation
+ * fails for some other reason, the method throws an
+ * OperationFailedException with the corresponding code.
+ *
+ * @param propertyName the name of the configuration property to set
+ * @param propertyValue the value to set to the given configuration property
+ * @throws OperationFailedException if the user does not have the right to
+ * change the room configuration, or the protocol does not support this, or
+ * the operation fails for some other reason
+ */
+ public void addAdvancedConfigProperty(String propertyName, String propertyValue) throws OperationFailedException
+ {
+ }
+
+ /**
+ * Removes a configuration property from this chat room configuration list.
+ * If the user does not have the right to change the room state, or the
+ * protocol does not support this, or the operation fails for some other
+ * reason, the method throws an OperationFailedException with the
+ * corresponding code.
+ *
+ * @param propertyName the name of the configuration property to be removed
+ *
+ * @throws OperationFailedException if the user does not have the right to
+ * change the room configuration, or the protocol does not support this, or
+ * the operation fails for some other reason
+ */
+ public void removeAdvancedConfigProperty(String propertyName) throws OperationFailedException
+ {
+ }
+
+ /**
+ * Returns an Iterator over a set of ChatRoomConfigParams,
+ * containing the current configuration of this chat room. This method is
+ * meant to be used by bundles interested in what are the specific chat room
+ * configurations.
+ *
+ * @return a Map of (Property_Name, Property_Value) pairs, containing the
+ * current configuration of this chat room
+ */
+ public Map getAdvancedConfigurationSet()
+ {
+ return new HashMap();
+ }
+
+ /**
+ * Adds a listener to join notifications. The listener will be fired
+ * anytime a ChatRoom has been joined.
+ *
+ * @param listener a join listener.
+ */
+ public void addJoinListener(ChatRoomJoinListener listener)
+ {
+ if(!chatRoomJoinListeners.contains(listener))
+ chatRoomJoinListeners.add(listener);
+ }
+
+ /**
+ * Removes the given listener from the list of join listeners registered to
+ * receive events every time when a ChatRoom has been joined.
+ *
+ * @param listener the join listener to remove
+ */
+ public void removeJoinListener(ChatRoomJoinListener listener)
+ {
+ chatRoomJoinListeners.remove(listener);
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/protocol/mock/MockChatRoomMember.java b/src/net/java/sip/communicator/impl/protocol/mock/MockChatRoomMember.java
new file mode 100644
index 000000000..1d2f91b42
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/protocol/mock/MockChatRoomMember.java
@@ -0,0 +1,90 @@
+/*
+ * 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.mock;
+
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ *
+ * @author Damian Minkov
+ */
+public class MockChatRoomMember
+ implements ChatRoomMember
+{
+ private ChatRoom chatRoom;
+ private String name;
+ private ChatRoomMemberRole role;
+
+ public MockChatRoomMember(String name, ChatRoom chatRoom,
+ ChatRoomMemberRole role)
+ {
+ this.chatRoom = chatRoom;
+ this.name = name;
+ this.role = role;
+ }
+
+ /**
+ * Returns the chat room that this member is participating in.
+ *
+ * @return the ChatRoom instance that this member belongs to.
+ */
+ public ChatRoom getChatRoom()
+ {
+ return chatRoom;
+ }
+
+ /**
+ * Returns the protocol provider instance that this member has originated
+ * in.
+ *
+ * @return the ProtocolProviderService instance that created this
+ * member and its containing cht room
+ */
+ public ProtocolProviderService getProtocolProvider()
+ {
+ return chatRoom.getParentProvider();
+ }
+
+ /**
+ * Returns the contact identifier representing this contact. In protocols
+ * like IRC this method would return the same as getName() but in others
+ * like Jabber, this method would return a full contact id uri.
+ *
+ * @return a String (contact address), uniquely representing the contact
+ * over the service the service being used by the associated protocol
+ * provider instance/
+ */
+ public String getContactAddress()
+ {
+ return name;
+ }
+
+ /**
+ * Returns the name of this member as it is known in its containing
+ * chatroom (aka a nickname). The name returned by this method, may
+ * sometimes match the string returned by getContactID() which is actually
+ * the address of a contact in the realm of the corresponding protocol.
+ *
+ * @return the name of this member as it is known in the containing chat
+ * room (aka a nickname).
+ */
+ public String getName()
+ {
+ return name;
+ }
+
+ /**
+ * Returns the role of this chat room member in its containing room.
+ *
+ * @return a ChatRoomMemberRole instance indicating the role
+ * the this member in its containing chat room.
+ */
+ public ChatRoomMemberRole getRole()
+ {
+ return role;
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/protocol/mock/MockMessage.java b/src/net/java/sip/communicator/impl/protocol/mock/MockMessage.java
new file mode 100644
index 000000000..cf62c73e1
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/protocol/mock/MockMessage.java
@@ -0,0 +1,127 @@
+/*
+ * MockMessage.java
+ *
+ * Created on Jun 21, 2007, 3:10:21 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+package net.java.sip.communicator.impl.protocol.mock;
+
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * Message Impl.
+ * @author Damian Minkov
+ */
+public class MockMessage
+ implements Message
+{
+ private String textContent = null;
+
+ private String contentType = null;
+
+ private String contentEncoding = null;
+
+ private String messageUID = null;
+
+ private String subject = null;
+
+ MockMessage(String content,
+ String contentType,
+ String contentEncoding,
+ String subject)
+ {
+ this.textContent = content;
+ this.contentType = contentType;
+ this.contentEncoding = contentEncoding;
+ this.subject = subject;
+
+ //generate the uid
+ this.messageUID = String.valueOf( System.currentTimeMillis())
+ + String.valueOf(hashCode());
+ }
+
+ MockMessage(String content)
+ {
+ this.textContent = content;
+ this.contentType =
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE;
+ this.contentEncoding =
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_ENCODING;
+ this.subject = null;
+
+ //generate the uid
+ this.messageUID = String.valueOf( System.currentTimeMillis())
+ + String.valueOf(hashCode());
+ }
+
+ /**
+ * Returns the content of this message if representable in text form or null
+ * if this message does not contain text data.
+ * @return a String containing the content of this message or null if the
+ * message does not contain data representable in text form.
+ */
+ public String getContent()
+ {
+ return textContent;
+ }
+
+ /**
+ * Returns the MIME type for the message content.
+ * @return a String containing the mime type of the message contant.
+ */
+ public String getContentType()
+ {
+ return contentType;
+ }
+
+ /**
+ * Returns the MIME content encoding of this message.
+ * @return a String indicating the MIME encoding of this message.
+ */
+ public String getEncoding()
+ {
+ return contentEncoding;
+ }
+
+ /**
+ * Returns a unique identifier of this message.
+ * @return a String that uniquely represents this message in the scope of
+ * this protocol.
+ */
+ public String getMessageUID()
+ {
+ return messageUID;
+ }
+
+ /**
+ * Get the raw/binary content of an instant message.
+ * @return a byte[] array containing message bytes.
+ */
+ public byte[] getRawData()
+ {
+ return getContent().getBytes();
+ }
+
+ /**
+ * Returns the size of the content stored in this message.
+ * @return an int indicating the number of bytes that this message contains.
+ */
+ public int getSize()
+ {
+ return getContent().length();
+ }
+
+ /**
+ * Returns the subject of this message or null if the message contains no
+ * subject.
+ * @return the subject of this message or null if the message contains no
+ * subject.
+ */
+ public String getSubject()
+ {
+ return subject;
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/protocol/mock/MockMultiUserChat.java b/src/net/java/sip/communicator/impl/protocol/mock/MockMultiUserChat.java
new file mode 100644
index 000000000..ea063bac4
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/protocol/mock/MockMultiUserChat.java
@@ -0,0 +1,310 @@
+/*
+ * 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.mock;
+
+import java.util.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.event.*;
+
+/**
+ * Multiuser chat functionalites for the mock protocol.
+ * @author Damian Minkov
+ */
+public class MockMultiUserChat
+ implements OperationSetMultiUserChat,
+ ChatRoomJoinListener
+{
+ /**
+ * The protocol provider that created us.
+ */
+ private MockProvider provider = null;
+
+ private List existingChatRooms = new Vector();
+ private List joinedChatRooms = new Vector();
+
+ /**
+ * Currently registered invitation listeners.
+ */
+ private Vector invitationListeners = new Vector();
+
+ /**
+ * Currently registered invitation reject listeners.
+ */
+ private Vector invitationRejectListeners = new Vector();
+
+ /**
+ * Currently registered local user chat room presence listeners.
+ */
+ private Vector localUserChatRoomPresenceListeners = new Vector();
+
+ /**
+ * Creates an instance of this operation set keeping a reference to the
+ * parent protocol provider and presence operation set.
+ *
+ * @param provider The provider instance that creates us.
+ */
+ public MockMultiUserChat(MockProvider provider)
+ {
+ this.provider = provider;
+ }
+
+ /**
+ * Returns the List of Strings indicating chat rooms
+ * currently available on the server that this protocol provider is
+ * connected to.
+ *
+ * @return a java.util.List of the name Strings for chat
+ * rooms that are currently available on the server that this protocol
+ * provider is connected to.
+ *
+ * @throws OperationFailedException if we faile retrieving this list from
+ * the server.
+ * @throws OperationNotSupportedException if the server does not support
+ * multi user chat
+ */
+ public List getExistingChatRooms()
+ throws OperationFailedException,
+ OperationNotSupportedException
+ {
+ return existingChatRooms;
+ }
+
+ /**
+ * Returns a list of the chat rooms that we have joined and are currently
+ * active in.
+ *
+ * @return a List of the rooms where the user has joined using a
+ * given connection.
+ */
+ public List getCurrentlyJoinedChatRooms()
+ {
+ return joinedChatRooms;
+ }
+
+ /**
+ * Returns a list of the chat rooms that chatRoomMember has joined
+ * and is currently active in.
+ *
+ * @param chatRoomMember the chatRoomMember whose current ChatRooms we will
+ * be querying.
+ * @return a list of the chat rooms that chatRoomMember has
+ * joined and is currently active in.
+ *
+ * @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 List getCurrentlyJoinedChatRooms(ChatRoomMember chatRoomMember)
+ throws OperationFailedException,
+ OperationNotSupportedException
+ {
+ List result = new Vector();
+
+ Iterator iter = joinedChatRooms.iterator();
+
+ while(iter.hasNext())
+ {
+ ChatRoom elem = (ChatRoom)iter.next();
+ if(elem.getMembers().contains(chatRoomMember))
+ result.add(elem);
+ }
+
+ return result;
+ }
+
+ /**
+ * Creates a room with the named roomName and according to the
+ * specified roomProperties on the server that this protocol
+ * provider is currently connected to. When the method returns the room the
+ * local user will not have joined it and thus will not receive messages on
+ * it until the ChatRoom.join() method is called.
+ *
+ * @param roomName the name of the ChatRoom 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 existant + * room or user has no permissions to create a chat room). + * @throws OperationNotSupportedException if chat room creation is not + * supported by this server + * + * @return the newly created ChatRoom named roomName. + */ + public ChatRoom createChatRoom(String roomName, Hashtable roomProperties) + throws OperationFailedException, + OperationNotSupportedException + { + MockChatRoom room = new MockChatRoom(provider, this, roomName); + existingChatRooms.add(room); + room.addJoinListener(this); + return room; + } + + /** + * Returns a reference to a chatRoom named roomName or null if no + * such room exists. + *
+ * @param roomName the name of the ChatRoom that we're looking for. + * @return the ChatRoom named roomName 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 ChatRoom findRoom(String roomName) + throws OperationFailedException, + OperationNotSupportedException + { + Iterator iter = existingChatRooms.iterator(); + while(iter.hasNext()) + { + ChatRoom elem = (ChatRoom)iter.next(); + if(elem.getName().equals(roomName)) + return elem; + } + + return null; + } + + /** + * Informs the sender of an invitation that we decline their invitation. + * + * @param invitation the invitation we are rejecting. + */ + public void rejectInvitation(ChatRoomInvitation invitation) + { + ChatRoomInvitationRejectedEvent evt = + new ChatRoomInvitationRejectedEvent( + invitation, + null, + null, + invitation.getReason(), + new Date()); + + Iterator iter = invitationRejectListeners.iterator(); + while(iter.hasNext()) + { + ChatRoomInvitationRejectionListener elem = + (ChatRoomInvitationRejectionListener)iter.next(); + elem.invitationRejected(evt); + } + } + + /** + * Adds a listener to invitation notifications. The listener will be fired + * anytime an invitation is received. + * + * @param listener an invitation listener. + */ + public void addInvitationListener(ChatRoomInvitationListener listener) + { + if(!invitationListeners.contains(listener)) + invitationListeners.add(listener); + } + + /** + * Removes listener from the list of invitation listeners + * registered to receive invitation events. + * + * @param listener the invitation listener to remove. + */ + public void removeInvitationListener(ChatRoomInvitationListener listener) + { + invitationListeners.remove(listener); + } + + /** + * Adds a listener to invitation notifications. The listener will be fired + * anytime an invitation is received. + * + * @param listener an invitation listener. + */ + public void addInvitationRejectionListener( + ChatRoomInvitationRejectionListener listener) + { + if(!invitationRejectListeners.contains(listener)) + invitationRejectListeners.add(listener); + } + + /** + * Removes the given listener from the list of invitation listeners + * registered to receive events every time an invitation has been rejected. + * + * @param listener the invitation listener to remove. + */ + public void removeInvitationRejectionListener( + ChatRoomInvitationRejectionListener listener) + { + invitationRejectListeners.remove(listener); + } + + /** + * Returns true if contact 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 contact supports chatrooms. + */ + public boolean isMultiChatSupportedByContact(Contact contact) + { + throw new UnsupportedOperationException("Not supported yet."); + } + + /** + * Indicates that a new + * {@link net.java.sip.communicator.service.protocol.ChatRoom} has been + * joined. + * + * @param event the ChatRoomJoinedEvent containing the + * ChatRoom that has been joined + */ + public void chatRoomJoined(ChatRoomJoinedEvent event) + { + joinedChatRooms.add(event.getSourceChatRoom()); + existingChatRooms.add(event.getSourceChatRoom()); + } + + /** + * Adds a listener that will be notified of changes in our participation in + * a chat room such as us being kicked, joined, left. + * + * @param listener a local user participation listener. + */ + public void addPresenceListener( + LocalUserChatRoomPresenceListener listener) + { + if(!localUserChatRoomPresenceListeners.contains(listener)) + localUserChatRoomPresenceListeners.add(listener); + } + + /** + * Removes a listener that was being notified of changes in our + * participation in a room such as us being kicked, joined, left. + * + * @param listener a local user participation listener. + */ + public void removePresenceListener( + LocalUserChatRoomPresenceListener listener) + { + localUserChatRoomPresenceListeners.remove(listener); + } + + void fireLocalUserChatRoomPresenceChangeEvent( + LocalUserChatRoomPresenceChangeEvent evt) + { + Iterator iter = localUserChatRoomPresenceListeners.iterator(); + while(iter.hasNext()) + { + LocalUserChatRoomPresenceListener elem = + (LocalUserChatRoomPresenceListener)iter.next(); + elem.localUserPresenceChanged(evt); + } + } +} diff --git a/src/net/java/sip/communicator/impl/protocol/mock/MockProvider.java b/src/net/java/sip/communicator/impl/protocol/mock/MockProvider.java index 648987121..4e43444d1 100644 --- a/src/net/java/sip/communicator/impl/protocol/mock/MockProvider.java +++ b/src/net/java/sip/communicator/impl/protocol/mock/MockProvider.java @@ -66,6 +66,10 @@ public MockProvider(String userName) this.supportedOperationSets.put( OperationSetBasicInstantMessaging.class.getName(), mockBImOpSet); + + this.supportedOperationSets.put( + OperationSetMultiUserChat.class.getName(), + new MockMultiUserChat(this)); MockOperationSetBasicTelephony mockTelphonyOpSet = new MockOperationSetBasicTelephony(this); diff --git a/src/net/java/sip/communicator/service/msghistory/MessageHistoryService.java b/src/net/java/sip/communicator/service/msghistory/MessageHistoryService.java index f82237a91..04811b04d 100644 --- a/src/net/java/sip/communicator/service/msghistory/MessageHistoryService.java +++ b/src/net/java/sip/communicator/service/msghistory/MessageHistoryService.java @@ -8,6 +8,7 @@ import java.util.*; +import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.contactlist.*; import net.java.sip.communicator.service.msghistory.event.*; @@ -189,4 +190,164 @@ public Collection findLastMessagesBefore(MetaContact contact, Date date, int cou * @param listener HistorySearchProgressListener */ public void removeSearchProgressListener(MessageHistorySearchProgressListener listener); + + /** + * Returns all the messages exchanged in the supplied + * chat room after the given date + * + * @param room The chat room + * @param startDate Date the start date of the conversations + * @return Collection of MessageReceivedEvents or MessageDeliveredEvents + * @throws RuntimeException + */ + public Collection findByStartDate(ChatRoom room, Date startDate) + throws RuntimeException; + + /** + * Returns all the messages exchanged + * in the supplied chat room before the given date + * + * @param room The chat room + * @param endDate Date the end date of the conversations + * @return Collection of MessageReceivedEvents or MessageDeliveredEvents + * @throws RuntimeException + */ + public Collection findByEndDate(ChatRoom room, Date endDate) + throws RuntimeException; + + /** + * Returns all the messages exchanged + * in the supplied chat room between the given dates + * + * @param room The chat room + * @param startDate Date the start date of the conversations + * @param endDate Date the end date of the conversations + * @return Collection of MessageReceivedEvents or MessageDeliveredEvents + * @throws RuntimeException + */ + public Collection findByPeriod(ChatRoom room, Date startDate, Date endDate) + throws RuntimeException; + + /** + * Returns all the messages exchanged + * in the supplied chat room between the given dates and having the given + * keywords + * + * @param room The chat room + * @param startDate Date the start date of the conversations + * @param endDate Date the end date of the conversations + * @param keywords array of keywords + * @return Collection of MessageReceivedEvents or MessageDeliveredEvents + * @throws RuntimeException + */ + public Collection findByPeriod(ChatRoom room, + Date startDate, Date endDate, String[] keywords) + throws RuntimeException; + + /** + * Returns all the messages exchanged + * in the supplied chat room between the given dates and having the given + * keywords + * + * @param room The chat room + * @param startDate Date the start date of the conversations + * @param endDate Date the end date of the conversations + * @param keywords array of keywords + * @param caseSensitive is keywords search case sensitive + * @return Collection of MessageReceivedEvents or MessageDeliveredEvents + * @throws RuntimeException + */ + public Collection findByPeriod(ChatRoom room, Date startDate, Date endDate, + String[] keywords, boolean caseSensitive) + throws RuntimeException; + + /** + * Returns all the messages exchanged + * in the supplied room having the given keyword + * + * @param room The Chat room + * @param keyword keyword + * @return Collection of MessageReceivedEvents or MessageDeliveredEvents + * @throws RuntimeException + */ + public Collection findByKeyword(ChatRoom room, String keyword) + throws RuntimeException; + + /** + * Returns all the messages exchanged + * in the supplied chat room having the given keyword + * + * @param room The chat room + * @param keyword keyword + * @param caseSensitive is keywords search case sensitive + * @return Collection of MessageReceivedEvents or MessageDeliveredEvents + * @throws RuntimeException + */ + Collection findByKeyword(ChatRoom room, String keyword, + boolean caseSensitive) + throws RuntimeException; + + /** + * Returns all the messages exchanged + * in the supplied chat room having the given keywords + * + * @param room The chat room + * @param keywords keyword + * @return Collection of MessageReceivedEvents or MessageDeliveredEvents + * @throws RuntimeException + */ + public Collection findByKeywords(ChatRoom room, String[] keywords) + throws RuntimeException; + + /** + * Returns all the messages exchanged + * in the supplied chat room having the given keywords + * + * @param room The chat room + * @param keywords keyword + * @param caseSensitive is keywords search case sensitive + * @return Collection of MessageReceivedEvents or MessageDeliveredEvents + * @throws RuntimeException + */ + public Collection findByKeywords(ChatRoom room, String[] keywords, + boolean caseSensitive) + throws RuntimeException; + + /** + * Returns the supplied number of recent messages exchanged + * in the supplied chat room + * + * @param room The chat room + * @param count messages count + * @return Collection of MessageReceivedEvents or MessageDeliveredEvents + * @throws RuntimeException + */ + public Collection findLast(ChatRoom room, int count) + throws RuntimeException; + + /** + * Returns the supplied number of recent messages after the given date + * exchanged in the supplied chat room + * + * @param room The chat room + * @param date messages after date + * @param count messages count + * @return Collection of MessageReceivedEvents or MessageDeliveredEvents + * @throws RuntimeException + */ + public Collection findFirstMessagesAfter(ChatRoom room, Date date, int count) + throws RuntimeException; + + /** + * Returns the supplied number of recent messages before the given date + * exchanged in the supplied chat room + * + * @param room The chat room + * @param date messages before date + * @param count messages count + * @return Collection of MessageReceivedEvents or MessageDeliveredEvents + * @throws RuntimeException + */ + public Collection findLastMessagesBefore(ChatRoom room, Date date, int count) + throws RuntimeException; } diff --git a/src/net/java/sip/communicator/service/protocol/event/LocalUserChatRoomPresenceListener.java b/src/net/java/sip/communicator/service/protocol/event/LocalUserChatRoomPresenceListener.java index 939d7ec36..1b37512fe 100644 --- a/src/net/java/sip/communicator/service/protocol/event/LocalUserChatRoomPresenceListener.java +++ b/src/net/java/sip/communicator/service/protocol/event/LocalUserChatRoomPresenceListener.java @@ -21,8 +21,9 @@ public interface LocalUserChatRoomPresenceListener * Called to notify interested parties that a change in our presence in * a chat room has occured. Changes may include us being kicked, join, * left. - * @param evt the LocalUserChatRoomPresenceListener instance + * @param evt the LocalUserChatRoomPresenceChangeEvent instance * containing the chat room and the type, and reason of the change */ - public void localUserPresenceChanged(LocalUserChatRoomPresenceListener evt); + public void localUserPresenceChanged( + LocalUserChatRoomPresenceChangeEvent evt); } diff --git a/test/net/java/sip/communicator/slick/msghistory/TestMsgHistoryService.java b/test/net/java/sip/communicator/slick/msghistory/TestMsgHistoryService.java index d15ff45ab..06f30f2fc 100644 --- a/test/net/java/sip/communicator/slick/msghistory/TestMsgHistoryService.java +++ b/test/net/java/sip/communicator/slick/msghistory/TestMsgHistoryService.java @@ -34,6 +34,8 @@ public class TestMsgHistoryService private static final Logger logger = Logger.getLogger(TestMsgHistoryService.class); static final String TEST_CONTACT_NAME = "Mincho_Penchev"; + + static final String TEST_ROOM_NAME = "test_room"; /** * The provider that we use to make a dummy server-stored contactlist @@ -46,6 +48,7 @@ public class TestMsgHistoryService */ public static MockPersistentPresenceOperationSet mockPresOpSet = null; public static MockBasicInstantMessaging mockBImOpSet = null; + public static MockMultiUserChat mockMultiChat = null; private static ServiceReference msgHistoryServiceRef = null; public static MessageHistoryService msgHistoryService = null; @@ -81,6 +84,10 @@ public static Test suite() new TestMsgHistoryService("writeRecords")); suite.addTest( new TestMsgHistoryService("readRecords")); + suite.addTest( + new TestMsgHistoryService("writeRecordsToMultiChat")); + suite.addTest( + new TestMsgHistoryService("readRecordsFromMultiChat")); suite.addTest( new TestMsgHistoryService("testPurgeLocalContactListCopy")); @@ -114,6 +121,10 @@ public void setupContact() mockBImOpSet = (MockBasicInstantMessaging) supportedOperationSets.get( OperationSetBasicInstantMessaging.class.getName()); + + mockMultiChat = + (MockMultiUserChat) supportedOperationSets.get( + OperationSetMultiUserChat.class.getName()); msgHistoryServiceRef = MsgHistoryServiceLick.bc. @@ -367,6 +378,231 @@ public void readRecords() assertTrue("Message no found", msgs.contains(messagesToSend[2].getContent())); } + + public void writeRecordsToMultiChat() + { + try + { + ChatRoom room = mockMultiChat.createChatRoom("test_room", null); + room.join(); + +// ChatRoom room = mockMultiChat.findRoom(TEST_ROOM_NAME); +// room.joinAs(TEST_CONTACT_NAME); + + // First deliver message, so they are stored by the message history service + room.sendMessage(messagesToSend[0]); + + this.controlDate1 = new Date(); + + Object lock = new Object(); + synchronized (lock) + { + // wait a moment + try + { + lock.wait(200); + } + catch (InterruptedException ex) + { + } + } + + room.sendMessage(messagesToSend[1]); + + room.sendMessage(messagesToSend[2]); + + this.controlDate2 = new Date(); + synchronized (lock) + { + // wait a moment + try + { + lock.wait(200); + } + catch (InterruptedException ex) + { + } + } + + room.sendMessage(messagesToSend[3]); + + room.sendMessage(messagesToSend[4]); + } + catch(OperationFailedException ex) + { + fail("Failed to create room : " + ex.getMessage()); + logger.error("Failed to create room", ex); + } + catch(OperationNotSupportedException ex) + { + fail("Failed to create room : " + ex.getMessage()); + logger.error("Failed to create room", ex); + } + } + + /** + * tests all read methods (finders) + */ + public void readRecordsFromMultiChat() + { + ChatRoom room = null; + + try + { + room = mockMultiChat.findRoom(TEST_ROOM_NAME); + + }catch(Exception ex) + { + fail("Cannot find room!" + ex.getMessage()); + } + + /** + * This matches all written messages, they are minimum 5 + */ + Collection rs = msgHistoryService.findByKeyword(room, "test"); + + assertTrue("Nothing found findByKeyword ", !rs.isEmpty()); + + Vector msgs = getChatMessages(rs); + + assertTrue("Messages too few - findByKeyword", msgs.size() >= 5); + + /** + * Will test case sernsitive and insensitive search + */ + rs = msgHistoryService.findByKeyword(room, "Test", false); + + assertTrue("Nothing found findByKeyword caseINsensitive search", !rs.isEmpty()); + + msgs = getChatMessages(rs); + + assertTrue("Messages too few - findByKeyword", msgs.size() >= 5); + + rs = msgHistoryService.findByKeyword(room, "Test", true); + + assertFalse("Something found by findByKeyword casesensitive search", !rs.isEmpty()); + + /** + * This must match also many messages, as tests are run many times + * but the minimum is 3 + */ + rs = msgHistoryService.findByEndDate(room, controlDate2); + + assertTrue("Nothing found findByEndDate", !rs.isEmpty()); + + msgs = getChatMessages(rs); + + assertTrue("Messages too few - findByEndDate", msgs.size() >= 3); + + /** + * This must find also many messages but atleast one + */ + rs = msgHistoryService.findByKeywords( + room, + new String[]{"test", "word2"}); + + assertTrue("Nothing found findByKeywords", !rs.isEmpty()); + msgs = getChatMessages(rs); + assertTrue("Messages too few - findByKeywords", msgs.size() >= 1); + + /** + * Nothing to be found + */ + rs = msgHistoryService.findByKeywords( + room, + new String[]{"test1", "word2"}); + + assertFalse("Something found findByKeywords", !rs.isEmpty()); + + /** + * must find 2 messages + */ + rs = msgHistoryService.findByPeriod( + room, controlDate1, controlDate2); + + assertTrue("Nothing found findByPeriod", !rs.isEmpty()); + + msgs = getChatMessages(rs); + + assertEquals("Messages must be 2", msgs.size(), 2); + + assertTrue("Message no found", + msgs.contains(messagesToSend[1].getContent())); + assertTrue("Message no found", + msgs.contains(messagesToSend[2].getContent())); + + /** + * must find 1 record + */ + rs = msgHistoryService.findByPeriod( + room, controlDate1, controlDate2, new String[]{"word2"}); + + assertTrue("Nothing found findByPeriod", !rs.isEmpty()); + + msgs = getChatMessages(rs); + + assertEquals("Messages must be 1", msgs.size(), 1); + assertTrue("Message no found", + msgs.contains(messagesToSend[1].getContent())); + + /** + * must find 2 records + */ + rs = msgHistoryService.findByStartDate(room, controlDate2); + + assertTrue("Nothing found findByStartDate", !rs.isEmpty()); + msgs = getChatMessages(rs); + assertEquals("Messages must be 2", msgs.size(), 2); + assertTrue("Message no found", + msgs.contains(messagesToSend[3].getContent())); + assertTrue("Message no found", + msgs.contains(messagesToSend[4].getContent())); + + /** + * Must return exactly the last 3 messages + */ + rs = msgHistoryService.findLast(room, 3); + + assertTrue("Nothing found 8", !rs.isEmpty()); + msgs = getChatMessages(rs); + assertEquals("Messages must be 3", msgs.size(), 3); + assertTrue("Message no found", + msgs.contains(messagesToSend[2].getContent())); + assertTrue("Message no found", + msgs.contains(messagesToSend[3].getContent())); + assertTrue("Message no found", + msgs.contains(messagesToSend[4].getContent())); + + /** + * Must return exactly the 3 messages after controlDate1 + */ + rs = msgHistoryService.findFirstMessagesAfter(room, controlDate1, 3); + + assertTrue("Nothing found 9", !rs.isEmpty()); + msgs = getChatMessages(rs); + assertEquals("Messages must be 3", msgs.size(), 3); + assertTrue("Message no found", + msgs.contains(messagesToSend[1].getContent())); + assertTrue("Message no found", + msgs.contains(messagesToSend[2].getContent())); + assertTrue("Message no found", + msgs.contains(messagesToSend[3].getContent())); + + /** + * Must return exactly the 3 messages before controlDate2 + */ + rs = msgHistoryService.findLastMessagesBefore(room, controlDate2, 3); + + assertTrue("Nothing found 10", !rs.isEmpty()); + msgs = getChatMessages(rs); + assertEquals("Messages must be 3", msgs.size(), 3); + assertTrue("Message no found", + msgs.contains(messagesToSend[0].getContent())); + assertTrue("Message no found", + msgs.contains(messagesToSend[1].getContent())); + assertTrue("Message no found", + msgs.contains(messagesToSend[2].getContent())); + } /** * Removes the locally stored contact list copy. The purpose of this is to @@ -383,7 +619,7 @@ private Vector getMessages(Collection rs) Iterator iter = rs.iterator(); while (iter.hasNext()) { - Object item = (Object) iter.next(); + Object item = iter.next(); if(item instanceof MessageDeliveredEvent) result.add(((MessageDeliveredEvent)item).getSourceMessage().getContent()); else @@ -393,6 +629,25 @@ private Vector getMessages(Collection rs) return result; } + + private Vector getChatMessages(Collection rs) + { + Vector result = new Vector(); + Iterator iter = rs.iterator(); + while (iter.hasNext()) + { + Object item = iter.next(); + if(item instanceof ChatRoomMessageDeliveredEvent) + result.add(((ChatRoomMessageDeliveredEvent)item). + getMessage().getContent()); + else + if(item instanceof ChatRoomMessageReceivedEvent) + result.add(((ChatRoomMessageReceivedEvent)item). + getMessage().getContent()); + } + + return result; + } private void dumpResult(QueryResultSet rs)