Child element namespace handling in custom PacketExtensions

Thanks to earlier help, I’m happily parsing the ugly-chunky ‘special’ element that I have to handle in my tests. But it’s requireing ugly-chunky code because it has to deal with all kinds of child elements. So I figured I’d break out the child elements into their own custom extensions. The trouble (I think) is that these child elements do not have an explicit namespace. By XML rules, they do have a namespace (it comes from the outermost element containing the child) but that doesn’t seem to be seen when parsing at that depth. First, the XML in question – the focus is on the elements inside element (not the similar RFC-033 block.

1

5a5a27d4-487d-11e2-8468-58b035f3b7bb

qa.imprivata.com

  <address jid="dkashtan.1@gocortext.com" type="to" />

  <address jid="tdkaa32cd44bbbf9@gocortext.com" type="to" />
<from domain="qa.imprivata.com" name="test dkashtan.2">tdka4c5ba62691f4@gocortext.com</from>

qa.imprivata.com

    <address jid="dkashtan.1@gocortext.com" name="dkashtan.1" />

    <address jid="tdkaa32cd44bbbf9@gocortext.com" name="dkashtan.3" />

    <address jid="tdka4c5ba62691f4@gocortext.com" name="dkashtan.2" />

Current State:

  • A default extension is created for the RFC-033 element but not for elements inside it. So I don’t think there is a clash there.

  • In my current provider for , as I iterate over the elements my element does have the namespace I expect. Because it is contained inside of a element with the namespace http://imprivata.com/protocol/cortex, it has that namespace.

  • Provider is registered in code via:

ProviderManager pm = ProviderManager.getInstance();

pm.addExtensionProvider(“content”, XMLConstants.AV_CORTEXT_NAMESPACE, new ContentExtension.Provider());

pm.addExtensionProvider(“domain”, XMLConstants.AV_CORTEXT_NAMESPACE, new DomainExtension.Provider());

pm.addExtensionProvider(“domain”, “jabber:client”, new CalvinDomainExtension.Provider());

pm.addExtensionProvider(“address”, XMLConstants.AV_CORTEXT_NAMESPACE, new CortextAddressExtension.Provider());

It is the last one.

Problem continued in next post…

XML section of interest.

// has namespace

// ns from parent

// ns from grandparent

The trouble is my new provider for that nested element isn’t getting called and I can’t see why. No exceptions are being tossed. Is this an artifact of the parsing model or am I missing something else? Is my block somehow being taken by the default provider? (It shouldn’t as the default use a NS of http://jabber.org/protocol/address and it’s being handled by the class org.jivesoftware.smackx.packet.MultipleAddresses)

Point me in the right direction. Do I have to provide empty PacketExtensions for elements all the way down the chain? Am I just missing the forest for the trees (again )?

I can keep all my parsing at the level of but it’s just a hot mess.

Thanks!

-Rich

I dumped the contents of the hash from the ProviderManager. I can see my provider listed and there are no name conflicts I can see via the debugger. But at least I know I got instantiated.

-Rich

Okay, I’m going to answer myself and if it’s wrong, hopefully it gets corrected.

It doesn’t look like any ExtensionProviders are called other than ones for immediate children of the packet/message.

So my assumption that the ExtensionProviders registered would fire no matter where in the message the element was found was just a bad assumption.

I’m becoming less enamored of the Provider model; sometimes I just wish I could get the raw xml of a packet. It’s there (you can clearly see it in the debug console). Having to write per-element providers and chain them to get to something deep can be painful. I know the DOM model is not efficient but being able to xpath to the thing I need because the tree is done makes me more efficient.

Ah well – it’s not like there are many (any) other xmpp client lib options in the Java space. I’ll make it work.

You are correct. The providers have to walk through the XML from start to end tag. This does not stop you from writing a single provider that will parse the entire contents of an element (including subelements) into a single text string that you can manipulate as you please.

You could do this in your **addresses **provider for instance.

That’s actually what I’ve done; it was just time consuming to write all the parsing to get down to the depth I needed. Always better if someone else had done it already. .

I just wrote a Provider style approach to each element; it makes it a lot easier to keep the parser in the right spot. Just need to deal with one last hurdle; the parser is having a fit when it hits a variant of the element that’s an empty tag. Most of the other times the element shows up it’s got a start and end. I’ll get it, I’m sure.

-Rich