Pubsub: modifying affiliations

Hi, I’m working with JRuby 1.5.6, OpenFire 3.6.4 and the latest nightly of smack/smackx (smack_2011-01-30). What I’m trying to do is to modify the affiliation of a node subscriber:

---- BEGIN SNIP ----

conn, mgr = establish_xmpp_connection(node_owner, password)

form = ConfigureForm.new(FormType.submit)

form.setNodeType(NodeType.leaf)

form.setAccessModel(AccessModel.open)

form.setPublishModel(PublishModel.publishers)

form.setPersistentItems(true)

form.setNotifyRetract(true)

Workaround for OF-16

form.setMaxItems(65535)

Create node, as owner-user

my_leaf_node = mgr.createNode(’/foo/bar’)

my_node.sendConfigurationForm(form)

conn.disconnect

now subscribe user (login, passwd) to ‘/foo/bar’

conn, mgr = establish_xmpp_connection(login, password)

jid = conn.getUser.split(’/’).first

user_node = mgr.getNode(’/foo/bar’) #LeafNode

user_node.subscribe(jid)

set_member_affiliation(‘member’, user_node, jid) <------- Method to be written

---- END SNIP ----

Following

http://xmpp.org/extensions/xep-0060.html#owner-affiliations-modify-request

I’d expect smackx to provide some high-level abstraction to connect to the pubsub service as the ‘/foo/bar’ node owner and then modify the affiliation of the user from the default ‘none’ to ‘member’ After having read both javadocs and documentation, I can’t find any class/method that performs the desired operation.

Moreover, if I try to go a little bit deeper into the stack, I can’t find any way to use Node.sendPubsubPacket for sending the stanza:

<iq type=‘set’

from=‘hamlet@denmark.lit/elsinore’

to=‘pubsub.shakespeare.lit’

id=‘ent2’>

<iq type=‘set’

from='admin@example.net/mac'

to='pubsub.example.net'

id='ent2'>
<affiliations node='/foo/bar'>

  <affiliation jid='test-user@example.net' affiliation='member'/>

</affiliations>

Appart from what was said in http://community.igniterealtime.org/thread/31210 (a bit outdated and unanswered) and http://community.igniterealtime.org/thread/43547 (it’s not an API question), I couldn’t find any more information in these forums about how to use smackx to have an user’s affiliation set, other than maybe sending the raw stanza.

Any help will be much appreciated. TIA.

//nando

Hi Nando,

Looking through the Smackx sources, it looks like you need to modify theorg.jivesoftware.smackx.pubsub.Affiliations. You could add a constructor that adds the jid parameter:

protected String jid;

public Affiliation(String nodeId, Type affiliation, String userJid) {

this(nodeId, affiliation);

jid = userJid

}

Adding the appropriate getter and then modifying the toXML() method to add the jid if it’s present. Then you could do the following:

List contents = new ArrayList();

list.add(new Affiliation(node.getId, Affiliation.Type.member, jid);

node.sendPubSubPacket(Type.SET, new AffiliationsExtension(contents));

Another option might be to create your own subclass of Affiliation and use that.

To the rest of the list: What would be the appropriate way of getting the Affiliations class patched in the Smack project proper?

Very well:

class MyAffiliation

  include Java::OrgJivesoftwareSmackPacket::PacketExtension

  attr_reader :jid, :type

  def initialize(jid,affiliation)

    @jid = jid

    @type = affiliation

  end

  def get_element_name

    'affiliation'

  end

  def get_namespace

    nil

  end

  def toXML

    "<#{get_element_name} jid=\"#{@jid}\" affiliation=\"#{@type.to_string}\"/>"

  end

  alias :to_xml :toXML

end

class MyAffiliationsExtension < Java::OrgJivesoftwareSmackxPubsub::NodeExtension

  attr_reader :node, :affiliations

  def initialize(node, my_affiliation_list)

    super PubSubElementType.value_of('AFFILIATIONS')

    @affiliations = my_affiliation_list

    @node = node

  end

  def toXML

    "<#{get_element_name} node=\"#{@node}\">#{@affiliations.inject(''){|r,aff| r = r+aff.to_xml}}</#{get_element_name}>"

  end

  alias :to_xml :toXML

end

class MyAffiliation

  include Java::OrgJivesoftwareSmackPacket::PacketExtension

  attr_reader :jid, :type

  def initialize(jid,affiliation)

    @jid = jid

    @type = affiliation

  end

  def get_element_name

    'affiliation'

  end

  def get_namespace

    nil

  end

  def toXML

    "<#{get_element_name} jid=\"#{@jid}\" affiliation=\"#{@type.to_string}\"/>"

  end

  alias :to_xml :toXML

end

class MyAffiliationsExtension < Java::OrgJivesoftwareSmackxPubsub::NodeExtension

  attr_reader :node, :affiliations

  def initialize(node, my_affiliation_list)

    super PubSubElementType.value_of('AFFILIATIONS')

    @affiliations = my_affiliation_list

    @node = node

  end

  def toXML

    "<#{get_element_name} node=\"#{@node}\">#{@affiliations.inject(''){|r,aff| r = r+aff.to_xml}}</#{get_element_name}>"

  end

  alias :to_xml :toXML

end

list = ArrayList.new

affiliation = MyAffiliation.new(jid, Affiliation::Type.value_of(type.to_s))

list.add(affiliation)

res = node.sendPubsubPacket(IQ::Type.from_string(‘set’), MyAffiliationsExtension.new(node.id, list),PubSubNamespace.value_of(‘OWNER’))

Much easier than the completely verbose code I’d write to do this in Java, and a good alternative to sending patches that never make it into trunk…

Sorry for digging this old thread up. I know it is marked as answered. But I am just hoping there might be an easier way to change the affiliation type than the described steps above. It has been more than 4 years, and I am surprised nobody has asked for an easier way to change the affiliation types?

Created SMACK-675.

I am using smack 4.2.0, how should i do in java. Thanks in advance