JEP-0093: Roster Item Exchange and future extensions

Hi. I was planning to add the extension JEP-0093: Roster Item Exchange to Smack as an exercise to learn Smack & XMPP. My idea is to share with the community this extension. But first I have a few questions.

  1. What are your plans with the JEPs? Are you planning to add some JEPs to Smack?

  2. Are you interested in this particular extension or do you prefer another extension? (just consider simple extensions…I’'m just learning Smack & XMPP)

  3. Checking my approach: Smack currently supports a way to add new extensions (PacketExtensionProvider, PacketExtension, etc.) but currently implements none (just a DefaultPacketExtension that it’‘s not enough for JEP-93). The RosterPacket it’‘s no good for JEP-93 since it’'s an IQ Packet. Therefore, I was thinking of:

a) Creating a new class RosterExchange that implements PacketExtension (similar to RosterPacket in some way)

b) Creating a new class RosterExchangeExtensionProvider that implements PacketExtensionProvider and register it in the ProviderManager

c) I have to still think how to process the Message when it’‘s received on the other side. But first I want to check if I’'m fine up to this point.

BTW, it would be nice to add to the Smack Debug Window the possibility to clear its contents.

Regards,

– Gato

Hi. I was planning to add the extension JEP-0093:

Roster Item Exchange to Smack as an exercise to learn

Smack & XMPP. My idea is to share with the community

this extension. But first I have a few questions.

We’‘d love to have smack users contribute code. I’‘ll warn that I’'m not one of the primary smack developers but my opinion is below:

  1. What are your plans with the JEPs? Are you

planning to add some JEPs to Smack?

I think everything outside of the ‘‘core’’ functionality will probably not be in Smack’'s core library. However, I it would be very nice to have an ‘‘smack-optional.jar’’ to augment the core smack library with support for other JEPs. That way people that only want a simple library for simple IM can work with core, but we can support as much as possible using the optional package.

I’‘m not sure how much we’‘ll be contributing to the optional protocol support but this would be an area that the community can make a huge difference by contributing code. It’'s also nice for community code because each protocol can be relatively separate from the core and other extension protocol support.

  1. Are you interested in this particular extension or

do you prefer another extension? (just consider

simple extensions…I’'m just learning Smack & XMPP)

Whatever is most interesting to you should be your first target. Roster item exchange seems like a great place to start.

  1. Checking my approach: Smack currently supports a

way to add new extensions (PacketExtensionProvider,

PacketExtension, etc.) but currently implements none

(just a DefaultPacketExtension that it’'s not enough

for JEP-93). The RosterPacket it’'s no good for JEP-93

since it’'s an IQ Packet. Therefore, I was thinking

of:

a) Creating a new class RosterExchange that

implements PacketExtension (similar to RosterPacket

in some way)

Yup.

b) Creating a new class

RosterExchangeExtensionProvider that implements

PacketExtensionProvider and register it in the

ProviderManager

Yup.

c) I have to still think how to process the Message

when it’'s received on the other side. But first I

want to check if I’'m fine up to this point.

You’‘ve got the right start. Once the roster is exchanged, you’'ll need some way for the recipient to respond to the roster item (display to user for acceptance), then use it to add the item to your roster. Since this is library code, the ‘‘allow receipient to respond to roster item’’ should probably use an event listener so people can plug in their own roster item exchange listener and code the appropriate response when they receive an item.

BTW, it would be nice to add to the Smack Debug

Window the possibility to clear its contents.

Good suggestion. I’'ll file a feature request in the bug tracker.

-iain

I think Iain covered all the major points. One thing I wanted to add is that the whole JEP process is a bit confusing at the moment. For example, JEP 0093 is a “Experimental, Informational” JEP which likely means that it will never be standards-track and won’‘t be an “official protocol”. Informational JEP’‘s are meant to document existing protocol usage rather than to develop “real protocol” changes. I find this whole idea to be complete BS since it makes it very hard to know which JEP’‘s should be implemented and which should be ignored. Until the JSF cleans up the JEP process we’'ll just have to figure out what to implement the best we can.

-Matt

Matt & Iain,

I’'ve finished with the development so far. But I have a couple of questions.

  1. How should I send you the code? What would be the normal procedure? Do you need unit tests? I have done some tests on the code and worked fine. I can send you the test code if you want.

  2. I have created all the classes in the package org.jivesoftware.smack.extensions. I would like to know the criteria you want to use for the extensions. For example, do you want to have all the extensions in this package? Or you prefer to have something like org.jivesoftware.smack.filter.extensions, org.jivesoftware.smack.packet.extensions, etc.?

  3. I haven’‘t created a new Listener, I used a common PacketListener for my example. What did you have in your mind when you said: “Since this is library code, the ‘‘allow receipient to respond to roster item’’ should probably use an event listener so people can plug in their own roster item exchange listener and code the appropriate response when they receive an item.”. If you want I can create a new class that implements PacketListener that automatically accepts the roster entries. Although I’'m not sure if this class would be useful or not for real situations.

  4. Why are you synchronizing some methods of RosterPacket? Like for example #getChildElementXML, #getRosterItems, etc… Is it possible that two or more threads try to access or modify a Package (In this case a RosterPacket)?

