New Action Module

Last modified by Vincent Massol on 2024/02/26 17:51

 XWiki
 Requirements
 Completed
 

http://markmail.org/message/5mkltud4fujhcck7

Description

First version implemented and documented as the Action API Module.

The need is to develop the Action module of the XWiki platform, i.e. the module that is the entry point for all UIs and in charge of calling the correct backend code to display what the user has asked for (it's the Controller in MVC terminology).

Requirements & Use cases

  • UC1: Actions should be able to be added without touching at the existing platform code (i.e. someone could write a new action in java and plug it in)
  • UC2: It should be possible to execute something before or after an Action's execution.
  • UC3: It should be possible to completely replace an Action with another implementation.
  • UC4: It should be possible to add Actions without stopping the running XWiki instance
  • UC5: Actions should not know about each other
  • UC6: Actions should be independent of the URL formats used
  • UC7: Actions should work for both Entity Resources and other Resources (such as static resources, skin resources, etc)
  • UC8: It should be possible for an Action to be registered for one action, a list of actions or all actions

Some examples matching those use cases:

  • When a browser supports gzip compression, the response should be passed through a discrete gzip Action component. However if the requested material is already compressed (images), it should not be gzip'd.
  • If the user is not logged in and the action they are requesting does not alter the database (Registration) the request should be passed to a cache Action. If the cache contains the desired page then it is returned, otherwise it is passed on to the requested action and when returned it is added to the cache.
    • Vincent: This should be done by caching the XDOM using the cache macro
  • If desired, a filter Action may catch requests depending on user agent, ip address etc. And reroute the request. Banned!

History

  • Vincent wrote a first version located in xwiki-platform-action a long time ago. This version has been idle for a long time and in July 2012 it was decided to remove it since it wasn't used (See http://jira.xwiki.org/browse/XWIKI-8000).
  • Before it was removed Caleb wanted to reuse it when he started working on the Captcha integration (See http://markmail.org/message/rtamtgjb5xwuj6bq). In the end the Captcha module was committed without making use of that action module.

Latest Proposal

  • An Action interface:
    /**
     * Executes a given {@link org.xwiki.resource.Resource}.
     *
     * @version $Id$
     * @since 6.0M1
     */

    @Unstable
    public interface Action
    {
       int getPriority();
        List<String> getSupportedActionIds();
       void execute(Resource resource, ActionChain chain) throws ActionException;
    }
  • An ActionManager interface:
    /**
     * The Action Manager's goal is to locate the right {@link Action} implementations to call in the right order.
     *
     * @version $Id$
     * @since 6.0M1
     */

    @Unstable
    public interface ActionManager
    {
       void execute(Resource resource) throws ActionException;
    }
  • An ActionChain interface:
    /**
     * Allows calling the next {@link org.xwiki.action.Action} in the chain. An instance of this class is passed to
     * {@link Action#execute(org.xwiki.resource.Resource, ActionChain)} and it's up to the Action implementation to
     * decide if it wants to stop the execution chain or not.
     *
     * @version $Id$
     * @since 6.0M1
     */

    @Unstable
    public interface ActionChain
    {
       void executeNext(Resource resource) throws ActionException;
    }

These 3 interfaces support the defined use cases:

  • UC1: ok since Actions are added as components 
  • UC2: ok by using the getPriority() to order Actions
  • UC3: ok by using component priority to replace a component impl with another one
  • UC4: ok since our component manager supports adding/removing components at runtime
  • UC5: this is the case with this proposal
  • UC6: proposal is reusing the Resource (from the xwiki-platform-resource module) and is thus independent of the URL format
  • UC7: ok but the Resource module needs some minor changes. IMO we need to add a getAction() API to the Resource interface and not only in EntityResource in order to support actions for all types of Resources.
  • UC8: one action and a list of actions are supported. All actions can also be supported if for example we consider that if getSupportedActionIds() returns an empty list it means it's registered for all actions.

Note that if required, Actions can get injected the Container and thus get access to the current Request/Response. Same for the Execution Context.

Migration

In order not to break existing oldcore XWikiAction the idea would be to not introduce a new Servlet ATM and instead inside XWikiAction to call the new ActionManager after all component/execution context have been initialized and then to call as now the various Struts actions.

Then the idea would be to migrate one by one the struts Actions to the new API. Once no more action remain, we would move the struts code into a legacy module as much as possible (which BTW would be easier if we move to Servlet 3.0 since the servlet could be moved there and still work without a mapping in web.xml).


 

Get Connected