Hi,

How do you feel about the next usage scenarios for the observation 
component?


A. Simple observing of changes
This is the most common usage of the old notification mechanism. It 
allows a listener to see when something gets changed. It receives as the 
source the changed document, from which it can get the original document 
(there's a doc.getOriginalDocument() method for this). For the moment, 
the data argument is the context, as it is still a vital object for most 
of the code, and it has to be passed around all the time.

The event will hold the type of change, like adding a new document, 
deleting, or just saving a new version. In the future I'd like to 
increase the granularity, to make this "change" a set of basic changes, 
to be able to say that (object added, attachment removed, content 
changed) is what happened to the document (see 
http://jira.xwiki.org/jira/browse/XE-213 too).

With this event, a listener can then update some data indexer, like the 
Lucene plugin does, or send the new documents/attachments to a 
repository, or send a mail with the new code, or ping on IRC.


B. Simple observing of actions
This is also implemented in the old notification mechanism. It allows a 
listener to monitor actions. It receives as the source the affected 
document, and as the additional data the same context, as it is needed.

The event holds the action name, and I'd like to add the full URL, too, 
as other important information might be in there. I don't know if 
sending the complete request object is a good idea, but I think we 
should be able to obtain it somehow.

With this event, a listener can update some statistics, refresh some 
caches or cleanup some indexes, send an attachment to another repository 
(like SVN), or, based on the URL, it can be used to take some action, 
like if the action was "createspace" and the "notify=admins" parameter 
was given in the request, then the observer can send the notifications, 
without polluting the application code with the checks and mail sending 
calls.


C. Precondition/Postcondition enforcing
The previous two use cases allow a simple ping that something has 
already happened. (Actually, the listeners can also change the passed 
document, as the actual object is sent.) But I'd like to be able to 
write a listener that can say "this is not allowed, please stop this 
action", or "these changes are not OK, don't save this document". So, a 
precondition can be that "/save/" cannot be performed between 6PM and 
7AM, which would be a needed feature in some companies, or that "/view/" 
cannot be performed on the "SectionA" space from the IP addresses like 
192.168.2.*, which belongs to the SectionB users (these are action 
events). And a postcondition can be that the XWiki.XWikiPreferences can 
only be updated by changing XWikiGlobalRights objects, other types of 
changes can only be performed by a superadmin only, or that adding some 
content that looks like spam is not allowed (these are document events).

So, on top of the previous use cases, I'd like to add a "phase" to the 
events, which indicates if the event is sent before or after the change 
(or we can just add new events), and a new type of exception thrown by 
the listeners, which is not ignored. Right now, if a listener throws an 
exception, it is ignored. This exception, when received by the code that 
sends the notification, should stop the normal processing and display 
"action not allowed" + ex.getMessage to the user.


D. Rendering hooks
While working on the SkinExtensions and trying to write a better #toc 
macro, I was faced with the problem that there's no way a plugin can 
change the rendered content at the end. Yes, it can alter it line by 
line, and in theory there is an endRenderingHook sent with the content, 
but that is actually buggy, as an empty string is sent instead of the 
content, and the result is discarded. Still, even if fixed, this is sent 
only for *rendered* content, not *parsed* content. My initial idea was 
to change the PluginInterface by adding two new methods that will be 
called before and after the content was generated, but that is a bad 
idea, since the PluginInterface is already too big and has too many 
types of methods. And since the new rendering component is not yet 
available, I thought that we can also use events for this.

So, instead of writing new methods in the PluginInterface, we can add 
other type of events, which gets sent in the parsing/rendering process. 
That way, we don't need to have a plugin that implements all these 
methods, and adding a new feature will require just sending a new type 
of event, instead of changing an interface (which is dangerous).

The source would be an object holding the string, which can be modified 
by the listeners. Other information could be the content document, if 
there is one, the rendering/parsing context, anything else?


E. Other generic events
Like FlushCacheEvent, StartupEvent, ShutdownEvent, VirtualInitEvent, 
VirtualShutdownEvent (sent when a wiki is deleted by the 
WikiManagerEvent), Application[Added/Enabled/Disabled/Removed]Event 
(sent by the ApplicationManager), Space[Added/Removed]Event (sent by the 
SpaceManagerPlugin), etc.

Comments, please?
-- 
Sergiu Dumitriu
http://purl.org/net/sergiu/
_______________________________________________
devs mailing list
[email protected]
http://lists.xwiki.org/mailman/listinfo/devs

Reply via email to