BUG? vCard::saveVCard invalid typecast

I’m not sure why this has cropped up only now but I’m getting an exception in saveVCard due to the typecast on line 596 of revision 11561:

var vcardExtNode:XML = vcardExt.getNode() as XML;

As of my latest update that cast always returns null.

I was able to work around it by changing that line to:

**
**

var vcardExtNode:XML = new XML(vcardExt.getNode().toString());

What I don’t understand is why I’m seeing this problem only now. That cast has existed since revision 11196 checked in August 22, 2009?

It is most probably because VCard was one of the first classes which I “upgraded” to use XML instead of XMLNode, but there might be some remainders like this.

getNode() returns XMLNode, that is why the casting is incorrect.

Latest trunk has fixed version.

That was my assumption as well. However, what I don’t understand is why it has apparently worked until now?

Code in trunk is still wrong. vcardExtNode is never appended to the vcardExt. Avatar data will not be sended to the server.

I agree. It looks like the problem started with revision 11196 when we started converting from XMLNode to XML, which introduced the typecast problem in question. I’m not entirely sure how to fix this. I have a working version of VCard.as with avatar upload support that predates revision 11196 but I don’t think we want to go that route as it would require re-implementing all of the other changes that have come since, excluding the switch over to XML instead of XMLNode.

Failing that, we need to figure out how to get the contents of vcardExtNode (which is an XML object) into vcardExt (which is an Extension object). I don’t see any obvious or clean ways to do this.

Anyone have any ideas?

Here’s a temporary fix. I reverted the move to XML, re-implemented saveVCard to handle avatars and some of the code cleanup that had been added. I’ve not exhaustively tested all of the implemented vCard attributes but I have confirmed that both nickname and avatar are working as expected. Attached is the merged source file and a corresponding patch created agains the head.

Code reviews welcome.
vCard Revert to XMLNode Patch.txt.zip (3897 Bytes)
VCard.as.zip (4994 Bytes)

Instead of reverting back so much, rather try the following code to the end of the *saveVCard *method in VCard.as:

var xmlDoc:XMLDocument = new XMLDocument(vcardExtNode.toString());
vcardExt.setNode(xmlDoc.firstChild);

Just before the iq.addExtension( vcardExt ); line, around ~895.

Well that’s a far better solution. Not sure how I missed sedNode() but after a brief test, it appears to work as expected. Below is a patch containing your proposed change. Please let me know if you see anything I missed.

Thanks for pointing out the right way to solve that.
vCard Save Patch.txt.zip (1021 Bytes)

In my opinion in VCard class there are to bugs:

  1. At the end of the method public function _vCardSent( resultIQ:IQ ):void suposed to be dispatched event VCardEvent.AVATAR_SENT. Don’t you think?

  2. When user upload avatar image cache will not be cleared. In method public function _vCardSent( resultIQ:IQ ):void:

delete cache[ resultIQ.to.unescaped.toString() ]; // Force profile refresh on next view

suposed to be:

delete cache[resultIQ.to.unescaped.bareJID];

Would you mind posting a patch?

patch:
xiff-vcard-patch.txt.zip (425 Bytes)

Seems reasonable to have the dispatch for sent, but I do not grasp the idea why the deletion should be by using bareJID where simply toString has been used othervise?

Added the dispatching of an avatar sent event in revision 11659.

Avatar is saved in cache object like this: cache[“xxx@xxx.com”], but cleared like this: delete cache[“xxx@xxx.com/xiff”]. Cache clearing won’t work.

Perhaps then all the related calls should be made by using the bareJID property?

Yes, It’s good idea.

Does the spec say whether a vcard could/should be saved against a given user/resource or just plain user?

The spec doesn’t say specifically, though when saving a vCard, no from attribute is specified in the stanza, implying to me that the card is not resource-dependent. Cards returned from the server however, are delivered to the requesting resource. Here’s the published example in the XEP: http://xmpp.org/extensions/xep-0054.html#sect-id327390

Applied the use of bareJID as an index for the cache in VCard.