/*
* Weblounge: Web Content Management System
* Copyright (c) 2003 - 2011 The Weblounge Team
* http://entwinemedia.com/weblounge
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package ch.entwine.weblounge.common.site;
import ch.entwine.weblounge.common.Customizable;
import ch.entwine.weblounge.common.content.Composeable;
import ch.entwine.weblounge.common.request.RequestFlavor;
import ch.entwine.weblounge.common.request.WebloungeRequest;
import ch.entwine.weblounge.common.request.WebloungeResponse;
import ch.entwine.weblounge.common.url.WebUrl;
import java.io.IOException;
/**
* An <code>Action</code> is java code that can be mounted to a specific url and
* that will be executed if these conditions hold:
* <ol>
* <li>The request is directly targeted at the action's mountpoint</li>
* <li>The action supports the requested flavor</li>
* </ol>
* <p>
* Once a request hits the mountpoint of an action, the action is then called in
* this order:
* <ol>
* <li>{@link #configure(WebloungeRequest, WebloungeResponse, RequestFlavor)}</li>
* <li>{@link #startResponse(WebloungeRequest, WebloungeResponse)}</li>
* </ol>
* By implementing an extended interface such as {@link HTMLAction},
* {@link XMLAction} or {@link JSONAction}, more sophisticated patterns for
* request handling and output generation are supported.
* <p>
* <b>Note:</b> A class that implements the <code>Action</code> interface must
* provide a default constructor (no arguments), since action handlers are
* created using reflection.
*/
public interface Action extends Composeable, Customizable {
/** Constant indicating that the current request should be evaluated */
int EVAL_REQUEST = 0;
/** Constant indicating that the current request should not be evaluated */
int SKIP_REQUEST = 1;
/** the default valid time is 60 minutes */
long DEFAULT_VALID_TIME = 60L * 60L * 1000L;
/** the default recheck time is 1 minute */
long DEFAULT_RECHECK_TIME = 60L * 1000L;
/**
* This method is the first call to an action once a request is dispatched to
* it. Here, the requested flavor is passed as well as the request and the
* response object in order to allow the action to validate the request and
* prepare data that it might need to satisfy subsequent calls regarding the
* processing of the request.
* <p>
* <b>Note:</b> It is not recommended to write anything to the response object
* yet, except for the case that it is obvious that the action cannot be
* executed, e. g. because the user is not authorized. In this case, the
* method should send back the proper <code>HTTP</code> error code and throw
* an {@link ActionException}.
*
* @param request
* the weblounge request
* @param response
* the weblounge response
* @param flavor
* the quested output flavor
* @throws ActionException
* if this action cannot handle the request
*/
void configure(WebloungeRequest request, WebloungeResponse response,
RequestFlavor flavor) throws ActionException;
/**
* This method is called after the action was able to validate the request and
* prepare for further request processing in
* {@link #configure(WebloungeRequest, WebloungeResponse, RequestFlavor)} and
* is considered the perfect place to write <code>HTTP</code> headers such as
* the content type to the response.
* <p>
* The action now has two choices: it can either completely take over control
* in serving the request by writing everything to the response and then
* returning {@link #SKIP_REQUEST}. Or it could just write the necessary
* <code>HTTP</code> headers to the response and then return
* {@link #EVAL_REQUEST}, in which case the action request handler will
* continue with the callback protocol depending on the actual type of the
* action (<code>HTMLAction</code>, <code>XMLAction</code> or
* <code>JSONAction</code>).
* <p>
* <b>Note:</b> the action request handler that is calling this action will
* already take care of those <code>HTTP</code> headers that deal with
* caching. If you would like to influence this behavior, make sure to
* implement <code>getRecheckTime()</code> accordingly rather than setting the
* headers yourself.
*
* @param request
* the servlet request
* @param response
* the servlet response
* @return either <code>EVAL_REQUEST</code> or <code>SKIP_REQUEST</code>
* @throws IOException
* if writing to the response fails
* @throws ActionException
* if a processing error occurs while handling the request
*/
int startResponse(WebloungeRequest request, WebloungeResponse response)
throws IOException, ActionException;
/**
* Returns the url to this action. The url will use the site's default url.
*
* @return the action url
*/
WebUrl getUrl();
/**
* Adds the given flavor to the list of supported flavors.
*
* @param flavor
* the flavor to add
*/
void addFlavor(RequestFlavor flavor);
/**
* Removes the given flavor from the list of supported flavors.
*
* @param flavor
* the flavor to remove
*/
void removeFlavor(RequestFlavor flavor);
/**
* Returns the supported content flavors. The meaning of flavors are the
* possible output formats of an action. Common flavors include include
* <code>HTML</code>, <code>XML</code> or <code>JSON</code>.
*
* @return the supported content flavors
*/
RequestFlavor[] getFlavors();
/**
* Returns <code>true</code> if the action supports the given content flavor.
* Common flavors might be <code>HTML</code>, <code>XML</code> or
* <code>JSON</code>.
*
* @param flavor
* the flavor
* @return <code>true</code> if the action can create the requested content
* flavor
*/
boolean supportsFlavor(RequestFlavor flavor);
/**
* Sets the action mountpoint.
*
* @param path
* the mountpoint
*/
void setPath(String path);
/**
* Returns the mountpoint used to call the action. The path is interpreted
* relative to the site root.
* <p>
* The extension can either be empty, <code>/*</code> or <code>/**</code>,
* depending on whether to match only the mountpoint (e. g. <code>/news</code>
* ), to match the mountpoint and any direct children (e. g.
* <code>/news/today</code>) or the mountpoint and any subsequent urls.
*
* @return the action mountpoint
*/
String getPath();
/**
* This method is used at initialization time and sets the site that was used
* to define this action.
*
* @param site
* the site
*/
void setSite(Site site);
/**
* Returns the associated site or <code>null</code> if no site has been set.
*
* @return the site
*/
Site getSite();
/**
* This method is used at initialization time and sets the module that was
* used to define this action.
*
* @param module
* the module
*/
void setModule(Module module);
/**
* Returns the associated module or <code>null</code> if no module has been
* set.
*
* @return the module
*/
Module getModule();
/**
* Notifies the action that it is about to be used. Actions are pooled
* resources and this callback indicates that the action was taken out of the
* pool of currently idle instances.
* <p>
* <b>Note:</b> Subclasses need to make sure to call the super implementation
* in order to not interfere with their ancestor's implementation.
*/
void activate();
/**
* Notifies the action that it is about to be put back into the pool of
* currently idle actions. Use this callback to release any resources that the
* action might be holding to up until now.
* <p>
* <b>Note:</b> Subclasses need to make sure to call the super implementation
* in order to not interfere with their ancestor's implementation.
*/
void passivate();
/**
* Returns an <code>XML</code> representation of the action configuration,
* that will look similar to the following example:
*
* <pre>
* <action id="myaction">
* TODO: Finish example
* </action>
* </pre>
*
* Use {@link #fromXml(org.w3c.dom.Node))} or
* {@link #fromXml(org.w3c.dom.Node, javax.xml.xpath.XPath)} to create a
* <code>ActionConfiguration</code> from the serialized output of this method.
*
* @return the <code>XML</code> representation of the action configuration
* @see #fromXml(org.w3c.dom.Node)
* @see #fromXml(org.w3c.dom.Node, javax.xml.xpath.XPath)
*/
String toXml();
/**
* Returns <code>true</code> if the given HTTP verb is supported by this
* action.
* <p>
* Common methods, amongst others, are:
* <ul>
* <li>HEAD</li>
* <li>OPTIONS</li>
* <li>GET</li>
* <li>POST</li>
* <li>PUT</li>
* <li>DELETE</li>
* </ul>
*
* @param method
* the request method
* @return <code>true</code> if <code>method</code> is supported by this
* action
*/
boolean supportsMethod(String method);
/**
* Returns the list of HTTP verbs that are supported by this action.
*
* @return the list of supported verbs
*/
String[] getMethods();
}