powered by Jive Software

`Message.getBody()` returns `null` if all bodies have an xml:lang


#1

A bot generates the following XML:

<message type="groupchat" id=":SSWw7a66axLGm4QMeBXq" to="muc" from="muc/bot">
  <body xml:lang="en">text</body>
  <x xmlns="http://jabber.org/protocol/muc#user" />
</message>

As this is the only body in the message, I would expect Message.getBody() to return it regardless of my locale settings. However, the function instead returns null and my client processes the message as if it were empty.


#2

Addition: messages with an xml:lang on the message level are processed “properly”, i.e. returning the body text:

<message id="xxx" xml:lang="en" type="groupchat" to="me" from="muc/user">
  <body>Ge0rG, fun fact: my message here has an xml:lang on the body, too</body>
</message>

#3

Yep, probably trivial to fix if there is only one body, but hard (or even impossible) if there are multiple bodies with their language explicitly set but no language set on the enclosing stanza or stream.

Just to check: This was the case here? No language explicitly set on the stream and the carrying message stanza?


#4

Created SMACK-851.


#5

I’m not sure whether Message will inherit from the stream, and I don’t know whether the server did set a language on the incoming stream. What I do know is that smack set the language on the outgoing stream to English, and that there was no explicit @xml:lang on the message, but on the body.


#6

It will.

That would be useful information, in case that happens again.


#7

So I followed further down the rabbit hole:

RECV (0):
<?xml version='1.0'?>
<stream:stream xmlns:stream='http://etherx.jabber.org/streams' xml:lang='en' from='yax.im' id='9fe4f653-4e1f-41c0-b4a1-1280e1ead767' version='1.0' xmlns='jabber:client'>
  <stream:features>
    <sm xmlns='urn:xmpp:sm:2'><optional/></sm>
    <sm xmlns='urn:xmpp:sm:3'><optional/></sm>
    <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><required/></bind>
    <session xmlns='urn:ietf:params:xml:ns:xmpp-session'><optional/></session>
    <c hash='sha-1' ver='FoK2NxLNphE3I3DYQcNaHYesaxY=' node='http://prosody.im' xmlns='http://jabber.org/protocol/caps'/>
    <csi xmlns='urn:xmpp:csi:0'/><ver xmlns='urn:xmpp:features:rosterver'/>
  </stream:features>

This is the post-auth pre-bind stream header, and it comes with @xml:lang=‘en’.

However, the Message class obtains its language field from ParserUtils.getXmlLang(parser) which is calling:

parser.getAttributeValue("http://www.w3.org/XML/1998/namespace", "lang");

…and which returns null if there is no @xml:lang on the message, so it’s not inheriting the xml:lang from the stream in any way.

For the first example I posted, Message.language is null and Body.language is “en”, so getMessageBody(null) returns no body at all.