From 7076dcd63d71db20af40cace061765f56514765c Mon Sep 17 00:00:00 2001 From: Emil Ivov Date: Wed, 29 Apr 2009 11:05:12 +0000 Subject: [PATCH] Significatnly stabilizes the meta contact list by fixing asynchronous contact loading and taking into account invalid xml node states. This should thus fix issue #598 : Losing the meta contact list although we'll wait a bit before closing it. --- .../impl/contactlist/MclStorageManager.java | 22 ++++++++-- .../MetaContactListServiceImpl.java | 42 +++++++++++-------- 2 files changed, 44 insertions(+), 20 deletions(-) diff --git a/src/net/java/sip/communicator/impl/contactlist/MclStorageManager.java b/src/net/java/sip/communicator/impl/contactlist/MclStorageManager.java index 6877b3d46..c72453f73 100644 --- a/src/net/java/sip/communicator/impl/contactlist/MclStorageManager.java +++ b/src/net/java/sip/communicator/impl/contactlist/MclStorageManager.java @@ -920,10 +920,14 @@ private void processGroupXmlNode(MetaContactListServiceImpl mclServImpl, * field in the contact descriptors. * @return a java.util.List containing contact descriptors. */ - private List extractProtoContacts( - Element metaContactNode, String accountID, - Map protoGroups) + private List + extractProtoContacts(Element metaContactNode, + String accountID, + Map protoGroups) { + if(logger.isTraceEnabled()) + logger.trace("Extracting proto contacts for " + + XMLUtils.getAttribute( metaContactNode, "uid")); List protoContacts = new LinkedList(); @@ -934,6 +938,11 @@ private List extractProtoContact { Node currentNode = children.item(i); + //for some reason every now and then we would get a null nodename + //... go figure + if (currentNode.getNodeName() == null) + continue; + if (currentNode.getNodeType() != Node.ELEMENT_NODE || !currentNode.getNodeName().equals(PROTO_CONTACT_NODE_NAME)) continue; @@ -997,6 +1006,13 @@ private Element createProtoContactNode(Contact protoContact) protoContactElement.setAttribute(ACCOUNT_ID_ATTR_NAME, protoContact .getProtocolProvider().getAccountID().getAccountUniqueID()); + if(logger.isTraceEnabled() + && protoContact.getParentContactGroup() == null) + { + logger.trace("the following contact looks weird:" + protoContact); + logger.trace("group:" + protoContact.getParentContactGroup()); + } + protoContactElement.setAttribute(PARENT_PROTO_GROUP_UID_ATTR_NAME, protoContact.getParentContactGroup().getUID()); diff --git a/src/net/java/sip/communicator/impl/contactlist/MetaContactListServiceImpl.java b/src/net/java/sip/communicator/impl/contactlist/MetaContactListServiceImpl.java index 77d1849df..f8ca53012 100644 --- a/src/net/java/sip/communicator/impl/contactlist/MetaContactListServiceImpl.java +++ b/src/net/java/sip/communicator/impl/contactlist/MetaContactListServiceImpl.java @@ -213,6 +213,8 @@ public void stop(BundleContext bc) if(opSetPersPresence !=null) { + opSetPersPresence + .removeContactPresenceStatusListener(this); opSetPersPresence .removeSubscriptionListener(clSubscriptionEventHandler); opSetPersPresence @@ -226,6 +228,8 @@ public void stop(BundleContext bc) if(opSetPresence != null) { + opSetPresence + .removeContactPresenceStatusListener(this); opSetPresence .removeSubscriptionListener(clSubscriptionEventHandler); } @@ -644,10 +648,10 @@ public MetaContactGroup findParentMetaContactGroup(MetaContact child) * with an appropriate code if the operation fails for some * reason. */ - public void createMetaContact( - ProtocolProviderService provider, - MetaContactGroup metaContactGroup, String contactID) throws - MetaContactListException + public void createMetaContact( ProtocolProviderService provider, + MetaContactGroup metaContactGroup, + String contactID) + throws MetaContactListException { if (! (metaContactGroup instanceof MetaContactGroupImpl)) { @@ -661,9 +665,9 @@ public void createMetaContact( contactID, false); //don't fire a PROTO_CONT_ADDED event we'll //fire our own event here. - fireMetaContactEvent( newMetaContact - , findParentMetaContactGroup(newMetaContact) - , MetaContactEvent.META_CONTACT_ADDED); + fireMetaContactEvent( newMetaContact, + findParentMetaContactGroup(newMetaContact), + MetaContactEvent.META_CONTACT_ADDED); } /** @@ -1595,14 +1599,13 @@ private void addContactGroupToMetaGroup(ContactGroup protoGroup, * Otherwise it would start a process where local contacts would be added on * the server. * - * @param provider - * the ProtocolProviderService that we've just detected. + * @param provider the ProtocolProviderService that we've just detected. */ - private void handleProviderAdded( - ProtocolProviderService provider) + private synchronized void handleProviderAdded( + ProtocolProviderService provider) { logger.debug("Adding protocol provider " - + provider.getProtocolName()); + + provider.getAccountID().getAccountUniqueID()); // check whether the provider has a persistent presence op set OperationSetPersistentPresence opSetPersPresence = @@ -1623,13 +1626,14 @@ private void handleProviderAdded( { storageManager.extractContactsForAccount( provider.getAccountID().getAccountUniqueID()); + logger.debug("All contacts loaded for account " + + provider.getAccountID().getAccountUniqueID()); } catch (XMLException exc) { logger.error("Failed to load contacts for account " + provider.getAccountID().getAccountUniqueID(), exc); } - synchronizeOpSetWithLocalContactList(opSetPersPresence); } else @@ -1672,6 +1676,12 @@ private void handleProviderRemoved( if(persPresOpSet == null) return; + //we don't gare about subscription and presence status events here any + //longer + persPresOpSet.removeContactPresenceStatusListener(this); + persPresOpSet.removeSubscriptionListener(clSubscriptionEventHandler); + persPresOpSet.removeServerStoredGroupChangeListener(clGroupEventHandler); + ContactGroup rootGroup = persPresOpSet.getServerStoredContactListRoot(); @@ -1976,8 +1986,7 @@ public void serviceChanged(ServiceEvent event) return; } - this - .handleProviderAdded( (ProtocolProviderService) sService); + this.handleProviderAdded( (ProtocolProviderService) sService); } else if (event.getType() == ServiceEvent.UNREGISTERING) { @@ -2289,8 +2298,7 @@ public void subscriptionRemoved(SubscriptionEvent evt) * ServerStoredGroupListeners. */ private class ContactListGroupListener - implements - ServerStoredGroupListener + implements ServerStoredGroupListener { /**