That’'s all for now.

Regards,

– Gato

  1. How should I send you the code? What would be the

normal procedure? Do you need unit tests? I have done

some tests on the code and worked fine. I can send

you the test code if you want.

We haven’‘t had any large outside code contributions yet, so there isn’‘t an established procedure. For now, it’‘s probably easiest to email me the code. If you’‘re interested in doing further Smack development I’'d be happy to get you setup with CVS, etc.

  1. I have created all the classes in the package

org.jivesoftware.smack.extensions. I would like to

know the criteria you want to use for the extensions.

For example, do you want to have all the extensions

in this package? Or you prefer to have something like

org.jivesoftware.smack.filter.extensions,

org.jivesoftware.smack.packet.extensions, etc.?

Hmm, good question that I haven’‘t thought about before. I’‘m open to suggestions so organize it the way you think works best and we’'ll go from therem.

  1. I haven’'t created a new Listener, I used a common

PacketListener for my example. What did you have in

your mind when you said: "Since this is library code,

the ‘‘allow receipient to respond to roster item’’

should probably use an event listener so people can

plug in their own roster item exchange listener and

code the appropriate response when they receive an

item.".

Iain will have to comment on this one since that was his input.

  1. Why are you synchronizing some methods of

RosterPacket? Like for example #getChildElementXML,

#getRosterItems, etc… Is it possible that two or

more threads try to access or modify a Package (In

this case a RosterPacket)?

I synchronize around the list operations since it is indeed possible that more than one thread could be doing operations on a single roster packet (although it’'s pretty unlikely).

Thanks,

Matt

Hi,

  1. I haven’'t created a new Listener, I used a common

PacketListener for my example. What did you have in

your mind when you said: "Since this is library code,

the ‘‘allow receipient to respond to roster item’’

should probably use an event listener so people can

plug in their own roster item exchange listener and

code the appropriate response when they receive an

item.". If you want I can create a new class that

implements PacketListener that automatically accepts

the roster entries. Although I’'m not sure if this

class would be useful or not for real situations.

As I understand it, the protocol lets you exchange roster items. But you don’‘t want to automatically add roster items someone sends you (they could just be sending you information about someoney they know). In addition, to add the roster item you receive, you’'ll have to start the presence subscribe protocol which requires more user input (and so you may not want to start the protocol immediately).

All of these decision will be handled differently depending on what you’‘re building with Smack. So if a roster item comes in, it should really be sent as an event to any registered event listener. The packet listener interface is fine, although there should be an easy way of filtering or otherwise detecting that you have a roster item event because many packet listeners will be handling a lot of different packet types if you use the generic packet listener interface. You don’‘t need to provide a default implementation of a listener for roster items because I think there are too many variables to make a good default implementation that fits enough people’'s needs. Instead just say ‘‘you need to implement a packet listener and register it with the roster exchange class in order to respond to roster item exchange packets’’.

Hope that makes sense

-iain

Iain,

As I understand it, the protocol lets you exchange roster items. But you don’'t want to automatically add roster items someone sends you …

I agree with you.

So if a roster item comes in, it should really be sent as an event to any registered event listener. The packet listener interface is fine, although there should be an easy way of filtering or otherwise detecting that you have a roster item event because many packet listeners will be handling a lot of different packet types if you use the generic packet listener interface.

I’‘ve created a special filter for roster exchange packets. If I’'m not wrong this would satisfy your requirement. Below is an usage example:

PacketFilter packetFilter = new RosterExchangeFilter();
     PacketListener packetListener = new PacketListener() {
          public void processPacket(Packet packet) {
               Message message = (Message) packet;
               System.out.println(message.getFrom());
               System.out.println(message.getBody());
               RosterExchange rosterExchange = (RosterExchange)message.getExtension("x", "jabber:x:roster");
               for (Iterator it = rosterExchange.getRosterItems(); it.hasNext();)
               {
                    RosterExchange.Item item = (RosterExchange.Item) it.next();
                    System.out.println(item.getName() + " " + item.getUser());
               }
          }
     };
     conn.addPacketListener(packetListener, packetFilter);
     System.out.println("Halt the debugger here until a message has been received");

Does this satisfy your requirement?

I sent the code to Matt. If you want you can take a look at it and let me know what you think. BTW, building an example (test-case) to test the code I found useful to have a new method in the Roster class that returns all its entries (Roster>>getAllEntries()). May be this new method is not usually needed but in my case it would have been handy.

Regards,

– Gato