From b9ba0d4ad091da5d365cf8726eb6fd45a9672af3 Mon Sep 17 00:00:00 2001 From: Danny van Heumen Date: Sat, 12 Jul 2014 18:15:47 +0200 Subject: [PATCH] Basic, rough implementation of instant messaging. --- .../impl/protocol/irc/ChatRoomIrcImpl.java | 49 ++-- .../protocol/irc/ChatRoomMemberIrcImpl.java | 5 +- .../protocol/irc/ContactGroupIrcImpl.java | 195 +++++++++++++ .../impl/protocol/irc/ContactIrcImpl.java | 83 ++++++ .../impl/protocol/irc/IrcStack.java | 118 +++----- ...rationSetBasicInstantMessagingIrcImpl.java | 142 ++++++++++ .../irc/OperationSetMultiUserChatIrcImpl.java | 32 ++- ...OperationSetPersistentPresenceIrcImpl.java | 264 ++++++++++++++++++ .../irc/ProtocolProviderServiceIrcImpl.java | 51 +++- 9 files changed, 837 insertions(+), 102 deletions(-) create mode 100644 src/net/java/sip/communicator/impl/protocol/irc/ContactGroupIrcImpl.java create mode 100644 src/net/java/sip/communicator/impl/protocol/irc/ContactIrcImpl.java create mode 100644 src/net/java/sip/communicator/impl/protocol/irc/OperationSetBasicInstantMessagingIrcImpl.java create mode 100644 src/net/java/sip/communicator/impl/protocol/irc/OperationSetPersistentPresenceIrcImpl.java diff --git a/src/net/java/sip/communicator/impl/protocol/irc/ChatRoomIrcImpl.java b/src/net/java/sip/communicator/impl/protocol/irc/ChatRoomIrcImpl.java index cfd03253c..0b639dda4 100644 --- a/src/net/java/sip/communicator/impl/protocol/irc/ChatRoomIrcImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/irc/ChatRoomIrcImpl.java @@ -32,7 +32,7 @@ public class ChatRoomIrcImpl = Logger.getLogger(ChatRoomIrcImpl.class); /** - * The parent protocol service provider + * The parent protocol service provider. */ private final ProtocolProviderServiceIrcImpl parentProvider; @@ -47,7 +47,7 @@ public class ChatRoomIrcImpl private String chatSubject = ""; /** - * list of members of this chatRoom + * list of members of this chatRoom. */ private final Hashtable chatRoomMembers = new Hashtable(); @@ -113,7 +113,7 @@ public class ChatRoomIrcImpl * The nick name of the local user for this chat room. */ private String userNickName; - + /** * The role of the local user for this chat room. */ @@ -126,12 +126,12 @@ public class ChatRoomIrcImpl * @param chatRoomName the name of the chat room * @param parentProvider the protocol provider */ - public ChatRoomIrcImpl( String chatRoomName, - ProtocolProviderServiceIrcImpl parentProvider) + public ChatRoomIrcImpl(String chatRoomName, + ProtocolProviderServiceIrcImpl parentProvider) { this(chatRoomName, parentProvider, false); } - + /** * Creates an instance of ChatRoomIrcImpl, by specifying the room * name, the protocol provider and the isPrivate property. Private chat @@ -1164,6 +1164,7 @@ void prepUserRole(ChatRoomMemberRole role) public void setLocalUserRole(ChatRoomMemberRole role) throws OperationFailedException { + // TODO implement setLocalUserRole throw new UnsupportedOperationException("Not supported yet."); } @@ -1173,6 +1174,7 @@ public void setLocalUserRole(ChatRoomMemberRole role) */ public void grantAdmin(String address) { + // TODO implement grantAdmin throw new UnsupportedOperationException("Not supported yet."); } @@ -1182,6 +1184,7 @@ public void grantAdmin(String address) */ public void grantMembership(String address) { + // TODO implement grantMembership throw new UnsupportedOperationException("Not supported yet."); } @@ -1191,6 +1194,7 @@ public void grantMembership(String address) */ public void grantModerator(String address) { + // TODO implement grantModerator throw new UnsupportedOperationException("Not supported yet."); } @@ -1200,6 +1204,7 @@ public void grantModerator(String address) */ public void grantOwnership(String address) { + // TODO implement grantOwnership throw new UnsupportedOperationException("Not supported yet."); } @@ -1209,6 +1214,7 @@ public void grantOwnership(String address) */ public void grantVoice(String address) { + // TODO implement grantVoice throw new UnsupportedOperationException("Not supported yet."); } @@ -1218,6 +1224,7 @@ public void grantVoice(String address) */ public void revokeAdmin(String address) { + // TODO implement revokeAdmin throw new UnsupportedOperationException("Not supported yet."); } @@ -1230,6 +1237,7 @@ public void revokeAdmin(String address) */ public void revokeMembership(String address) { + // TODO implement revokeMembership throw new UnsupportedOperationException("Not supported yet."); } @@ -1240,6 +1248,7 @@ public void revokeMembership(String address) */ public void revokeModerator(String address) { + // TODO implement revokeModerator throw new UnsupportedOperationException("Not supported yet."); } @@ -1259,6 +1268,7 @@ public void revokeOwnership(String address) */ public void revokeVoice(String address) { + // TODO implement revokeVoice throw new UnsupportedOperationException("Not supported yet."); } @@ -1270,50 +1280,55 @@ public void revokeVoice(String address) public ConferenceDescription publishConference(ConferenceDescription cd, String name) { + // TODO implement publishConference return null; } /** * {@inheritDoc} - * - * Not implemented. */ @Override public Contact getPrivateContactByNickname(String name) { - return null; + return this.parentProvider.getPersistentPresence() + .findContactByID(name); } /** * {@inheritDoc} - * - * Not implemented. */ @Override - public void updatePrivateContactPresenceStatus(String nickname) { } + public void updatePrivateContactPresenceStatus(String nickname) + { + // TODO implement updatePrivateContactPresenceStatus + } /** * {@inheritDoc} - * - * Not implemented. */ @Override - public void updatePrivateContactPresenceStatus(Contact sourceContact) { } + public void updatePrivateContactPresenceStatus(Contact sourceContact) + { + // TODO implement updatePrivateContactPresenceStatus + } /** * Destroys the chat room. + * * @param reason the reason for destroying. * @param alternateAddress the alternate address * @return true if the room is destroyed. */ public boolean destroy(String reason, String alternateAddress) { + // IRC chat rooms cannot be destroyed return true; } /** - * Returns the ids of the users that has the member role in the room. - * When the room is member only, this are the users allowed to join. + * Returns the ids of the users that has the member role in the room. When + * the room is member only, this are the users allowed to join. + * * @return the ids of the users that has the member role in the room. */ @Override diff --git a/src/net/java/sip/communicator/impl/protocol/irc/ChatRoomMemberIrcImpl.java b/src/net/java/sip/communicator/impl/protocol/irc/ChatRoomMemberIrcImpl.java index e3110ed58..da3952dfa 100644 --- a/src/net/java/sip/communicator/impl/protocol/irc/ChatRoomMemberIrcImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/irc/ChatRoomMemberIrcImpl.java @@ -52,9 +52,8 @@ public class ChatRoomMemberIrcImpl * corresponding chat room */ public ChatRoomMemberIrcImpl(ProtocolProviderService parentProvider, - ChatRoom chatRoom, - String contactID, - ChatRoomMemberRole chatRoomMemberRole) + ChatRoom chatRoom, String contactID, + ChatRoomMemberRole chatRoomMemberRole) { if (parentProvider == null) throw new IllegalArgumentException( diff --git a/src/net/java/sip/communicator/impl/protocol/irc/ContactGroupIrcImpl.java b/src/net/java/sip/communicator/impl/protocol/irc/ContactGroupIrcImpl.java new file mode 100644 index 000000000..a598ef294 --- /dev/null +++ b/src/net/java/sip/communicator/impl/protocol/irc/ContactGroupIrcImpl.java @@ -0,0 +1,195 @@ +package net.java.sip.communicator.impl.protocol.irc; + +import java.util.*; + +import net.java.sip.communicator.service.protocol.*; + +public class ContactGroupIrcImpl + implements ContactGroup +{ + /** + * The protocol provider service instance. + */ + private final ProtocolProviderServiceIrcImpl provider; + + /** + * Group name. + */ + private final String name; + + /** + * Subgroups + */ + private final List subgroups = new ArrayList(); + + /** + * Contacts in this group. + */ + private final List contacts = new ArrayList(); + + /** + * Parent contact group. + */ + private ContactGroup parent; + + /** + * Contact Group IRC implementation. + * + * @param provider IRC protocol provider service instance. + */ + public ContactGroupIrcImpl(ProtocolProviderServiceIrcImpl provider) + { + this(provider, null, "root"); + } + + /** + * Contact Group IRC implementation. + * + * @param provider IRC protocol provider service instance. + * @param name Group name + */ + public ContactGroupIrcImpl(ProtocolProviderServiceIrcImpl provider, + ContactGroupIrcImpl parentGroup, String name) + { + if (provider == null) + throw new IllegalArgumentException("provider cannot be null"); + this.provider = provider; + this.parent = parentGroup; + if (name == null) + throw new IllegalArgumentException("name cannot be null"); + this.name = name; + } + + @Override + public Iterator subgroups() + { + return new ArrayList(this.subgroups).iterator(); + } + + @Override + public int countSubgroups() + { + return this.subgroups.size(); + } + + @Override + public ContactGroup getGroup(int index) + { + return this.subgroups.get(index); + } + + @Override + public ContactGroup getGroup(String groupName) + { + if (groupName == null) + return null; + for (ContactGroupIrcImpl group : this.subgroups) + { + if (groupName.equals(group.getGroupName())) + { + return group; + } + } + return null; + } + + @Override + public Iterator contacts() + { + return new ArrayList(this.contacts).iterator(); + } + + @Override + public int countContacts() + { + return this.contacts.size(); + } + + @Override + public Contact getContact(String id) + { + if (id == null) + return null; + for (ContactIrcImpl contact : this.contacts) + { + if (id.equals(contact.getAddress())) + { + return contact; + } + } + return null; + } + + @Override + public boolean canContainSubgroups() + { + return true; + } + + @Override + public String getGroupName() + { + return this.name; + } + + @Override + public ProtocolProviderServiceIrcImpl getProtocolProvider() + { + return this.provider; + } + + @Override + public ContactGroup getParentContactGroup() + { + return this.parent; + } + + @Override + public boolean isPersistent() + { + return false; + } + + @Override + public String getUID() + { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean isResolved() + { + return false; + } + + @Override + public String getPersistentData() + { + return null; + } + + /** + * Add contact to the group. + * + * @param contact Contact to be added. + */ + public void addContact(ContactIrcImpl contact) + { + if (contact == null) + throw new IllegalArgumentException("contact cannot be null"); + this.contacts.add(contact); + } + + /** + * Add group as subgroup to this group. + * + * @param group the group + */ + public void addSubGroup(ContactGroupIrcImpl group) + { + if (group == null) + throw new IllegalArgumentException("group cannot be null"); + this.subgroups.add(group); + } +} diff --git a/src/net/java/sip/communicator/impl/protocol/irc/ContactIrcImpl.java b/src/net/java/sip/communicator/impl/protocol/irc/ContactIrcImpl.java new file mode 100644 index 000000000..745998b33 --- /dev/null +++ b/src/net/java/sip/communicator/impl/protocol/irc/ContactIrcImpl.java @@ -0,0 +1,83 @@ +package net.java.sip.communicator.impl.protocol.irc; + +import net.java.sip.communicator.service.protocol.*; + +public class ContactIrcImpl + extends AbstractContact +{ + private ProtocolProviderServiceIrcImpl provider; + + private String id; + + public ContactIrcImpl(ProtocolProviderServiceIrcImpl provider, String id) + { + if (provider == null) + throw new IllegalArgumentException("provider cannot be null"); + this.provider = provider; + if (id == null) + throw new IllegalArgumentException("id cannot be null"); + this.id = id; + } + + @Override + public String getAddress() + { + return this.id; + } + + @Override + public String getDisplayName() + { + return this.id; + } + + @Override + public byte[] getImage() + { + return null; + } + + @Override + public PresenceStatus getPresenceStatus() + { + return IrcStatusEnum.ONLINE; + } + + @Override + public ContactGroup getParentContactGroup() + { + // TODO Auto-generated method stub + return null; + } + + @Override + public ProtocolProviderService getProtocolProvider() + { + return this.provider; + } + + @Override + public boolean isPersistent() + { + return false; + } + + @Override + public boolean isResolved() + { + return false; + } + + @Override + public String getPersistentData() + { + return null; + } + + @Override + public String getStatusMessage() + { + return null; + } + +} diff --git a/src/net/java/sip/communicator/impl/protocol/irc/IrcStack.java b/src/net/java/sip/communicator/impl/protocol/irc/IrcStack.java index 71f899eb4..bb08759e2 100644 --- a/src/net/java/sip/communicator/impl/protocol/irc/IrcStack.java +++ b/src/net/java/sip/communicator/impl/protocol/irc/IrcStack.java @@ -13,9 +13,8 @@ import javax.net.ssl.*; import net.java.sip.communicator.impl.protocol.irc.ModeParser.ModeEntry; +import net.java.sip.communicator.impl.protocol.irc.OperationSetBasicInstantMessagingIrcImpl.IrcMessage; import net.java.sip.communicator.service.certificate.*; -import net.java.sip.communicator.service.gui.*; -import net.java.sip.communicator.service.muc.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.util.*; @@ -405,7 +404,6 @@ public void setSubject(ChatRoomIrcImpl chatroom, String subject) */ public boolean isJoined(ChatRoomIrcImpl chatroom) { - // TODO Do we really consider a joining attempt as joined? return this.joined.get(chatroom.getIdentifier()) != null; } @@ -784,6 +782,18 @@ public void message(ChatRoomIrcImpl chatroom, String message) this.irc.message(target, message); } + /** + * Send an IRC message. + * + * @param contact The contact to send the message to. + * @param message The message to send. + */ + public void message(Contact contact, String message) + { + String target = contact.getAddress(); + this.irc.message(target, message); + } + /** * Prepare a chat room for initial opening. * @@ -796,6 +806,10 @@ private void prepareChatRoom(final ChatRoomIrcImpl chatRoom, final IRCTopic topic = channel.getTopic(); chatRoom.updateSubject(topic.getValue()); + OperationSetPersistentPresenceIrcImpl opSetPersistentPresence = + this.provider.getPersistentPresence(); + ContactGroupIrcImpl nonPersistentGroup = + opSetPersistentPresence.getNonPersistentGroup(); for (IRCUser user : channel.getUsers()) { // TODO Correctly gather active member statuses and choose strongest @@ -814,6 +828,14 @@ private void prepareChatRoom(final ChatRoomIrcImpl chatRoom, new ChatRoomMemberIrcImpl(this.provider, chatRoom, user.getNick(), role); chatRoom.addChatRoomMember(member.getContactAddress(), member); + + // FIXME working on persistent presence + // Prepare Contact and MetaContact + // ContactIrcImpl sourceContact = + // opSetPersistentPresence.createVolatileContact( + // member.getContactAddress(), true); + // opSetPersistentPresence.fireSubscriptionEvent(sourceContact, + // nonPersistentGroup, SubscriptionEvent.SUBSCRIPTION_CREATED); } } @@ -905,7 +927,15 @@ public void onServerNumericMessage(ServerNumericMessage msg) IrcStack.this.joined.put(channelName, chatRoom); } IrcStack.this.irc.addListener(new ChatRoomListener(chatRoom)); - openChatRoomWindow(chatRoom); + try + { + IrcStack.this.provider.getMUC() + .openChatRoomWindow(chatRoom); + } + catch (NullPointerException e) + { + LOGGER.error("failed to open chat room window", e); + } IrcStack.this.prepareChatRoom(chatRoom, channel); IrcStack.this.provider.getMUC().fireLocalUserPresenceEvent( chatRoom, @@ -924,38 +954,6 @@ public void onServerNumericMessage(ServerNumericMessage msg) } } - /** - * Open a chat room window. - * - * In IRC a situation may occur where the user gets joined to a channel - * without Jitsi initiating the joining activity. This "unannounced" - * join event, must also be handled and we should display the chat room - * window in that case, to alert the user that this happened. - * - * TODO Move this operation to somewhere "higher" up on the chain. Maybe - * in the ProtocolProviderService implementation, e.g. as a - * (conditional) operation in a fireLocalUserPresence call? (The IRC - * client glue should not be bothered by whether or not the chat room - * window is actually opened or not ...) - * - * @param chatRoom the chat room - */ - private void openChatRoomWindow(ChatRoomIrcImpl chatRoom) - { - MUCService mucService = IrcActivator.getMUCService(); - UIService uiService = IrcActivator.getUIService(); - try - { - ChatRoomWrapper wrapper = - mucService.getChatRoomWrapperByChatRoom(chatRoom, true); - uiService.openChatRoomWindow(wrapper); - } - catch (NullPointerException e) - { - LOGGER.error("failed to open chat room window", e); - } - } - /** * Print out received errors for debugging purposes and may be for * expected errors that can be acted upon. @@ -994,47 +992,13 @@ public void onUserPrivMessage(final UserPrivMsg msg) { final String user = msg.getSource().getNick(); final String text = Utils.parse(msg.getText()); - ChatRoomIrcImpl chatroom; - synchronized (IrcStack.this.joined) - { - chatroom = IrcStack.this.joined.get(user); - if (chatroom == null) - { - OperationSetMultiUserChatIrcImpl muc = - IrcStack.this.provider.getMUC(); - chatroom = muc.findOrCreateRoom(user); - IrcStack.this.joined - .put(chatroom.getIdentifier(), chatroom); - chatroom = initiatePrivateChatRoom(user, chatroom); - } - } - deliverReceivedMessageToPrivateChat(chatroom, user, text); - } - - /** - * Deliver a private message to the provided chat room. - * - * @param chatroom the chat room - * @param user the source user - * @param text the message - */ - private void deliverReceivedMessageToPrivateChat( - ChatRoomIrcImpl chatroom, String user, String text) - { - ChatRoomMember member = chatroom.getChatRoomMember(user); - if (member == null) - { - // TODO check should not be necessary, but sometimes null is - // still returned. - LOGGER - .warn("Got null member from chatroom, but expected message" - + "source member '" + user + "' to be present."); - return; - } - MessageIrcImpl message = - new MessageIrcImpl(text, "text/html", "UTF-8", null); - chatroom.fireMessageReceivedEvent(message, member, new Date(), - ChatRoomMessageReceivedEvent.CONVERSATION_MESSAGE_RECEIVED); + IrcMessage message = + new OperationSetBasicInstantMessagingIrcImpl.IrcMessage(text); + Contact from = + IrcStack.this.provider.getPersistentPresence().findContactByID( + user); + IrcStack.this.provider.getBasicInstantMessaging() + .fireMessageReceived(message, from); } /** diff --git a/src/net/java/sip/communicator/impl/protocol/irc/OperationSetBasicInstantMessagingIrcImpl.java b/src/net/java/sip/communicator/impl/protocol/irc/OperationSetBasicInstantMessagingIrcImpl.java new file mode 100644 index 000000000..b91d01f94 --- /dev/null +++ b/src/net/java/sip/communicator/impl/protocol/irc/OperationSetBasicInstantMessagingIrcImpl.java @@ -0,0 +1,142 @@ +package net.java.sip.communicator.impl.protocol.irc; + +import net.java.sip.communicator.service.protocol.*; + +public class OperationSetBasicInstantMessagingIrcImpl + extends AbstractOperationSetBasicInstantMessaging +{ + /** + * IRC protocol provider service. + */ + private final ProtocolProviderServiceIrcImpl provider; + + /** + * Constructor. + * + * @param provider IRC provider service. + */ + public OperationSetBasicInstantMessagingIrcImpl( + ProtocolProviderServiceIrcImpl provider) + { + if (provider == null) + throw new IllegalArgumentException("provider cannot be null"); + this.provider = provider; + } + + /** + * Create a new message. + * + * {@inheritDoc} + * + * @param content Message content + * @param contentType Message content type + * @param contentEncoding message encoding + * @param subject Message subject + */ + @Override + public Message createMessage(String content, String contentType, + String contentEncoding, String subject) + { + return new IrcMessage(content, contentType, contentEncoding, subject); + } + + /** + * Send instant message. + * + * @param to contact to send message to + * @param message message to send + * @throws IllegalStateException in case of bad internal state + * @throws IllegalArgumentException in case invalid arguments have been + * passed + */ + @Override + public void sendInstantMessage(Contact to, Message message) + throws IllegalStateException, + IllegalArgumentException + { + this.provider.getIrcStack().message(to, message.getContent()); + } + + /** + * Check if offline messaging is supported. + * + * @return returns true if offline messaging is supported or false + * otherwise. + */ + @Override + public boolean isOfflineMessagingSupported() + { + return false; + } + + /** + * Test content type support. + * + * {@inheritDoc} + * + * @param contentType contentType to test + * @return returns true if content type is supported + */ + @Override + public boolean isContentTypeSupported(String contentType) + { + return OperationSetBasicInstantMessaging.HTML_MIME_TYPE + .equalsIgnoreCase(contentType); + } + + /** + * {@inheritDoc} + * + * @param message the received message + * @param contactId the sender + */ + @Override + protected void fireMessageReceived(Message message, Contact from) + { + super.fireMessageReceived(message, from); + } + + /** + * Implementation of an IRC basic instant message. + * + * @author danny + */ + static class IrcMessage + extends AbstractMessage + { + /** + * Constructor. + * + * @param message instant message + * @param contentType Message content type + * @param contentEncoding Message content encoding + * @param subject Message subject + */ + IrcMessage(String message, String contentType, + String contentEncoding, String subject) + { + super(message, contentType, contentEncoding, subject); + } + + /** + * Constructor for simple messages. + * + * @param message instant message + */ + IrcMessage(String message) { + this(message, OperationSetBasicInstantMessaging.HTML_MIME_TYPE, + OperationSetBasicInstantMessaging.DEFAULT_MIME_ENCODING, ""); + } + + /** + * Constructor. + * + * @param message instant message + */ + private IrcMessage(String message, String contentType, + String contentEncoding, String subject, String UUID) + { + super(message, contentType, contentEncoding, subject, UUID); + } + } +} diff --git a/src/net/java/sip/communicator/impl/protocol/irc/OperationSetMultiUserChatIrcImpl.java b/src/net/java/sip/communicator/impl/protocol/irc/OperationSetMultiUserChatIrcImpl.java index 0f62d492f..c523d2fd1 100644 --- a/src/net/java/sip/communicator/impl/protocol/irc/OperationSetMultiUserChatIrcImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/irc/OperationSetMultiUserChatIrcImpl.java @@ -8,8 +8,11 @@ import java.util.*; +import net.java.sip.communicator.service.gui.*; +import net.java.sip.communicator.service.muc.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; +import net.java.sip.communicator.util.*; /** * Allows creating, configuring, joining and administering of individual @@ -23,6 +26,12 @@ public class OperationSetMultiUserChatIrcImpl extends AbstractOperationSetMultiUserChat { + /** + * Logger. + */ + private static final Logger LOGGER = Logger + .getLogger(OperationSetMultiUserChatIrcImpl.class); + /** * A call back to the IRC provider that created us. */ @@ -312,11 +321,30 @@ protected ChatRoomMemberIrcImpl findSystemMember() /** * {@inheritDoc} * - * Always returns false. + * Always returns true. */ @Override public boolean isPrivateMessagingContact(String contactAddress) { - return false; + return true; + } + + /** + * Open a chat room window. + * + * In IRC a situation may occur where the user gets joined to a channel + * without Jitsi initiating the joining activity. This "unannounced" join + * event, must also be handled and we should display the chat room window in + * that case, to alert the user that this happened. + * + * @param chatRoom the chat room + */ + void openChatRoomWindow(ChatRoomIrcImpl chatRoom) + { + MUCService mucService = IrcActivator.getMUCService(); + UIService uiService = IrcActivator.getUIService(); + ChatRoomWrapper wrapper = + mucService.getChatRoomWrapperByChatRoom(chatRoom, true); + uiService.openChatRoomWindow(wrapper); } } diff --git a/src/net/java/sip/communicator/impl/protocol/irc/OperationSetPersistentPresenceIrcImpl.java b/src/net/java/sip/communicator/impl/protocol/irc/OperationSetPersistentPresenceIrcImpl.java new file mode 100644 index 000000000..f7661808f --- /dev/null +++ b/src/net/java/sip/communicator/impl/protocol/irc/OperationSetPersistentPresenceIrcImpl.java @@ -0,0 +1,264 @@ +/* + * Jitsi, 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.irc; + +import java.util.*; + +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.service.protocol.event.*; +import net.java.sip.communicator.util.*; + +/** + * Implementation of support for Persistent Presence for IRC. + * + * @author Danny van Heumen + */ +public class OperationSetPersistentPresenceIrcImpl extends AbstractOperationSetPersistentPresence +{ + /** + * Logger. + */ + private final Logger LOGGER = Logger + .getLogger(OperationSetPersistentPresenceIrcImpl.class); + + /** + * Root contact group for IRC contacts. + */ + private final ContactGroupIrcImpl rootGroup = new ContactGroupIrcImpl(this.parentProvider); + + /** + * IRC implementation for OperationSetPersistentPresence. + * + * @param parentProvider IRC instance of protocol provider service. + */ + protected OperationSetPersistentPresenceIrcImpl( + ProtocolProviderServiceIrcImpl parentProvider) + { + super(parentProvider); + } + + ContactIrcImpl createVolatileContact(String id) + { + ContactIrcImpl newVolatileContact = + new ContactIrcImpl(this.parentProvider, id); + + // Check whether a volatile group already exists and if not create + // one + ContactGroupIrcImpl volatileGroup = getNonPersistentGroup(); + + // if the parent group is null then add necessary create the group + if (volatileGroup == null) + { + volatileGroup = + new ContactGroupIrcImpl(this.parentProvider, this.rootGroup, + IrcActivator.getResources().getI18NString( + "service.gui.NOT_IN_CONTACT_LIST_GROUP_NAME")); + + this.rootGroup.addSubGroup(volatileGroup); + + this.fireServerStoredGroupEvent(volatileGroup, + ServerStoredGroupEvent.GROUP_CREATED_EVENT); + } + volatileGroup.addContact(newVolatileContact); + + this.fireSubscriptionEvent(newVolatileContact, volatileGroup, + SubscriptionEvent.SUBSCRIPTION_CREATED); + + return newVolatileContact; + } + + ContactGroupIrcImpl getNonPersistentGroup() + { + String groupName + = IrcActivator.getResources().getI18NString( + "service.gui.NOT_IN_CONTACT_LIST_GROUP_NAME"); + + for (int i = 0; i < getRootGroup().countSubgroups(); i++) + { + ContactGroupIrcImpl gr = + (ContactGroupIrcImpl)getRootGroup().getGroup(i); + + if(!gr.isPersistent() && gr.getGroupName().equals(groupName)) + return gr; + } + + return null; + } + + public ContactGroup getRootGroup() + { + return rootGroup; + } + + @Override + public void subscribe(String contactIdentifier) + throws IllegalArgumentException, + IllegalStateException, + OperationFailedException + { + System.out.println("subscribe(\"" + contactIdentifier + "\") called"); + // TODO Auto-generated method stub + } + + @Override + public void subscribe(ContactGroup parent, String contactIdentifier) + throws IllegalArgumentException, + IllegalStateException, + OperationFailedException + { + System.out.println("subscribe(\"" + parent.getGroupName() + "\", \"" + + contactIdentifier + "\") called"); + // TODO Auto-generated method stub + } + + @Override + public void unsubscribe(Contact contact) + throws IllegalArgumentException, + IllegalStateException, + OperationFailedException + { + System.out.println("unsubscribe(\"" + contact.getAddress() + + "\") called"); + // TODO Auto-generated method stub + } + + @Override + public void createServerStoredContactGroup(ContactGroup parent, + String groupName) throws OperationFailedException + { + // TODO Auto-generated method stub + + } + + @Override + public void removeServerStoredContactGroup(ContactGroup group) + throws OperationFailedException + { + // TODO Auto-generated method stub + + } + + @Override + public void renameServerStoredContactGroup(ContactGroup group, + String newName) + { + // TODO Auto-generated method stub + + } + + @Override + public void moveContactToGroup(Contact contactToMove, ContactGroup newParent) + throws OperationFailedException + { + // TODO Auto-generated method stub + + } + + @Override + public ContactGroup getServerStoredContactListRoot() + { + return this.rootGroup; + } + + @Override + public Contact createUnresolvedContact(String address, + String persistentData, ContactGroup parentGroup) + { + LOGGER.warn("Unresolved contact: " + address + " " + persistentData + + " group: " + parentGroup.getGroupName()); + // TODO Auto-generated method stub + return null; + } + + @Override + public ContactGroup createUnresolvedContactGroup(String groupUID, + String persistentData, ContactGroup parentGroup) + { + LOGGER.warn("Unresolved contactgroup: " + groupUID + " " + + persistentData + " parent: " + parentGroup.getGroupName()); + // TODO Auto-generated method stub + return null; + } + + @Override + public PresenceStatus getPresenceStatus() + { + // TODO Auto-generated method stub + return null; + } + + @Override + public void publishPresenceStatus(PresenceStatus status, + String statusMessage) + throws IllegalArgumentException, + IllegalStateException, + OperationFailedException + { + // TODO Auto-generated method stub + + } + + @Override + public Iterator getSupportedStatusSet() + { + // TODO Auto-generated method stub + return null; + } + + @Override + public PresenceStatus queryContactStatus(String contactIdentifier) + throws IllegalArgumentException, + IllegalStateException, + OperationFailedException + { + // TODO Auto-generated method stub + return null; + } + + @Override + public Contact findContactByID(String contactID) + { + // FIXME DEBUG + LOGGER.warn("findContactByID(\"" + contactID + "\") called"); + if (contactID == null) + return null; + Contact contact = this.rootGroup.getContact(contactID); + if (contact != null) + return contact; + Iterator groups = this.rootGroup.subgroups(); + while (groups.hasNext()) + { + ContactGroup group = groups.next(); + contact = group.getContact(contactID); + if (contact != null) + return contact; + } + // FIXME currently just creates a new volatile contact + return createVolatileContact(contactID); + } + + @Override + public void setAuthorizationHandler(AuthorizationHandler handler) + { + // TODO Auto-generated method stub + + } + + @Override + public String getCurrentStatusMessage() + { + // TODO Auto-generated method stub + return null; + } + + @Override + public Contact createUnresolvedContact(String address, String persistentData) + { + // TODO Auto-generated method stub + return null; + } +} diff --git a/src/net/java/sip/communicator/impl/protocol/irc/ProtocolProviderServiceIrcImpl.java b/src/net/java/sip/communicator/impl/protocol/irc/ProtocolProviderServiceIrcImpl.java index f4c307873..eb0a093aa 100644 --- a/src/net/java/sip/communicator/impl/protocol/irc/ProtocolProviderServiceIrcImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/irc/ProtocolProviderServiceIrcImpl.java @@ -42,6 +42,16 @@ public class ProtocolProviderServiceIrcImpl */ private OperationSetMultiUserChatIrcImpl multiUserChat; + /** + * The operation set for instant messaging. + */ + private OperationSetBasicInstantMessagingIrcImpl instantMessaging; + + /** + * The operation set for persistent presence. + */ + private OperationSetPersistentPresenceIrcImpl persistentPresence; + /** * Indicates whether or not the provider is initialized and ready for use. */ @@ -93,9 +103,19 @@ protected void initialize(String userID, AccountID accountID) OperationSetMultiUserChat.class, multiUserChat); - // TODO Implement OperationSetPersistentPresence and - // OperationSetBasicInstantMessaging in order to support private - // messaging. + // Initialize basic instant messaging + this.instantMessaging = + new OperationSetBasicInstantMessagingIrcImpl(this); + + addSupportedOperationSet(OperationSetBasicInstantMessaging.class, + this.instantMessaging); + + //Initialize persistent presence + persistentPresence = + new OperationSetPersistentPresenceIrcImpl(this); + + addSupportedOperationSet(OperationSetPersistentPresence.class, + persistentPresence); // TODO Implement OperationSetServerStoredAccountInfo so we can // suggest a display name to use when adding new chat rooms? @@ -114,10 +134,35 @@ protected void initialize(String userID, AccountID accountID) } } + /** + * Get the Multi User Chat implementation. + * + * @return returns the Multi User Chat implementation + */ public OperationSetMultiUserChatIrcImpl getMUC() { return this.multiUserChat; } + + /** + * Get the Basic Instant Messaging implementation. + * + * @return returns the Basic Instant Messaging implementation + */ + public OperationSetBasicInstantMessagingIrcImpl getBasicInstantMessaging() + { + return this.instantMessaging; + } + + /** + * Get the Persistent Presence implementation. + * + * @return returns the Persistent Presence implementation. + */ + public OperationSetPersistentPresenceIrcImpl getPersistentPresence() + { + return this.persistentPresence; + } /** * Returns the AccountID that uniquely identifies the account represented