Support for <who/> query

I have added support for <query xmlns=’‘jabber:iq:admin’’> in my copy of the smack library.

Are you interested in patches?

Can you link to some more information about the who query? Is it in a JEP? What servers support it?

Thanks,

Matt

I have implemented the client side of the following example.

As an administrator you can then get a list form users from the connection object.

http://www.jabber.org/admin/adminguide.html#admin-online

Looks cool. However, I’‘m going to defer to Iain here, who advised me that the admin protocols are a bit half-baked at the moment. Therefore, it probably doesn’‘t make sense to add this functionality to the core of Smack at this time. However, I’'m planning on creating a GenericIQ packet class, which should make doing custom functionality like this much easier.

Regards,

Matt

Could you please send me the code at cs98nt1@ucy.ac.cy I will really appreciate that. If you could include an example would be perfect. Tnanks!

Check out the new ProviderManager class – it provides a way to do pluggable IQ parsing that means a generic IQ class isn’'t needed.

Regards,

Matt

I am trying but I have probles. Hope you can help me. I have done the following things.

  1. Found the type of xml. When i send a who to the server i get the following answer:
<iq type=''result'' to=''admin@localhost/Smack'' from=''localhost''>   <query xmlns=''jabber:iq:admin''>     <who>
      <presence from=''test@localhost/JabberApplet-1289871547'' to=''test@localhost''>
        <status>Online</status>
        <priority>1</priority>
        <x xmlns=''jabber:x:delay'' from=''test@localhost/JabberApplet-1289871547'' stamp=''20030520T13:52:19''/>
        <x xmlns=''jabber:x:delay'' from=''test@localhost/JabberApplet-1289871547'' stamp=''20030520T13:52:19''/>
        <x xmlns=''jabber:mod_admin:who'' timer=''17'' from=''7'' to=''8''/>
      </presence>
      <presence id=''TdB54-2'' from=''admin@localhost/Smack'' to=''admin@localhost''>
        <x xmlns=''jabber:x:delay'' from=''admin@localhost/Smack'' stamp=''20030520T13:52:35''/>
        <x xmlns=''jabber:x:delay'' from=''admin@localhost/Smack'' stamp=''20030520T13:52:35''/>
        <x xmlns=''jabber:mod_admin:who'' timer=''0'' from=''4'' to=''7''/>
      </presence>
      <presence from=''Tnikos@localhost/Exodus'' to=''Tnikos@localhost''>
        <status>available</status>
        <priority>1</priority>
        <x xmlns=''jabber:x:delay'' from=''Tnikos@localhost/Exodus'' stamp=''20030520T13:07:10''/>
        <x xmlns=''jabber:x:delay'' from=''Tnikos@localhost/Exodus'' stamp=''20030520T13:07:10''/>
        <x xmlns=''jabber:x:delay'' from=''Tnikos@localhost/Exodus'' stamp=''20030520T13:52:01''/>
        <x xmlns=''jabber:mod_admin:who'' timer=''2726'' from=''22'' to=''26''/>
      </presence>
    </who>   </query>
</iq>

I want to parse that xml and get the online Users.

  1. I have a file smack.providers in a WEB-INF dir with the following

query

jabber:iq:admin

Who

  1. I have a Who.java extending IQ. There is my question. What methods must who implement? The xml has the following attributes: who, presence, status, priority, x. I must have a set and get method for each one? For example setWho and getWho ?

  2. I have implement a correct packet listener.

I have manage to work your example with time but I have problem doing this. Any help will be appreciated.

Nick

Nick,

It looks like who packets are too complex for introspection to work. Instead, you’'ll need to implement the IQProvider interface which lets you parse the XML directly and then turn it into objects. Check out the Javadocs and also the packet parsing that is done in PacketReader as a guide. If you have additional questions after looking there, let me know.

Regards,

Matt

Need your help again.

I have write the following Who class implementing the IQProvider interface and extending IQ:

import org.jivesoftware.smack.packet.*;

import org.jivesoftware.smack.packet.XMPPError;

import org.jivesoftware.smack.filter.PacketFilter;

import org.jivesoftware.smack.util.StringUtils;

import org.jivesoftware.smack.provider.*;

import org.xmlpull.v1.*;

