powered by Jive Software

Sending XML files through XMPP (content filtering plugin)

Hi guys/gals,

I have a big problem, and a looming deadline at the same time.

I am writing a content-filtering plugin which basically takes care of the following:

  1. provides an admin interface for defining the bad words list

  2. serves this list (in XML format) to the client at login-time

I am stuck at point 2. I first tried to serve this XML file by using a JSP page which is part of the admin-console pages of the plugin - but I bumped into the problem of authentication. When the client needs to open this page, he is greeted by an “Authorization needed” page. I didn’'t know how to solve this problem - how to automatically authenticate the client when he requests the page - without hard-coding the admin pass into the code, so I went to look for another solution.

This other solution was to use an IQ packet in the jabber:iq:private namespace. The idea was to use these type of messages (which are basically used for storing client app preferences on the server, etc) to serve the bad words list. I wrote a plugin extending the IQPrivateHandler class, and overriding the HandleIQ method with the following code:

@Override public IQ handleIQ(IQ packet) throws UnauthorizedException {

IQ resultPacket = IQ.createResultIQ(packet);

Element resultElement = resultPacket.getElement();

resultElement.addElement(“query”, “jabber:iq:private”);

if (packet.getType().equals(IQ.Type.get)) {

Element child = packet.getChildElement();

if (child.getName().equals(“query”) && child.getNamespaceURI().equals(“jabber:iq:private”)) {

boolean badwordsRequest = (child.element(“badwords”) != null);

if (badwordsRequest) {


Element badWords = badWordsXMLDocument.getRootElement();



return resultPacket;



return IQ.createResultIQ(packet);


The problem with this approach is that the server somehow strips the contents of the element has to have an enclosing element in its own namespace. But even after I’'ve done this, the server still strips away the data I need.

I think that this behaviour may be related to some un-overriden IQPacketHandler/PrivateStorage method that goes through the database for the packet contents, finds nothing, and returns empty result, while stripping away my data.

So, my question is: how do I get away with this, without the server stripping out the things I need?

Any ideas about how to solve this problem, or other suggestions about the ways that would enable me to send this wordlist to the client will be very much appreciated.

Thanks for your time and patience to read this long post.


P.S. As I was writing this, I came to the idea to use PrivateStorage instance to add() the data I need programmatically, and let the client to just IQ-get the necessary data. I’'ll try to see if this works tommorow.

Hi Darkos,

Maybe the content filter plugin on the plugins page alraedy does some of what you are looking for. Its based on the packet inteceptor, and rejects/alters message with disallowed content. It is not tied to the client in any way.

It works with JM 2.2.0 onwards.


Yes, I know about the content filtering plugin, but this needs to be done client-side since it is a part of a customized instanting-messaging solution involving in-house developed IM client, and a customized JM server using the plugin I’'m trying to develop.

The existing content-filtering plugin is filtering on the server side, and I need it to be client-side. Thus the need to transfer the bad word list back from the server to the client.


Hey Darko,

From your code snippet I cannot see some parts of what you are doing so I’‘m not sure of what’'s going on. Anyway, your code made me have more questions than answers.

My first question would be: Why is it that the IQPrivateHandler class is not enough for what you are looking for? Is it that you need to provide a generic list of badWords besides the badWords list per user? Is that what loadBadWordsXML() is doing?

If that is the case I think that we could improve IQPrivateHandler by letting hook up some kind of interceptors that will be triggered when a user is asking for his private data for a certain namespace. So the interceptor may add his own information in addition to the personal information. The interceptor should also remove the generic information when storing the private data.

In summary, the plugin may provide a UI for setting up the generic list of badWords that will be used by the interceptor described above.

Will that idea work for you?


– Gato