How to stop processing loop when you listen for document edits and edit an XObject

Hi,

I have an extension that listens for DocumentUpdatedEvent, intended to pick up when a user modifies the normal page content. I have code that detects whether the main content has changed using the Delta list.

When that event happens, the extension modifies an XObject that is attached to that same document/page and calls Document#save().

Because there is a change to the XObject, that appears to cause a DocumentUpdatedEvent (which makes sense) but because the first event raised hasn’t completed yet and the page still has an entry in the Delta list, my code loops.

I have tried running the bit of code that modifies the XObject in another thread but setting values on the XObject requires the xcontextprovider and that doesn’t work, I assume because it’s not in an XWiki managed thread.

Does anyone have any ideas on how I can either stop the loop by improving the initial checks I perform when a DocumentedUpdatedEvent happens or, how I can run my XObject task in another thread properly? Or any other ideas? :slight_smile:

Thanks in advance,
Alex

The recommended way to cover this kind of use case (modify document at save) is:

  • listen to DocumentUpdatingEvent
  • modify the XWikiDocument sent along with the event

That’s it. The modified XWikiDocument will be saved after the listener is called.

As always, thank you @tmortagne! Your help is very much appreciated.

Hi @tmortagne, I switched to using the DocumentUpdatingEvent and now the loop has stopped (I also removed my call to doc.save() that I had); however, my XObject value isn’t being updated.

The Steps are:

  1. Page with attached XObject of type MyClass.
  2. MyClass has a PureText / com.xpn.xwiki.objects.classes.TextAreaClass property/attribute called myval
  3. Page is edited.
  4. My Event Listener receives the DocumentUpdatingEvent and:
    1. Reads the MyClass instance that is attached that page.
    2. Updates the myval attribute with new content (Uses a setValue on com.xpn.xwiki.api.Object).
  5. The Event Listener onEvent completes.

At this point from what you’ve said, if I view the attached object via the xwiki objects editor, I should see the updated value populated by the Event Listener; however, I don’t see that update and instead I see the old value.

Is there anything I might be missing? Sorry, I know it might be a bit difficult to say. I’m looking through the docs again.

Thanks in advance,
Alex

Where is the XWikiDocument instance you are modifying coming from ? You need to modify the one which is passed ton onEvent as second parameter.

You can see an example of this general logic on xwiki-platform/AverageRatingProtectionListener.java at master · xwiki/xwiki-platform · GitHub.

Yeah, that’s the one I’m modifying, well, an XObject attached to that document. And wherever I need to pass in a context, I use the one that’s provided to onEvent as the other parameter. If I get chance, I’ll either try to create a separate test or try to debug the path of the code through XWiki to see what I can see what’s happening.

After running out of things to try to get it to work, I tried going back to a DocumentUpdatedEvent and that now seems to be working and without the loop I was seeing. I’ll be honest, I have no idea why the loop used to happen and now it doesn’t.