public class Who extends IQ implements IQProvider {

private String who = null;

public Who() {

}

public IQ parseIQ(org.xmlpull.v1.XmlPullParser parser) throws Exception

{

IQ iqPacket = null;

String presence_from = null;

String presence_status = null;

Map properties = null;

String elementName = parser.getName();

String namespace = parser.getNamespace();

System.err.println("ElementName: "+ elementName);

System.err.println("NameSpace: "+ namespace);

boolean done = false;

while (!done)

{

int eventType = parser.next();

if (eventType == XmlPullParser.START_TAG)

{

elementName = parser.getName();

namespace = parser.getNamespace();

if (elementName.equals(“query”))

{

System.err.println("Query: ");

}

if (parser.getName().equals(“who”))

{

System.err.println("Who: ");

}

if (parser.getName().equals(“presence”))

{

presence_from = parser.getAttributeValue("", “from”);

System.err.println("Presence: "+ presence_from);

if (properties == null) {

properties = new HashMap();

}

properties.put(“presence”, presence_from);

}

if (parser.getName().equals(“status”))

{

presence_status = parser.nextText();

System.err.println("Status: "+ presence_status);

if (properties == null) {

properties = new HashMap();

}

properties.put(“status”, presence_status);

}

if (elementName.equals(“priority”))

{

presence_status = parser.nextText();

System.err.println("Priority: "+ presence_status);

if (properties == null) {

properties = new HashMap();

}

properties.put(“priority”, presence_status);

}

if (parser.getName().equals(“x”))

{

System.err.println("x: ");

}

}

else if (eventType == XmlPullParser.END_TAG)

{

if (parser.getName().equals(“query”))

done = true;

}

}

// Set basic values on the iq packet.

if (iqPacket == null)

{

iqPacket = new IQ();

}

// Set packet properties.

if (properties != null)

{

for (Iterator i=properties.keySet().iterator(); i.hasNext(); )

{

String name = (String)i.next();

System.err.print("\n\nProperties: "+name);

iqPacket.setProperty(name, properties.get(name));

System.err.println("Name: "+properties.get(name));

}

}

return iqPacket;

}

}

I also have a pachet listener. When a packet is instance of IQ checks if is instance of Time or Who. Time works ok. But IQ never is an instace of Who. That if statement never gets executed. Someting wrong with Who class? I also have a smack.providers :

<?xml version="1.0"?>

query

jabber:iq:time

Time

query

jabber:iq:admin

Who

The Who class gets executed ok. The println methods return the proper values. Thanks for your time.

Nick.

Nick,

Looks like a simple problem. Your parseIQ class is returning a new IQ object, not a new Who object.

Regards,

Matt

Matt thanks for your help. I wouldn’'t have come this far without you. But, I have one more question.

I have a Who class extending IQ implementing IQProvider. This class returns a who packet and I add a LinkedList as a property named presence.

I have a packet listener that process who packets. I have some println that works ok as I see the values of the linked list.

I also have another class ReceiveMsg where I connect to jabber and I send a who packet. What I can not do is get the reply Who packet and get the values of the property presence.

import org.jivesoftware.smack.*;

import org.jivesoftware.smack.packet.Message;

import org.jivesoftware.smack.packet.*;

import org.jivesoftware.smack.provider.ProviderManager;

import org.jivesoftware.smack.filter.*;

import java.util.*;

public class ReceiveMsg {

LinkedList presenceList = null;

public static void main(String args[]) {

try {

XMPPConnection.DEBUG_ENABLED = false;

XMPPConnection connection = new XMPPConnection(“localhost”);

Message msg;

MyPacketListener myPacketListener = new MyPacketListener(connection);

//MyPacketFilter myFilter = new MyPacketFilter();

connection.login(“admin”, “test”);

//Add filter to see everything basically

OrFilter or1 = new OrFilter(new PacketTypeFilter(IQ.class),

new PacketTypeFilter(Message.class));

OrFilter or2 = new OrFilter(new PacketTypeFilter(Presence.class), or1);

connection.addPacketListener(myPacketListener , or2);

Packet pck = new Packet() {

public String toXML() {

return "<iq id=“id1_001” type=“get” to=“localhost”> <query xmlns=“jabber:iq:admin”> ";

}

};

connection.sendPacket(pck);

msg = connection.createChat(“admin@localhost”).nextMessage(2000);

// Check to see if the msg is null.

System.out.println(msg);

} catch (Exception e){System.err.println(e);}

}

}

When I write the connection.createChat I see the println of the packetListener but the msg that returns is null. How can I get the who msg and the values of the property in ReceiveMsg?

Nick,

Never mind my previous question. I found the answer. I used a packetcollector and a filter accepting only who packets.

MyPacketFilter myFilter = new MyPacketFilter();

packet = connection.createPacketCollector(myFilter).nextResult();

Thanks for your help. You were great!

Nick.