coliver 2003/03/05 19:44:49
Added: src/idl/cocoon cocoon.idl
src/idl/cocoon_flow cocoon_flow.idl
Log:
initial interface definitions
Revision Changes Path
1.1 xml-cocoon2/src/idl/cocoon/cocoon.idl
Index: cocoon.idl
===================================================================
module cocoon {
/**
* @see org.apache.cocoon.environment.Request
*/
interface Request {
};
interface Response {
};
interface Session {
};
interface Context_ {
};
interface Environment {
};
interface ComponentManager {
};
/**
* @see java.io.OutputStream
*/
interface OutputStream {
};
interface Function {
};
typedef sequence<string> StringArray;
const short COLUMNCOUNT = 1;
const short ROWCOUNT = 1;
typedef Object Rows[ROWCOUNT];
typedef Object RowsByIndex[ROWCOUNT][COLUMNCOUNT];
interface XForm;
typedef sequence<XForm> XForms;
};
1.1 xml-cocoon2/src/idl/cocoon_flow/cocoon_flow.idl
Index: cocoon_flow.idl
===================================================================
/**
* <p>The general flow of actions in an application which uses the control
flow is as described below.</p>
*
* <p>The request is received by Cocoon and passed to the sitemap for
processing. In the sitemap, you can do two things to pass the control to the
Controller layer:</p>
*
* <p><ul></p>
*
* <p><li>you can invoke a JavaScript top-level function to start processing
a logically grouped sequences of pages. Each time a response page is being sent
back to the client browser from this function, the processing of the JavaScript
code stops at the point the page is sent back, and the HTTP request finishes.
Through the magic of continuations, the execution state is saved in a
continuation object. Each continuation is given a unique string id, which could
be embedded in generated page, so that you can restart the saved computation
later on.</p>
*
* <p> To invoke a top level JavaScript function in the Controller, you use
the <tt><map:call function="function-name"/></tt> construction.</p>
*
* <p><li>to restart the computation of a previously stopped function, you
use the <tt><map:continue with="..."/></tt> construction. This restarts
the computation saved in a continuation object identified by the string value
of the <tt>with</tt> attribute. This value could be extracted in the sitemap
from the requested URL, from a POST or GET parameter etc. When the computation
stored in the continuation object is restarted, it appears as if nothing
happened, all the local and global variables have exactly the same values as
they had when the computation was stopped.<br />
*
* </ul></p>
*
* <p>Once the JavaScript function in the control layer is restarted, you're
effectively inside the Controller. Here you have access to the request
parameters, and to the business logic objects. The controller script takes the
appropriate actions to invoke the business logic, usually written in Java,
creating objects, setting various values on them etc.</p>
*
* <p>When the business logic is invoked, you're inside the Model. The
business logic takes whatever actions are needed, accessing a database, making
a SOAP request to a Web service etc. When this logic finishes, the program
control goes back to the Controller.</p>
*
* <p>Once here, the Controller has to decide which page needs to be sent
back to the client browser. To do this, the script can invoke either the
<tt>sendPage</tt> or the <tt>sendPageAndContinue</tt> functions. These
functions take two parameters, the relative URL of the page to be sent back to
the client, and a context object which can be accessed inside this page to
extract various values and place them in the generated page.</p>
*
* <p>The second argument to <tt>sendPage</tt> and
<tt>sendPageAndContinue</tt> is a context object, which can be a simple
dictionary with values that need to be displayed by the View. More generally
any Java or JavaScript object can be passed here, as long as the necessary get
methods for the important values are provided.</p>
*
* <p>The page specified by the URL is processed by the sitemap, using the
normal sitemap rules. The simplest case is an XSP generator followed by an XSLT
transformation and a serializer. This page generation is part of the View
layer. If an XSP page is processed, you can make use of JXPath elements to
retrieve values from the context objects passed by the Controller.</p>
*
* <p>The JXPath elements mirror similar XSLT constructions, except that
instead of operating on an XML document, operate on a Java or JavaScript
object. The JXPath logicsheet has constructs like <tt>jpath:if</tt>,
<tt>jpath:choose</tt>, <tt>jpath:when</tt>, <tt>jpath:otherwise</tt>,
<tt>jpath:value-of</tt> and <tt>jpath:for-each</tt>, which know how to operate
on hierarchies of nested Java objects. Historically the namespace is called
<em>jpath</em> instead of <em>jxpath</em>, we'll probably change it to the
latter before the next major release.</p>
*
* <p>A special instruction, <tt>jpath:continuation</tt> returns the id of
the continuation that restarts the processing from the last point. It can
actually retrieve ids of earlier continuations, which represent previous
stopped points, but I'm not discussing about this here to keep things
simple.</p>
*
* <p>Going back to the <tt>sendPage</tt> and <tt>sendPageAndContinue</tt>
functions, there is a big difference between them. The first function will send
the response back to the client browser, and will stop the processing of the
JavaScript script by saving it into a continuation object. The other function,
sendPageAndContinue will send the response, but it will not stop the
computation. This is useful for example when you need to exit a top-level
JavaScript function invoked with <tt><map:call function="..."/></tt>.</p>
*
* <p>The above explains how MVC could be really achieved in Cocoon with the
control flow layer. Note that there is no direct communication between Model
and View, everything is directed by the Controller by passing to View a context
object constructed from Model data. In a perfect world, XSP should have only
one logicsheet, the JXPath logicsheet. There should be no other things in an
XSP page that put logic in the page (read View), instead of the Model. If you
don't like XSP, and prefer to use JSP or Velocity, the JXPath logicsheet
equivalents should be implemented.</p>
*
* <p><h4>Basic usage</h4></p>
*
* <p>As hinted in the previous section, an application using Cocoon's MVC
approach is composed of three layers:</p>
*
* <p><ul><br />
* <li>a JavaScript controller which implements the interaction with the
client</p>
*
* <p><li>the business logic model which implements your application</p>
*
* <p><li>the XSP pages, which describe the content of the pages, and XSLT
stylesheets which describe the look of the content.<br />
* </ul></p>
*
* <p>In more complex applications, the flow of pages can be thought of
smaller sequences of pages which are composed together. The natural analogy is
to describe these sequences in separate JavaScript functions, which can then be
called either from the sitemap, can call each other freely.</p>
*
* <p>An example of such an application is the user login and preferences
sample I've just checked in CVS:</p>
*
* <p><a
href="http://cvs.apache.org/viewcvs.cgi/xml-cocoon2/src/webapp/samples/flow/examples/prefs">http://cvs.apache.org/viewcvs.cgi/xml-cocoon2/src/webapp/samples/flow/examples/prefs</a></p>
*
* <p>This application is composed of four top-level JavaScript functions:
<tt>login</tt>, <tt>registerUser</tt>, <tt>edit</tt> and <tt>logout</tt>.</p>
*
* <p>The entry level point in the application can be any of these functions,
but in order for a user to use the application, (s)he must login first. Once
the user logs in, we want to maintain the Java User object which represents the
user between top-level function invocations.</p>
*
* <p>If the script does nothing, each invocation of a top-level function
starts with fresh values for the global variables, no global state is preserved
between top-level function invocations from the sitemap. In this sample for
example, the <tt>login</tt> function assigns to the global variable
<em>user</em> the Java User object representing the logged in user. The
<tt>edit</tt> function trying to operate on this object would get a null value
instead, because the value is not shared by default between these top-level
function invocations.</p>
*
* <p>To solve the problem, the <tt>login</tt> and <tt>registerUser</tt>
functions have to call the <tt>cocoon.createSession()</tt> method, which
creates a servlet session and saves the global scope containing the global
variables' value in it. Next time the user invokes one of the four top-level
functions, the values of the global variables is restored, making sharing very
easy.</p>
*
* <p>Even if you don't need complex control flow in your application, you
may still choose to use the MVC pattern described above. You can have top-level
JavaScript functions which obtain the request parameters, invoke the business
logic and then call <tt>sendPageAndContinue</tt> to generate a response page
and return from the computation. Since there's no continuation object being
created by this function, and no global scope being saved, there's no memory
resource being eaten. The approach provides a clean way of separating logic and
content, and makes things easy to follow, since you have to look at a single
script to understand what's going on.</p>
*/
module cocoon_flow {
/**
* Interface to a Continuation
*/
interface WebContinuation {
readonly attribute string id;
readonly attribute Object continuation;
void invalidate();
void display();
};
/**
* Interface to the Cocoon log facility.
*/
interface Log {
/**
* Log a debug message
* @param message the message
*/
void debug(in string message);
/**
* Log an information message
* @param message the message
*/
void info(in string message);
/**
* Log a warning message
* @param message the message
*/
void warn(in string message);
/**
* Log an error message
* @param message the message
*/
void error(in string message);
};
/**
* Top level object
*/
interface Global {
readonly attribute Log log;
/**
* Prints a message on standard out followed by a newline
* @param message message to be printed
*/
void print(in string message);
/**
* Passes control to the Cocoon sitemap to generate the output page
* @param uri the relative URL of the page to be sent back to the
client
* @param bean a context object which can be accessed inside this
page to extract various values and place them in the generated page
*/
void sendPage(in string uri, in Object bean);
/**
* Passes control to the Cocoon sitemap to generate the output page.
* <p>The flow script is suspended after the page is generated and
the whole execution stack saved in a Continuation object </p>
* @param uri the relative URL of the page to be sent back to the
client
* @param bean a context object which can be accessed inside this
page to extract various values and place them in the generated page
* @param timeToLive time to live for the continuation created
*/
void sendPageAndWait(in string uri, in Object bean, in long
timeToLive);
/**
* Action Support
*
* call an action from JS
*/
void act(in string type, in string source, in Object parameters);
/**
* InputModule Support
*
* obtain value form InputModule
*/
Object inputValue(in string type, in string attribute_);
/**
* OutputModule Support
* set an attribute (starts transaction, commit or rollback required!)
*/
void outputSet(in string type, in string attribute_, in Object value);
/**
* makes attributes permanent (ends transaction)
*/
void outputCommit(in string type);
/**
* deletes attributes (ends transaction)
*/
void outputRollback(in string type);
/**
* Entry point to a flow-based XMLForm application. Replaces the
functionality
* of XMLForm actions.
* @param application Name of a JavaScript function that represents
the page flow for a form
* @param id form id
* @param validator_ns XML namespace of validator
* @param validator_doc validator document
*/
void xmlForm(in string application,
in string id, in string validator_ns,
in string validator_doc);
};
/**
* Interface to various Cocoon abstractions.
*/
interface Cocoon {
readonly attribute cocoon::Request request;
readonly attribute cocoon::Response response;
readonly attribute cocoon::Session session;
readonly attribute cocoon::Context_ context_;
readonly attribute cocoon::Environment environment;
readonly attribute cocoon::ComponentManager componentManager;
readonly attribute cocoon::StringArray parameters;
/**
* Call the Cocoon sitemap for the given URI, sending the output of
the
* eventually matched pipeline to the specified outputstream.
*
* @param uri The URI for which the request should be generated.
* @param biz Extra data associated with the subrequest.
* @param out An OutputStream where the output should be written to.
* @return Whatever the Cocoon processor returns (????).
* @exception Exception If an error occurs.
*/
boolean process(in string uri, in Object object, in
cocoon::OutputStream stream);
/**
* Set the Scope object in the session object of the current
* user. This effectively means that at the next invocation from the
* sitemap of a JavaScript function (using the <map:call
* function="...">), will obtain the same scope as the current
* one.
*/
void createSession();
/**
* Remove the Scope object from the session object of the current
* user.
*/
void removeSession();
void forwardTo(in string uri, in Object bizData, in Object
continuation);
void displayAllContinuations();
void callAction(in string type, in string source, in Object
parameters);
Object inputModuleGetAttribute(in string type, in string attribute_);
void outputModuleSetAttribute(in string type, in string attribute_,
in Object value);
void outputModuleCommit(in string type);
void outputModuleRollback(in string type);
};
/**
* Interface to Cocoon XMLForm
*/
interface XForm {
/**
* Creates a new JavaScript wrapper of a Form object
* @see org.apache.cocoon.components.xmlform.Form
* @param id form id
* @param validatorNS Namespace of validator
* @param validatorDoc Validator document
*/
cocoon::XForm constructor(in string form_id, in string
validator_namespace, in string validator_document);
readonly attribute cocoon::XForms forms;
/**
* The model object of this form: any Any Java bean, JavaScript, DOM,
or JDOM object
*/
readonly attribute Object model;
/**
* Creates a new web continuation
* @param lastCont previous web continuation
* @param timeToLive expiration time for this continuation
*/
WebContinuation start(in WebContinuation lastCont, in long
timeToLive);
/**
* Adds a violation to this form
* @param xpath xpath expression of field that contains invalid data
* @param message error message
*/
void addViolation(in string xpath, in string message);
/**
* Computes the value of an xpath expression against the model of
this form
* @param expr xpath expression
* @return result of computing <code>expr</code>
*/
Object getValue(in string expr);
/**
* Sends view to presentation pipeline and waits for subsequent
submission.
* Automatically resends view if validation fails.
* Creates two continuations: one immediately before the page is sent
* and one immediately after. These are used to implement automated
support
* for back/forward navigation in the form. When you move forward in
the
* form the second continuation is invoked. When you move back from
the
* following page the first continuation is invoked.
* @param phase view to send (and phase to validate)
* @param uri presentation pipeline resource identifier
* @param validator optional function invoked to perform validation
*/
void sendView(in string phase, in string uri, in cocoon::Function
validator);
/**
* Sends view to presentation pipeline but doesn't wait for submission
* @param view view to send
* @param uri presentation pipeline uri
*/
void finish(in string view, in string uri);
};
/**
* Object returned by a database query
*/
interface Result {
/**
* An array with a case-insensitive object per row with properties
matching column names and values matching column values.
*/
readonly attribute cocoon::Rows rows;
/**
* An array with an array per row of column values
*/
readonly attribute cocoon::RowsByIndex rowsByIndex;
/**
* An array of column names
*/
readonly attribute cocoon::StringArray columnNames;
/**
* Number of rows returned
*/
readonly attribute long rowCount;
/**
* True if not all rows are included due to reaching a maximum value
*/
readonly attribute boolean isLimitedByMaxRows;
};
/**
* High level interface to JDBC operations modeled after JSTL
*/
interface Database {
/**
* Used to execute INSERT, UPDATE, and DELETE statements, as well as
statements that create or remove database objects, such as CREATE TABLE and
DROP TABLE. It returns the number of rows affected by the statement.
* @param sql SQL statement to execute
* @return the number of rows affected
*/
long update(in string sql);
/**
* Executes a SQL SELECT statement. You can limit the result with
startRow and maxRows (which are optional).
* @param sql SQL statement to execute
* @return Result: contains the same properties as in JSTL.
*/
Result query(in string sql);
};
};